这是本系列的第三贴(100大洋啊~~~归来吧~~~~)。正如前期所说,这期介绍实时操作系统CoOS。其作者CooCox的官方中文网传送门:http://www.coocox.com/CN/ 。其实时特性、容量特性请上官网查阅,说明文档也一样。
引用官方介绍,CooCox CoOS 是一款针对ARM Cortex-M系列芯片而设计的实时系统内核。
CoOS特征:
免费并开源 ARM Cortex M3及M0定制操作系统 高度可裁剪性,最小系统内核仅974Byte 支持优先级抢占和时间片轮转 自适应任务调度算法 零中断延时时间 - 堆栈溢出检测信号量、邮箱、队列、事件标志、互斥等同步通信方式
- 支持多种编译器:ICCARM、ARMCC、GCC
一年还是半年前接触了第一个操作系统是μC/OS II,当时跑的是LPC2103的ARM7周立功的板子,懒得一直去下了个移植好的工程压缩包,最后总算把最简单的点灯程序跑通了,那板子就下不进程序了,不知为何。后来因为没深入学下去(换了别的芯片开发,懒得找移植也懒得自己移植),就没怎么用过操作系统,一直跑的裸机。记得一次做项目由于任务转换调度太多太复杂,设置了一大堆标志变量,程序乱,调度性能差,容易出错,可靠性差。
后来接触到CoOS后,感觉这个系统跟μC/OS II十分类似,而且例程齐全,所以很容易上手。更重要的是Coocox提供了一个免费而易用的开发环境,各种主流芯片的移植都能在他的工程向导的一步步指引下轻易完成。先上图:
这就是工程建立向导的第一步,选择芯片厂商,下面是2,3步,选择芯片型号和使用的设备。
新唐M0的型号一应俱全,只要点击相应的连接就能够建立起一个以该芯片为目标芯片的项目。
[localimg=1000,481]1[/localimg]
只要勾选栏目里面的设备,就可以直接将该芯片对应的官方BSP接口驱动添加到工程目录以及物理目录中,省去了自己复制剪裁的功夫,除此还提供一些第三方驱动,帮助开发者提高开发效率。CoOS也作为一个组件在其中勾选。
这是我建立起来的一个简单串口项目工程。包括了必要的DrvSYS、DrvUART和DrvGPIO。同时有几个设备的后面写明了软件提供了几个例程,通过把例程调出,直接复制粘贴,也省了开发者的不少事,当然,也养成了开发者懒惰的习惯。
下面写一个有两个任务(其中一个空闲任务void CoIdleTask(void* pdata);)的小程序,用于展示这个系统的基本功能
- /**
- /*---------------------------- Inlcude ---------------------------------------*/
- #include <CoOS.h> /*!< CoOS header file */
- #include "NUC1xx.h"
- #include "DrvSYS.h"
- #include "DrvUART.h"
- #include "DrvGPIO.h"
- /*---------------------------- Symbol Define -------------------------------*/
- #define STACK_SIZE_TASKA 128 /*!< Define "taskA" task size */
- /*---------------------------- Variable Define -------------------------------*/
- OS_STK taskA_stk[STACK_SIZE_TASKA]; /*!< Define "taskA" task stack */
- /** 定义信号量 */
- OS_EventID semA;
- uint8_t sbuf[1];
- /** 串口接收中断 call back */
- void UART0_INT_HANDLE(uint32_t u32IntStatus);
- /*--------------------------------------------------------------------*/
- /** taskA 用于打印接收到的字符 */
- void taskA (void* pdata) {
- /** 初始化串口 */
- STR_UART_T UartParam;
- UNLOCKREG();
- /* Enable the 12MHz oscillator oscillation */
- DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);
- DrvSYS_Delay(5000);
- DrvGPIO_InitFunction(E_FUNC_UART0);
- /* Set UART I/O */
- DrvGPIO_InitFunction(FUNC_UART0);
- UartParam.u32BaudRate = 115200;
- UartParam.u8cDataBits = DRVUART_DATABITS_8;
- UartParam.u8cStopBits = DRVUART_STOPBITS_1;
- UartParam.u8cParity = DRVUART_PARITY_NONE;
- UartParam.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES;
- UartParam.u8TimeOut = 0;
- /* Open the UART */
- DrvUART_Open(UART_PORT0, &UartParam);
- printf(" \n finish init \n ");
- /* Enable Interrupt and install the call back function */
- DrvUART_EnableInt(UartNum, DRVUART_RDAINT, UART0_INT_HANDLE);
- /** 创建信号量semA、semB初始值为0,最大值为1,先进先出模式 */
- semA = CoCreateSem (0, 1, EVENT_SORT_TYPE_FIFO);
- /** 任务在死循环中循环进行,每次循环的开头等待semA释放才能往下走,否则任务进入挂起状态 */
- while(1){
- CoPendSem (semA, 0);
- printf("%c\n", sbuf[0]);
- }
- }
- int main (){
- CoInitOS (); /*!< Initial CooCox CoOS */
- /*!< Create three tasks */
- CoCreateTask (taskA,0,0,&taskA_stk[STACK_SIZE_TASKA-1],STACK_SIZE_TASKA);
- CoStartOS (); /*!< Start multitask */
- while (1); /*!< The code don''t reach here */
- }
- /** 串口0终端call back */
- void UART0_INT_HANDLE(uint32_t u32IntStatus)
- {
- EnterISR(); // Enter ISR 中断中使用CoOS函数必须调用
- if(u32IntStatus & DRVUART_RDAINT)
- {
- /* Get all the input characters */
- while(UART0->ISR.RDA_IF==1)
- {
- /* Get the character from UART Buffer */
- DrvUART_Read(UART_PORT0, sbuf, 1);
- }
- }
- isr_PostSem (semA);
- ExitISR(); // Exit ISR 中断中使用CoOS函数必须调用
- }
taskA创建以后初始化了串口的设置,并且创建了一个初值为0的信号量semA。于是在运行到等待信号量semA的一步上无法继续运行,任务挂起,剩下空闲任务在死循环。当有串口数据发过来,系统发生中断,并吧发过来的一个字符读入到sbuf[0]中,同时释放了信号量semA。于是taskA得以从挂起态转入运行态,将sbuf[0]输出,之后继续循环回来等待semA,如此循环下去。
本操作系统的的用法跟μC/OS II类似,就不详细描述了,课参考μ系统的书籍。
其中CoOS的设置通过编辑其OsConfig.h来改变。信箱、消息队列等功能在默认下是关闭的。
先写到这了。实验室都下班了。。。。
|