最近项目开发需要用到ucos,之前有听说过,但没用过,之前一直从事的与Linux相关的开发工作,基于应用的学习,所以本文偏向于应用的认知,只具备以下的认知即可进行开发啦,OS,其实都差不多。
本文只是个人学习ucos的理解,也参考了邵贝贝老师以及其它网站上的学习教程。
内核调度的方法:时间片轮洵、优先级调度
不可剥夺性内核与可剥夺性内核的含义:
(1)不可剥夺性内核的好处就是只要这个任务不主动放弃CPU,那么别的任务是不能被抢夺的。
(2)可剥夺性内核对于一个优先级较低的来说,它的实时性可能不是很好,但是对于一个优先级较高的来说,它的实时性是相当好的,只要这个任务需要执行,他就会立马执行,这个就是可剥夺性内核。
Ucos属于优先级调度====>可剥夺性内核,数字越小,优先级越大。
专业术语
指处理时不可分割的代码。一旦这段代码开始执行,不允许中断的打入。
在进入临界段代码之前,需要关中断,执行完临界段代码,开中断。
资源:任何为任务所占用的实体。如:打印机,键盘,显示器等。另外资源也可以是一个变量,一个结构或者一个数组。
共享资源:被一个以上的任务使用的资源。
如果要使用共享资源,必须满足互斥:(独占)
满足互斥的方法如下:
1、 关中断和开中断
在使用这个全局变量或者共享资源之前呢,我们首先把这个中断给关掉,当共享资源使用完毕以后,我们再把这个中断给打开就行了
2、 使用测试并置位指令
3、 任务禁止切换,使用,允许任务切换
不被任务打断,意味着不会被别的任务打断,这时就可以使用共享资源,使用完再开启任务切换。
4、 使用信号量
方法与使用测试并置位指令类似,但注意使用共享资源,首先要获取这个信号量,获取后才能使用共享资源,使用完以后,需要释放信号量。
死锁也称为抱死。指2个任务无限期的互相等待对方控制的资源。
简单的说就是两个任务分别都有它们相互的共享资源,一个任务在执行的过程中必须等待这个共享资源,而这个资源又正在另外一个任务利用,另外一个也是出现一样的情况。我等你,你等我,但最后谁都无法等待谁。
进入中断函数:OS-IntEnter();
退出中断函数:OS-IntExit();
中断计数器:ISRCounter,相当于引用计数,来一个中断就加一,中断退出的时候就减一。
OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INTU prio);
参数:
task:指向任务函数的函数指针INT16U opt);
参数:INT8U OSTaskResume(INT8U prio);
两个事件之间的通讯是基于一个模型:
任务1 ===> 发送事件 <=====请求事件<====任务2
事件控制块结构
typedef struct
{
INT8U OSEventType; //事件的类型
INT16U OSEventCnt; //信号量计数器
void *OSEventPtr; //消息或消息队列的指针
INT8U OSEventGrp; //等待事件的任务组
INT8U OSEventTbl[OS_EVENT_TBL_SIZE];//任务等待表
#if OS_EVENT_NAME_EN > 0u
INT8U *OSEventName; //事件名
#endif
} OS_EVENT;
信号量:
对应事件控制块结构的事件类型为OS_EVENT_TYPE_SEM
1、创建信号量
OS_EVENT *OSSemCreate (INT16U cnt);
cnt:信号量计数器的初始值
return:返回值为已经创建的信号量的指针
2、请求信号量函数
void OSSemPend ( OS_EVENT *pevent, INT16U timeout, INT8U *err);
pevent:被请求信号量的指针
timeout:等待时限
err:错误信息
3、发送信号量函数(释放信号量)
INT8U OSSemPost(OS_EVENT *pevent);
pevent:信号量指针
return:成功返回值为OS_ON_ERR,否则会根据错误类型返回OS_ERR_EVENT_TYPE、OS_SEM_OVF
4、删除信号量函数
OS_EVENT *OSSemDel (OS_EVENT *pevent,INT8U opt, INT8U *err);
pevent:要删除的信号量指针
opt:删除条件选项
err:错误信息
邮箱:
任务与任务之间传递数据的方式。
对应事件控制块结构的事件类型为OS_EVENT_TYPE_MBOX
1、创建邮箱函数
OS_EVENT *OSMboxCreate (void *msg);
msg:消息指针
return:返回值为消息邮箱的指针。
使用: OS_EVENT *msg_ptr = NULL ;
u8 *msg_string = "hello world" ;
msg_ptr = OSMboxCreate(msg_string);
2、向邮箱发送消息的函数
INT8U OSMboxPost (OS_EVENT *pevent,void *msg);
pevent:消息邮箱的指针
msg:消息指针
3、请求邮箱指针
void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err);
pevent:消息邮箱的指针
timeout:等待时限
err:错误信息
4、查询邮箱状态函数
INT8U OSMboxQuery(OS_EVENT *pevent,OS_MBOX_DATA *pdata);
pevent:消息邮箱指针
pdata:存放邮箱信息的结构
5、删除邮箱函数
OS_EVENT *OSMboxDel(OS_EVENT *pevent,INT8U opt,INT8U *err);
pevent:消息邮箱指针
opt:删除选项
err:错误信息
暂时就这样吧,后面用到了再加进来。
参考:
1、邵贝贝老师的书籍。
2、麦子学院ucos wiki教程:http://www.maiziedu.com/wiki/iot/ucoskernel/