zoukankan      html  css  js  c++  java
  • 2019年9月25日星期三(STM32 ucos3)

    一.UCOS

    1.概念

        uc/OS-III(Micro C OS Thee),微型C语言编写的操作系统第三版。是一个可升级,可固化,多任务基于优先级的可抢占式实时内核。

        ucos的任务个数不限制,实现了操作系统所需求的大部分功能,资源管理,同步,任务之间的通信。除了这些基本的功能以外,还提供一些其他的实时性内核找不到的特色功能,比如完备的运行时间测量,也可以直接发送信号/消息到某个任务,任务也可以同时等待多个内核对象

        由于ucos体积微小,功能强悍,可移植性强,在微控制器领域应用广泛

        ucos要收费,有时候我们会选择免费的系统,比如freeRTOS....,以及一些其他和物联网结合操作系统(华为liteOS 阿里巴巴.. 腾讯..)

    2.ucos移植

    (1)源代码结构

        EvalBoards ------------ 工程文件

        uc-CPU -------------- CPU相关代码

        uc-LIB -------------- 和硬件/编译器 无关的库函数(字符串 数学 内存)

        uCOS-III ----------- ucos操作系统相关代码

     

     

    (2)将源码拷贝到工程,修改源码(详情见手册)

    (3)特性

     

    3.ucos的任务调度和任务

        合作式调度 -------- 多个任务按照指定时间和顺序依次运行,下一个任务等待上一个任务时间用完再开始运行

        抢占式调度 -------- 在任务时间片没有用完时,优先级高的任务先运行,ucos使用抢占式调度

    (1)创建任务 ------ OSTaskCreate()

      void  OSTaskCreate (OS_TCB        *p_tcb,//任务控制块(TCB)
                        CPU_CHAR      *p_name,//任务名
                        OS_TASK_PTR    p_task,//任务函数
                        void          *p_arg,//任务函数的参数
                        OS_PRIO        prio,//优先级(数字越小,优先级越高)
                        CPU_STK       *p_stk_base,//任务栈起始地址
                        CPU_STK_SIZE   stk_limit,//任务栈告警大小
                        CPU_STK_SIZE   stk_size,//任务栈大小
                        OS_MSG_QTY     q_size,//消息队列大小
                        OS_TICK        time_quanta,//时间片长度,给0默认时间
                        void          *p_ext,//补充存储区
                        OS_OPT         opt,//任务选项
                        OS_ERR        *p_err)//返回错误

     

    (2)任务函数编写注意事项

        无返回值,void *参数

        通常要写成死循环

        任务内部要加延时,让出CPU

    延时函数:

        delay_us/delay_ms

        

     void  OSTimeDlyHMSM (CPU_INT16U   hours,//时
                         CPU_INT16U   minutes,//分
                         CPU_INT16U   seconds,//秒
                         CPU_INT32U   milli,//毫秒
                         OS_OPT       opt,//选项

     

     


                         OS_ERR      *p_err)//返回错误

    (3)ucos启动

    主函数

        初始化时钟----->中断优先级分组----->串口初始化----->其他硬件初始化----->初始化ucos----->创建起始任务(启动实际工作的任务)---->启动ucos

    起始任务:

        CPU初始化----->创建任务----->删除起始任务

     

    具体工作任务:

        根据具体需求完成具体工作

    (3)ucos任务抢占

        任务执行的时候,高优先级的任务会抢占低优先级任务的CPU(数字越小优先级越高,优先级相同互相抢占)

    4.将裸机代码移植到ucos

        大部分的代码直接使用即可,只有和延时相关,中断相关的代码需要修改

    (1)延时的修改

        如果延时时间是os tick的倍数,直接使用系统延时

        如果不是,将系统调度关闭来用作延时,延时完成之后再恢复系统调度

    (2)中断的修改

        主要是要修改中断处理函数

        在中断处理函数开始时加上

            OSIntEnter();  

        在中断处理函数结束时加上

            OSIntExit();

    注;调用了ucos中的函数需要包含includes.h头文件

    二.ucos中互斥和同步,任务通信,定时器等的操作

    1.临界区

        由于ucos支持多任务,某个任务执行有可能被其他任务(中断)打断,但是某些代码如果执行过程中被打断,造成执行失败。

        为了避免这种情况,我们可以使用临界区来保护我们不希望被打断的代码。

        进入临界区的本质就是关闭系统任务调度和抢占,甚至关闭中断,从而保证临界区的代码执行不会被打断,保证执行成功,当临界区代码(关键代码)执行完毕,

        在退出临界区,恢复任务调度和抢占,或者中断,从而恢复系统的正常执行

    CPU_SR_ALLOC();//分配变量

    OS_CRITICAL_ENTER();//进入临界区

    执行关键代码.....

    OS_CRITICAL_EXIT();//退出临界区

    注意事项:

        在临界区关键代码中禁止使用延时阻塞函数,这些函数会失效,甚至影响任务的运行

        可以通过os_cfg.h中宏 OS_CFG_ISR_POST_DEFERRED_EN 的设置来决定临界区代码中是否禁用中断,设置为1,不禁用中断,0禁止中断

    2.ucos的时基

        ucos提供最小的时间单位由系统tick决定,tick值的设置在os_cfg_app.h中宏 OS_CFG_TICK_RATE_HZ

        该宏的取值范围10-1000Hz,周期1ms-100ms

        以上取值最小时间单位就是5ms,此时系统延时最小时间是5ms,低于5ms的系统延时会失效

        这个宏的值会影响ucos系统的功耗,值越大功耗越高,值越大高优先级的任务执行越及时

            在实际应用中,如果是电池供电或者设备有功耗要求,该值尽量调低

            如果固定电源供电,不关系功耗,该值可以调高

    3.ucos的信号量

        ucos中的信号量的原理和Linux中的信号量一样,也是一个计数器,可以进行PV操作,计数值为0就阻塞P操作,直到重新大于0在解除阻塞

        创建信号量 -------- OSSemCreate()

     void  OSSemCreate (OS_SEM      *p_sem,//指向信号量(控制块)
                       CPU_CHAR    *p_name,//信号量名字
                       OS_SEM_CTR   cnt,//信号量初始值
                       OS_ERR      *p_err)//错误返回

        等待信号量(P操作) ----- OSSemPend() 

     OS_SEM_CTR  OSSemPend (OS_SEM   *p_sem,//指向信号量(控制块)
                           OS_TICK   timeout,//等待时间(单位是tick,给0无限等待)
                           OS_OPT    opt,//等待方式(阻塞/非阻塞)

                            


                           CPU_TS   *p_ts,//收到信号量的时间戳,不需要给NULL
                           OS_ERR   *p_err)//错误返回

        发送信号量(V操作) ----- OSSemPost()

      OS_SEM_CTR  OSSemPost (OS_SEM  *p_sem,,//指向信号量(控制块)
                           OS_OPT   opt,//发送方式

                            


                           OS_ERR  *p_err))//错误返回

  • 相关阅读:
    Codeforces训练记录
    2017中国大学生程序设计竞赛-杭州站
    Codeforces Round #636 (Div. 3)
    自适应Simpson积分
    2020牛客暑期多校训练营(第九场)- E. Groundhog Chasing Death
    2020 Multi-University Training Contest 6
    拉格朗日插值法学习笔记
    二次剩余学习笔记
    2020 Multi-University Training Contest 3
    2020 Multi-University Training Contest 2
  • 原文地址:https://www.cnblogs.com/zjlbk/p/11593807.html
Copyright © 2011-2022 走看看