• uCOS-III基础入门函数


    uCOS-III是一个主要是运行在单片机上操作系统,可以实现并发,主要的功能就是任务、mutex、event的创建和使用。

    调度器

    调度器就是使用相关算法来决定当前需要执行的任务,调度器的核心有两个,一是调度算法,二是任务切换

    不同系统之间的任务切换都是差不多的,而调度算法却不一样,FreeRTOS和uCOS的调度算法就不一样。

    合作式调度器

    FreeRTOS支持合作式调度

    抢占式调度器

    如果使用抢占式调度,最高优先级的任务一旦准备就绪,总能得到CPU的控制权,当一个运行着的任务使一个优先级比他高的任务进入了就绪态,当前任务的CPU使用权就被剥夺了,高优先级的任务立即得到CPU控制权。学习抢占式调度最重要的一点就是 : 优先级

    时间片调度器

    最常用的时间片调度算法是round-robin调度算法,实现round-robin算法需要给同优先级的任务之间分配一个专门的列表,用于记录当前就绪的任务,还需要给每个任务一个时间片。目前FreeRTOS和uCOS-III都支持round-robin算法。

    任务创建和删除任务

    OSTaskCreate()函数
    void  OSTaskCreate (OS_TCB        *p_tcb,
    						//p_tcb: 指向任务控制块 OS_TCB
    						//TCB: Task Controller Block
    						//在ucos中用结构体OS_TCB来保存一个任务的所有信息
                        CPU_CHAR      *p_name,
    						//"字符串",指定任务的个性化的名字,如,“sb250”
    
    
                        OS_TASK_PTR    p_task,
    						//p_task 函数指针,指向任务的“任务函数”
    
                        void          *p_arg,
    						//指针,指向的对象,将作为“任务函数”的参数传入
    
                        OS_PRIO        prio,
    						//priority 任务级
    						//指定任务的优先级 "unsigned char"
    						//数字越小,优先级就越高
    						// [2, OS_CFG_PRIO_MAX - 2]
    
    
    					//STK: stack
    					//如下三个参数用来描述“任务栈”: stack
    					//"栈内存":用来保存任务执行过程中的一些参数,局部变量等等
    					//每个任务都需要有一个独立的栈空间!!!
    					//一般来说,定义一个全局的数组,用来当作任务的栈空间
    
                        CPU_STK       *p_stk_base,
    						//p_stk_base指向任务栈的基址,任务栈数组的首地址
    						//任务栈数组的元素类型必须为  CPU_STK(CPU_INT32U)
                        CPU_STK_SIZE   stk_limit,
    						//设置一个 任务栈的 下限值
    						//栈中剩余多少元素时“报警”
                        CPU_STK_SIZE   stk_size,
    						//指定任务栈中最多的元素个数(不是字节数)
    
    
    
                        OS_MSG_QTY     q_size,
    						//指定任务内部消息队列的最大消息数
    						//ucos会为每个任务在内核中创建一个消息队列,用于IPC
    
    
                        OS_TICK        time_quanta,
    						//tick: SysTick 时钟嘀哒
    						//指定该任务的时间片的长度,以时钟嘀哒为单位
    						//如: SysTick频率为  1000HZ
    						//   1s内时钟中断产生 1000次
    						// => 每隔1ms产生一个 SysTick的时钟中断
    						// 这个时钟中断的间隔,称为“Tick 时钟嘀哒”
    						// 时间片的长度为 : time_quanta * 1ms
    						// os_cfg_app.h
    						#define  OS_CFG_TICK_RATE_HZ   1000u   /* Tick rate in Hertz (10 to 1000 Hz)    
                        void          *p_ext,
    						//指向用户补充的内存区,如:在栈越界的时候,可以用
    
                        OS_OPT         opt,
    						//包含任务的特定的选项,位域,可以或:
    						// //如:
    						//  OS_OPT_TASK_NONE            No option selected  
    						// OS_OPT_TASK_STK_CHK         Stack checking to be allowed for the task
                            //  OS_OPT_TASK_STK_CLR         Clear the stack when     
    						//  /// ...                            
                        OS_ERR        *p_err
    						//p_err指针,用来保存出错信息
    						// OS_ERR_NONE 表示成功
    						// 其他值,表示失败
    					
    					)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    OSTaskDel函数

    删除任务,函数原型非常简单,只需要知道被删除任务的任务控制块就行了。

    #if OS_CFG_TASK_DEL_EN > 0u
    void  OSTaskDel (OS_TCB  *p_tcb,
                     OS_ERR  *p_err)
    
    • 1
    • 2
    • 3

    使用OSTaskDel删除一个任务的时候,这个任务的堆栈、tcb占用的内存并没有释放掉,我们可以利用他们用于其他任务

    任务挂起和恢复实验

    OSTaskSuspend()函数

    suspend:暂停

    #if OS_CFG_TASK_SUSPEND_EN > 0u
    void   OSTaskSuspend (OS_TCB  *p_tcb,
                          OS_ERR  *p_err)
    
    • 1
    • 2
    • 3

    有时候有些任务由于某些原因需要暂停运行,但是以后还要运行,因此我们不能删除任务,这里可以使用OSTaksSuspend挂起任务,以后再恢复运行。

    我们可以多次调用OSTaksSuspend来挂起一个任务,因此我们需要调用同样次数的OSTaskResume才可以恢复被挂起的任务,这一点特别重要。

    OSTaskResume()函数

    resume:恢复

    #if OS_CFG_TASK_SUSPEND_EN > 0u
    void  OSTaskResume (OS_TCB  *p_tcb,
                        OS_ERR  *p_err)
    
    • 1
    • 2
    • 3

    OSTaskResume用来恢复被OSTaskSuspend函数挂起的任务,OSTaskResume是唯一能恢复被挂起任务的函数。

    时间管理函数

    OSTimeDly函数
    void  OSTimeDly (OS_TICK   dly,
                     OS_OPT    opt,
                     OS_ERR   *p_err)
    
    • 1
    • 2
    • 3

    延时函数,延时会主动放弃CPU的执行权。

    OSTimeDlyHMSM()函数
    #if OS_CFG_TIME_DLY_HMSM_EN > 0u
    void  OSTimeDlyHMSM (CPU_INT16U   hours,
                         CPU_INT16U   minutes,
                         CPU_INT16U   seconds,
                         CPU_INT32U   milli,
                         OS_OPT       opt,
                         OS_ERR      *p_err)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    opt可以设置为严格或者非严格的。

    OSTimeDlyResume()函数

    一个任务可以通过调用这个函数来解救那些因为调用了 OSTimeDly或者OSTimeDlyHMSM而进入等待状态的任务。

    #if OS_CFG_TIME_DLY_RESUME_EN > 0u
    void  OSTimeDlyResume (OS_TCB  *p_tcb,
                           OS_ERR  *p_err)
    
    • 1
    • 2
    • 3
    OSTimeGet 和 OSTimeSet函数
    void  OSTimeSet (OS_TICK   ticks,
                     OS_ERR   *p_err)
                     
    OS_TICK  OSTimeGet (OS_ERR  *p_err)
    
    • 1
    • 2
    • 3
    • 4

    用来获取和设置当前计数器时钟节拍数的值。

    互斥信号量

    uCOS-III会改变任务的优先级。

    可以嵌套使用中断信号量(最多250次),当然也需要释放同样的次数才能真正的释放这个信号量。

    创建互斥型信号量
    OSMutexCreate()函数
    void  OSMutexCreate (OS_MUTEX  *p_mutex,
                         CPU_CHAR  *p_name,
                         OS_ERR    *p_err)
    
    • 1
    • 2
    • 3
    请求互斥型信号量
    OSMutexPend()函数

    pend:有阻塞的意思,suspend是挂起。挂起是一种主动行为,阻塞是一种被动行为。

    这里OSMutexPend是等待一个互斥信号量,如果该信号量被占用的话则一直阻塞,知道信号量被释放或者到达超时时间了。

    注意:如果占用该互斥信号量的任务比当前申请该互斥信号量的任务的优先级低的话,OSMutexPend函数会将占用该互斥信号量的任务的优先级提升到和当前申请该信号的任务的优先级一样,当任务释放掉该信号量后,优先级恢复到和之前一样。

    void  OSMutexPend (OS_MUTEX  *p_mutex,
                       OS_TICK    timeout,
                       OS_OPT     opt,
                       CPU_TS    *p_ts,
                       OS_ERR    *p_err)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    opt可以选择是否使用阻塞模式。p_ts是一个时间戳。

    释放互斥信号量
    OSMutexPost()函数
    void  OSMutexPost (OS_MUTEX  *p_mutex,
                       OS_OPT     opt,
                       OS_ERR    *p_err)
    
    • 1
    • 2
    • 3

    事件标志组

    每个事件有两种状态: 0 或者 1,用一组连续的比特位表示一组事件。

    事件标志组与任务之间有两种同步机制:“与”同步 和 “或”同步,当任意一个事件发生时进行同步的是或同步,当所有时间全部发生时才同步的是与同步。

    创建事件标志组
    OSFlagCreate()函数
    void  OSFlagCreate (OS_FLAG_GRP  *p_grp,
                        CPU_CHAR     *p_name,
                        OS_FLAGS      flags,
                        OS_ERR       *p_err)
    
    • 1
    • 2
    • 3
    • 4

    创建一个事件标志组,指定名字p_name和初始状态flags。

    等待事件标志组
    OSFlagPend()函数
    OS_FLAGS  OSFlagPend (OS_FLAG_GRP  *p_grp,
                          OS_FLAGS      flags,
                          OS_TICK       timeout,
                          OS_OPT        opt,
                          CPU_TS       *p_ts,
                          OS_ERR       *p_err)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第一个参数指定要等待的事件标志组

    第二个参数指定需要等待的事件,为 1 的位表示需要等待的事件

    timeout表示等待的最大超时时间

    opt:

    OS_OPT_PEND_FLAG_CLR_ALL 等待所有的事件位为 0 (clear),这是与事件

    OS_OPT_PEND_FLAG_CLR_ANY 等待任意时间位为 0 (clear) ,这是或事件

    OS_OPT_PEND_FLAG_SET_ALL 等待所有事件位为1 (set) ,这是与事件

    OS_OPT_PEND_FLAG_SET_ANY 等待任意事件位为1(set), 这是或事件

    p_ts是一个时间戳。

    设置事件组标志位
    OSFlagPost()函数
    OS_FLAGS  OSFlagPost (OS_FLAG_GRP  *p_grp,
                          OS_FLAGS      flags,
                          OS_OPT        opt,
                          OS_ERR       *p_err)
    
    • 1
    • 2
    • 3
    • 4

    第一个参数是要设置的事件标志组

    第二个参数是需要设置事件位(可以有多个)

    第三个参数为OS_OPT_POST_FLAG_SET或者OS_OPT_POST_FLAG_CLR

  • 相关阅读:
    Java中如何清空一个HashSet对象呢?
    el-table表格监听滚动是否到底部
    react.js在visual code 下的hello World
    如何从主机环境演变到云原生开发模式?
    Linux中怎么启动Zookeeper
    安徽2022农民丰收节 国稻种芯:郑栅洁启动舒城主场活动仪式
    C#创建并调用dll
    如何去开展软件测试工作
    LoadRunner 使用
    R绘制箱线图
  • 原文地址:https://blog.csdn.net/m0_45972156/article/details/127924387