普通的单片机编程:程序(软件)——单片机硬件;html
嵌入式操做系统开发:程序(软件)——操做系统——嵌入式硬件(包括单片机等);编程
咱们平时普通所学的单片机编程开发,通常状况下都须要对单片机的片载资源进行了解,了解IO口、PWM发生器、中断、定时器、串口等经常使用的内部资源,而后通常采用C编程的面向过程编程,程序的运行过程从进入入口函数开始运行,是顺序执行的。单片机的开发,相对来讲比较简单,可是不一样的单片机,要实现相同的功能,其内部程序必然存在差异,也就是所说的移植性较差,另外在开发单片机时,必然要阅读芯片手册,对可用的资源有必定的硬件上的了解。在事件的执行上也不如嵌入式开发来得效率高。数组
嵌入式开发,也就是在已有的硬件基础上移植操做系统,开发者所写的软件程序运行在操做系统中,经过调用操做系统提供的 API 接口等调用硬件资源,实现想要实现的功能。操做系统某种程度上屏蔽了底层的硬件,能够暂时不去考虑操做系统是如何调用硬件资源问题,这其中涉及到驱动等知识。浏览器
固然,想要实现移植操做系统的单片机,相对来讲其性能就要求高一些,像普通的51芯片,即便移植剪裁到很小的Linux系统,运行起来也很吃力。网络
开发者所写的程序是与操做系统相关,与硬件无关,只要运行在相同的操做系统中便可,所以嵌入式开发具备较好的移植性,对底层硬件也不强制要求熟悉,此外嵌入式系统一般是并发式执行任务,所以执行效率要好。好比要说得us/Os II 可同时管理64个任务,多个任务的处理在同时间段内同步完成。(这里涉及到多线程以及CPU时间片的概念)。数据结构
总结来讲,与单片机开发相比,嵌入式开发有以下优势:多线程
除此以外,嵌入式操做系统还具有不少优越性:精简的内核,高实时性,多任务的操做系统;高可靠性;可裁剪性好;架构
百度百科的解释仍是颇有道理的:并发
嵌入式操做系统(Embedded Operating System,简称:EOS)是指用于嵌入式系统的操做系统。嵌入式操做系统是一种用途普遍的系统软件,一般包括与硬件相关的底层驱动软件、系统内核、设备驱动接口、通讯协议、图形界面、标准化浏览器等。嵌入式操做系统负责嵌入式系统的所有软、硬件资源的分配、任务调度,控制、协调并发活动。它必须体现其所在系统的特征,可以经过装卸某些模块来达到系统所要求的功能。目前在嵌入式领域普遍使用的操做系统有:嵌入式实时操做系统µC/OS-II、嵌入式Linux、Windows Embedded、VxWorks等,以及应用在智能手机和平板电脑的Android、iOS等。框架
OS_ENTER_CRITICAL() OS_EXIT_CRITCAL() //宏定义的具体实现取决于移植所用的微处理器,每种微处理器都要本身的OS_CPU.H文件
OSTickISR():硬件定时器以时钟节拍为周期定时产生中断,该中断服务程序为OSTickISR,该函数中主要调用了OSTIMETick()函数来完成系统在每一个时钟节拍须要完成的工做。
保存处理器寄存器的值 调用OSIntEnter()或是OSIntNesting加1 调用OSTimeTick() 调用OSIntExit() 恢复处理器寄存器的值 执行中断返回指令
OSTimeTick():时钟节拍服务函数作的工做包括:记录节拍树,任务延时减一,其任务时在每一个时钟节拍了解任务的延时状态,使得其中延时结束的非挂起任务进入就绪状态。
任务状态:OSTCBStat 任务状态字
任务控制块OS_TCB:用来记录任务的堆栈指针,任务的当前状态,任务的优先级等一些与任务管理有关的属性的表,叫作任务控制块TCB。系统初始化时会按照用户提供的任务数(OS_MAX_TASKS)为任务建立相应数量的任务控制块链表,也就是空任务块链表,当建立一个任务后,会调用OSTCBInit来为任务控制块进行初始化,从链表中获取一个任务控制块,并利用属性对各个成员赋值,最后将该块链入链表头部。
任务就绪表:ready List:包含两个变量,OSRdyGrp和OSRdyTb1[],每一个任务的就绪标志都会放入就绪表中,任务按照优先级分组,8个任务为一组(64个任务),OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪状态的任务。
任务堆栈:保存CPU寄存器中的内容及存储私有数据的须要,每一个任务都应该分配有本身的堆栈,任务堆栈是任务的重要组成部分,在应用程序中定义任务堆栈方法为:OS_TSK TaskStk[TASK_STK_SIZE]定义一个OS_STK类型数组并在建立一个任务时将数组地址赋给该任务。
任务建立:建立函数:OSTaskCreate + 建立函数:OSTaskCreateExt 建立任务时传递任务的堆栈指针,任务的指针,任务参数以及任务优先级等,OSTaskCreate()在建立任务时会调用任务堆栈初始化函数OSTaskStkInit()来完成任务堆栈的初始化工做,这个函数在OS_CPU.C根据处理器移植时编写
任务切换:OS_TASK_SW()任务切换宏:停止正在运行的任务,转而去运行另一个任务的操做,这个任务时就绪任务中优先级别最高的那个任务。简单说,就是将挂起的任务寄存器入栈,将较高优先级任务的寄存器出栈
OSSchedLock() 禁止调度保护任务级的共享资源
typedef struct { INT8U OSEventType; //事件的类型 INT16U OSEventCnt; //信号量计数器 void *OSEventPtr; //消息或消息队列的指针 INT8U OSEventGrp; //等待事件的任务组 INT8U OSEventTbl[OS_EVENT_TBL_SIZE];//任务等待表 } OS_EVENT;
设置OS_CPU.H与处理器和编译器相关的代码:包括定义数据类型INT8U,INT8S等,使用OS_ENTER_CRITICAL等宏开启中断关闭中断等,定义堆栈增加方向(要注意)
用C语言编写与操做系统相关的函数 OS_CPU_C.C:OSTaskStkInit(初始化任务堆栈),OSTaskCreateHook,OSTaskDelHook,OSTaskSwHoOK,OSTaskStatHook,OSTimeTickHooK,比较重要的是第一个,后面五个通常可置空
用汇编语言编写四个与处理器相关的函数 OS_CPU.ASM:OSStartHighRdy,OSCtxSw(上下文切换)OSIntCtxSw(中断级任务切换),OSTickISR
飞思卡尔9s12X系列双核中的协处理器XGATE
双核架构,增长了一个RISC核的高效协处理器,XGATE模块,专门用于处理中断任务,能够将主核CPU从执行耗时的中断处理程序工做中解放出来,专一于执行与应用有关的任务,实现更好的实时事件处理,XGATE采用RISC指令核,代码高效,主频运行速率可达到主核的2倍。
#pragma DATA_SEG_SHARED_DATA volatile int shared_counter;// 定义XGATE与主核共享RAM的变量 #pragma DATA_SEG DEFAULT
#define ROUTE_INTERRUPT(vec_adr, cfdata) \ INT_CFADDR= (vec_adr) & 0xF0; \ INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata) //channel id 须要到xgate.cxgate文件向量列表中查找 //自定义向量名 #define RTI_VEC 0xF0 /* vector address= 2 * channel id */ #define MSCAN0_VEC 0xB2 /* vector address= 2 * channel id */ #define SCI2_VEC 0x8A /* vector address= 2 * channel id */ #define SCI0_VEC 0xD6 static void SetupXGATE(void) { //初始化Xgate向量表模块并将XGVBR 寄存器设置到初始地址 XGVBR= (unsigned int)(void*__far)(XGATE_VectorTable - XGATE_VECTOR_OFFSET); // RTI_VEC 为自定义中断名 设置xgate中断以及中断优先级 ROUTE_INTERRUPT(RTI_VEC, 0x86); /* RQST=1 and PRIO=1 */ //实时时钟中断 ROUTE_INTERRUPT(MSCAN0_VEC, 0x81); /* RQST=1 and PRIO=1 */ //CAN接收中断 ROUTE_INTERRUPT(SCI2_VEC, 0x84); /* RQST=1 and PRIO=1 */ ROUTE_INTERRUPT(SCI0_VEC, 0x83); /* RQST=1 and PRIO=1 */ XGMCTL= 0xFBC1; /* XGE | XGFRZ | XGIE */ }
interrupt void SCI2_Handler(void){ } const XGATE_TableEntry XGATE_VectorTable[] ={ ... {(XGATE_Function)SCI2_Handler}, // Channel 45 - SCI2 ... }
can总线是一种串行数据通讯协议,特色包括:多主机方式工做,任意节点能够在任意时刻主动向网络上其余节点发送信息;串行,同步,半双工,CRC
节点信息分红不一样的优先级:仲裁总线结构机制,节点同时传送信息时,优先级低的节点主动中止数据发送,优先级高的节点不受影响继续传送数据。
CAN总线系统:由多个电子控制单元EMU同时控制多个工做装置或系统,各控制单元ECU的共用信息经过总线互相传递。
传输速度快;相关控制单元可共用传感器;更少的线束,更小的控制单元,节省了空间。
参考:https://wenku.baidu.com/view/bab35fb765ce0508763213cf.html
每组报文开头的11位字符为标识符,定义了报文的优先级,这种报文格式称为面向内容的编址方案。标识符在网络中是惟一的,描述了数据的特定含义,也决定报文优先级(标识符数值越小,优先级越高)。注意:最高优先级的报文得到总线访问权,低优先级报文在下一个总线周期自动重发。
当一个站要向其它站发送数据时,该站的CPU将要发送的数据和本身的标识符传送给本站的CAN芯片,并处于准备状态;当它收到总线分配时,转为发送报文状态。CAN芯片将数据根据协议组织成必定的报文格式发出,这时网上的其它站处于接收状态。每一个处于接收状态的站对接收到的报文进行检测,判断这些报文是不是发给本身的,以肯定是否接收它。