USCOSII

Posted zxy20175227

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USCOSII相关的知识,希望对你有一定的参考价值。

1.ucos是如何分层的?
分为四层:

  • 硬件相关层
    该层中,要尽量所有硬件相关都囊括在其中。不管是GPIO还是定时器,或串行接口。这其中有三个最为重要的接口Open、Close、Ctrl。
    Open主要来完成对应硬件初始化,形参中包括了一些初始化的相关参数。
    Close失能硬件。
    Ctrl来实现一些控制的修改如优先级、中断回调函数等等,硬件不同,内容不同。
  • 驱动接口层
    该层会用到一个或多个硬件层的接口,进行组合来实现特定功能的程序。
    以Flash为列进行说明:
    这里主要调用硬件层的SPI函数接口,但是主要的写、读指令都是在以下函数中完成的。该层中需要提供5个标准统一的接口函数:XXXOpen、XXXClose、XXXWrite、XXXRead、XXXIoCtl。
    没有被用到的函数,可以为空。本来还需要Install函数来进行动态加载和删除,因为stm32内存一般都很有限,所以舍弃动态分配。而把这5个函数用常量的形式直接编译到ROM中。在驱动的抽象接口层中可以做选择,哪些驱动要加载到内核,哪些不需要。不要的驱动不参与编译。这样有限的资源就可以得到合理的应用。该层大部分工作可以说属于一次性投入。
  • 应用接口层
    该层主要连接驱动和应用。又是连接应用层模块与模块之间的一层,这一块有很强的特殊性,第一包括了驱动抽象接口层,第二包括了模块与模块的接口层。第三又与应用层密不可分。
    首先是驱动抽象接口,这个接口其实就是通过ID去访问ID对应的五个函数。抽象接口也是一次性投入的函数,在设计时对其可靠性要很重视。
    然后是模块与模块的接口层,包括模块的接口头文件,这些头文件要求是非常独立的,不能加载模块内的内部头文件,应该包括接口函数的函数声明,在接口中尽量少用到全局变量。如果非要用到可以使用函数的方式进行传递,或ucos消息队列方式。最好用ucos进行传递,因为有很好的互斥保护功能。
  • 应用层
    该层中所有模块都算是应用层。模块内所有变量,或函数(接口除处)应该都本地化。在模块内可以有本模块化共用的主头文件,来方便本模块的维护。对硬件的访问其实直接调用应用接口就可完成。

2.HAL都有哪些代码?
stm32f2xx.h主要包含STM32同系列芯片的不同具体型号的定义,是否使用HAL库等的定义,接着,其会根据定义的芯片信号包含具体的芯片型号的头文件

#if defined(STM32F205xx) #include "stm32f205xx.h" #elif defined(STM32F215xx) #include "stm32f215xx.h" #elif defined(STM32F207xx) #include "stm32f207xx.h" #elif defined(STM32F217xx) #include "stm32f217xx.h" #else #error "Please select first the target STM32F2xx device used in your application (in stm32f2xx.h file)" #endif

紧接着,其会包含stm32f2xx_hal.h。

stm32f2xx_hal.h:stm32f2xx_hal.c/h 主要实现HAL库的初始化、系统滴答相关函数、及CPU的调试模式配置
stm32f2xx_hal_conf.h
:该文件是一个用户级别的配置文件,用来实现对HAL库的裁剪,其位于用户文件目录,不要放在库目录中。
接下来对于HAL库的源码文件进行一下说明,HAL库文件名均以stm32f2xx_hal开头,后面加上_外设或者模块名(如:stm32f2xx_hal_adc.c):

  • 库文件:
    stm32f2xx_hal_ppp.c/.h // 主要的外设或者模块的驱动源文件,包含了该外设的通用API
    stm32f2xx_hal_ppp_ex.c/.h // 外围设备或模块驱动程序的扩展文件。这组文件中包含特定型号或者系列的芯片的特殊API。以及如果该特定的芯片内部有不同的实现方式,则该文件中的特殊API将覆盖_ppp中的通用API。
    stm32f2xx_hal.c/.h // 此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的时间延迟等相关的API

  • 其他库文件
    用户级别文件:
    stm32f2xx_hal_msp_template.c // 只有.c没有.h。它包含用户应用程序中使用的外设的MSP初始化和反初始化(主程序和回调函数)。使用者复制到自己目录下使用模板。
    stm32f2xx_hal_conf_template.h // 用户级别的库配置文件模板。使用者复制到自己目录下使用
    system_stm32f2xx.c // 此文件主要包含SystemInit()函数,该函数在刚复位及跳到main之前的启动过程中被调用。 **它不在启动时配置系统时钟(与标准库相反)**。 时钟的配置在用户文件中使用HAL API来完成。
    startup_stm32f2xx.s // 芯片启动文件,主要包含堆栈定义,终端向量表等
    stm32f2xx_it.c/.h // 中断处理函数的相关实现
    main.c/.h //

3.分析任务是如何切换的。
ucos的任务切换方式一般有两种:

  • 时钟节拍中断服务函数OSTickISR()进行切换。
  • 任务中调用时间延迟函数OSTimeDly()进行切换。
    • 延迟函数OSTimeDly()进行切换:
      `y = OSTCBCur->OSTCBY;
      OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;//清除准备优先级中的X标记量
      if (OSRdyTbl[y] == 0) {
      OSRdyGrp &= ~OSTCBCur->OSTCBBitY;//如果对应的Y优先级中没有X的优先级标记了,则把Y优先级也清除
      }
      OSTCBCur->OSTCBDly = ticks;//把对应的延时时间赋值给任务控制块,在系统滴答中断中会自动减

OS_SchedNew();//从准备好的任务中找到优先级最高的,赋值给OSPrioHighRdy,然后通过OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];从任务的链表中找出对应的任务控制块, OS_TASK_SW();实际切换任务的函数,一般由汇编代码完成。`

  • 中断服务函数进行切换:
    OSTimeTick()函数的主要内容,if (ptcb->OSTCBDly != 0) 和 if (--ptcb->OSTCBDly == 0) 判断该任务块中的设定的延时是否到了,OSRdyGrp |= ptcb->OSTCBBitY; OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;延时时间到后将该任务的优先级重新加入到优先级准备变量中。
    OSIntExit()该函数和上面的内容差不多,是中断函数中真正切换任务的地方

以上是关于USCOSII的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序代码片段

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器