这是本系列的第三贴(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来改变。信箱、消息队列等功能在默认下是关闭的。
先写到这了。实验室都下班了。。。。 |