uCOS学习笔记

1、uCOS不支持时间轮转调度法。

2、uCOS提供很多系统服务,例如邮箱、消息队列、信号量、块大小固定的内存的申请与释放、时间相关函数等。

它们之间的区别:

邮箱:只能存放一个消息;邮箱是用来传递消息缓冲区指针的数据结构;

消息队列:加入了循环队列,可以存放多个消息,可以看成是多个邮箱的组合;消息队列是用来传递多个消息邮箱的数据结构;

信号量:高优先级的任务在等待接收信号量的时候,若低优先级的任务没有释放信号量,就会一直等待下去,低优先级的任务就无法运行了。

3、对于代码的临界段,即处理不可分割的代码时(处理时不允许任何中断打入),处理时需要关/开中断,需要调用两个宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),其在OS_CPU.H里定义。

4、一个任务,也称为一个线程。

5、uCOS系统启动:

void main(void)

{

OSInit();

_mem_init(); //初始化内存分配

BSP_Init();//硬件平台初始化
OSTaskCreate(FirstTask1,...)调用OSTaskCreate或OSTaskCreateExt;

OSTaskCreate(FirstTask2,...)

...
OSStart();//启动多任务管理

}

INT8U  OSTaskCreate (void   (*task)(void *p_arg),//指向任务代码的指针
                     void    *p_arg, //任务开始执行时,传递给任务的参数的指针
                     OS_STK  *ptos, //分配给任务的堆栈的栈顶指针,从顶向下递减
                     INT8U    prio) //分配给任务的优先级

举例:OStaskCreate(mytask,(void *)0,(OS_STK *)&STK_TASK_SUB[TASK_STK_SIZE-1],8);

INT8U  OSTaskCreateExt (void   (*task)(void *p_arg),//指向任务代码的指针
                        void    *p_arg, //任务开始执行时,传递给任务的参数的指针
                        OS_STK  *ptos, //分配给任务的堆栈的栈顶指针,从顶向下递减
                        INT8U    prio, //分配给任务的优先级
                        INT16U   id, //预备给后续的版本的特殊标识符,在现行版本同任务优先级
                        OS_STK  *pbos, //指向任务堆栈栈底的指针,用于堆栈的检验
                        INT32U   stk_size, //指定堆栈的容量,用于堆栈的检验
                        void    *pext, //指向用户附加的数据域的指针,用来扩展任务的任务控制块
                        INT16U   opt, //选项,指定是否允许堆栈检验,是否将堆栈清0,任务是否要进行浮点运算等待
                         INT8U need_free_stack) //

OSTaskCreateExt(main_thread, 0, TASK_MAIN_PRIO, 0, TASK_MAIN_STACK_SIZE,NULL,(INT16U)(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR),need_free_stack);

删除任务:通过OSTaskDel来删除,之后uCOS就不会再调用了。或OSTaskDelReq来删除,后者可将资源释放后再删除自己。

改变任务优先级:OSTaskChangePrio来改变

挂起任务:OSTaskSuspend;恢复任务:OSTaskResume。


6、时间管理:

1)任务延时函数:延时的长短是用时钟节拍的数目来确定的,调用OSTimeDly(),调用后uCOS进行一次任务调度,并执行下一个优先级最高的就绪态任务。

2)按时分秒延时函数:使用OSTimeDlyHMSM()函数,

3)让延时任务结束延时:通过调用OSTimeDlyResume()和指定要恢复的任务的优先级来完成。

4)系统时间:通过调用OSTimeGet来获得计数器的当前值;或通过调用OSTimeSet()来改变该计数器的值。


7、任务之间的通信与同步

1)事件控制块ECB:通过4个系统函数OSEventWaitListInit(),OSEventTaskRdy(),OSEventWait()和OSEventTO()来实现。

2)信号量:信号量在多任务系统中用于:控制共享资源的使用权,标志事件的发生,使两个任务的行为同步。使用一个信号量之前,首先要建立该信号量,即调用OSSEMCreate(),其参数值为0到65535的一个数。如果信号量是用来表示一个或多个事件的发生,那么该信号量的初始值应设为0;如果信号量是用于对共享资源的访问,那么该信号量的初始值应设为1;如果该信号量是用来表示允许任务访问n个相同的资源,那么该初始值显然应该是n,并把该信号量作为一个可计数的信号量使用。

uCOS提供了5个对信号量进行操作的函数:OSSemCreate()->建立一个信号量;OSSemPend()->等待一个信号量;OSSemPost()->发送一个信号量;OSSemAccept()->无等待地请求一个信号量;OSSemQuery->查询一个信号量的当前状态。系统通过OSSemPend()和OSSemPost()来支持信号量的两种原子操作P()和V(),P()操作减少信号量的,如果新的信号量的值不大于0,则操作阻塞;V()操作增加信号量的值。

3)邮箱:它可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量。该指针指向了一个包含了特定“消息”的数据结构,为了在uCOS中使用邮箱,必须将OS_MBOX_EN置为1.

使用邮箱之前,必须先建立邮箱。可以通过调用OSMboxCreate()函数来完成,并且要指定指针的初始值,一个情况下,初始值为NULL,但也可以初始化一个邮箱,使其在最开始就包好一条消息。如果使用邮箱是为了通知一个事件的发生,那么就初始化该值为NULL,如果使用邮箱是为了共享某些资源,那么就要初始化该邮箱为一个非NULL的指针,此时邮箱被当成一个二值信号量使用。

uCOS提供了5种对邮箱的操作,分别是OSMboxCreate()->建立一个邮箱,OSMboxPend()->等待一个邮箱中的消息,OSMboxPost()->发送一个消息到邮箱,OSMboxAccept()->无等待地从邮箱中得到一个消息,OSMboxQuery()函数->查询一个邮箱的状态。

4)消息队列:它可以使一个任务或中断服务子程序向另一个任务发送以指针方式定义的变量。因具体的应用有所不同,每个指针指向的数据结构变量也有所不同。为了使用uCOS的消息队列,需要将OS_Q_EN置1,并且通过常数OS_MAX_QS来决定uCOS支持的最多消息队列数。

在使用一个消息队列之前,必须先建立该消息队列,这可以通过调用OSQCreate()函数,并定义消息队列中的消息数来完成。uCOS提供了7个对消息队列进行操作的函数:OSQCreate(),OSQPend(),OSQPostFront(),OSQAccept(),OSQFlush()和OSQQuery()函数。

8、内存管理:uCOS对内存的管理通过OSMemcreate()->创建一个内存分区,OSMemGet()->分配一个内存块,OSMemPut()->释放一个内存块,OSMemQuery()->查询一个内存分区的状态 4个函数来完成。




9、中断的处理有两种方法:

1)通过OSMBoxPost()、OSQPost、OSSemPost()等函数去通知该处理中断的任务,让任务完成中断事件的处理;

2)由中断服务子程序本身完成事件的处理。

中断处理的流程框架:

(1)保存全部CPU寄存器;

(2)调用OSIntEnter或OSIntNesting直接加1;

(3)执行用户代码做中断服务;

(4)调用OSIntExit();

(5)恢复所有CPU寄存器

(6)执行中断返回命令。

void UART1_IRQHandler(void)

{

OS_CPU_SR cpu_sr;

OS_ENTER_CRITICAL();//保存全局中断标志,关总中断

OSIntNesting++;

OS_EXIT_CRITICAL();//恢复全局中断标志

...//中断处理函数,一般仅仅是读取数据,处理函数在其它任务中

OSMboxPost(Com1_MOX,(void *)&msg);//假设定义了邮箱,则在这边通知邮箱有事件发生,其中msg里存的为接收到的数据。

OSIntEXIT();

}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值