定位到源码的uCOS-II/Ports/ARM-Cortex-M3/Generic/IAR/os_cpu_c.c:

  os_cpu_c.c定义了9个钩子(Hook)函数和一个堆栈初始化函数。

  所谓钩子函数,是那些插入到某些函数中以扩展这些功能的函数,一般钩子函数是为第三方软件开发人员提供的扩充软件功能的入口。为了系统使用者扩展系统功能,uCOS-II中提供很多的钩子函数,使用者可以不修改uCOS-II的源码,只是往对应的钩子函数添加代码即可扩充uCOS-II的功能。

  虽说uCOS-II提供了许多钩子函数,但在实际移植我们可以实现的也就9个,这9个就位于当前文件os_cpu_c.c。钩子函数的声明是必须的,但不是必须定义。

1. 系统定时器SysTick寄存器定义

/*
*********************************************************************************************************
*                                          SYS TICK DEFINES
*********************************************************************************************************
*/#define  OS_CPU_CM3_NVIC_ST_CTRL    (*((volatile INT32U *)0xE000E010uL)) /* SysTick Ctrl & Status Reg. */
#define  OS_CPU_CM3_NVIC_ST_RELOAD  (*((volatile INT32U *)0xE000E014uL)) /* SysTick Reload  Value Reg. */
#define  OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018uL)) /* SysTick Current Value Reg. */
#define  OS_CPU_CM3_NVIC_ST_CAL     (*((volatile INT32U *)0xE000E01CuL)) /* SysTick Cal     Value Reg. */
#define  OS_CPU_CM3_NVIC_PRIO_ST    (*((volatile INT8U  *)0xE000ED23uL)) /* SysTick Handler Prio  Reg. */#define  OS_CPU_CM3_NVIC_ST_CTRL_COUNT                    0x00010000uL   /* Count flag.                */
#define  OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC                  0x00000004uL   /* Clock Source.              */
#define  OS_CPU_CM3_NVIC_ST_CTRL_INTEN                    0x00000002uL   /* Interrupt enable.          */
#define  OS_CPU_CM3_NVIC_ST_CTRL_ENABLE                   0x00000001uL   /* Counter mode.              */
#define  OS_CPU_CM3_NVIC_PRIO_MIN                               0xFFu    /* Min handler prio.          */

2. 系统初始化函数开头时会调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u    //OS_CPU_HOOKS_EN宏在os_cfg.h中
//系统初始化函数OSInit()开头调用
void  OSInitHookBegin (void)    //系统初始化函数开头的钩子函数
{INT32U   size;OS_STK  *pstk;/* Clear exception stack for stack checking.*/pstk = &OS_CPU_ExceptStk[0];size = OS_CPU_EXCEPT_STK_SIZE;while (size > 0u) {size--;*pstk++ = (OS_STK)0;}OS_CPU_ExceptStkBase = &OS_CPU_ExceptStk[OS_CPU_EXCEPT_STK_SIZE - 1u];#if OS_TMR_EN > 0uOSTmrCtr = 0u;  //当使用os_tmr.c定时器管理模块,初始化系统节拍计数数量OSTmrCtr为0,每个节拍会使得OSTmrCtr加1
#endif
}
#endif

  OS_CPU_HOOKS_EN是以操作系统配置宏。在uCOS-II中,类似于xxxx_EN这样的宏都是操作系统配置宏,它们一般被宏定义在os_cpu_cfg.h文件中。用于裁剪系统功能。这个文件理论是需要系统使用者编写的,但是我们一般采用移植的方法,使用现有的文件加以修改即可。

  OS_CPU_HOOKS_EN大于0表示当前系统使用了钩子函数这个功能。下来的8个钩子函数也都有OS_CPU_HOOKS_EN的判断操作。

3. 系统初始化函数结束时会调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSInitHookEnd (void)  //系统初始化函数结束的钩子函数
{
}
#endif

4. 创建任务时会调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSTaskCreateHook (OS_TCB *ptcb)   //创建任务的钩子函数
{
#if OS_APP_HOOKS_EN > 0u            //若有定义应用任务App_TaskCreateHook(ptcb);       //调用应用任务创建的钩子函数
#else                               //否则(void)ptcb;                     //告诉编译器ptcb没有用到。
#endif
}
#endif

  这个函数是在OSTaskCreate()或OSTaskCreateExt()中调用的。

5. 删除任务时会调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSTaskDelHook (OS_TCB *ptcb)
{
#if OS_APP_HOOKS_EN > 0uApp_TaskDelHook(ptcb);
#else(void)ptcb;
#endif
}
#endif

6. 空闲任务调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSTaskIdleHook (void) //空闲任务钩子函数
{
#if OS_APP_HOOKS_EN > 0uApp_TaskIdleHook();
#endif
}
#endif

7. 任务返回时调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSTaskReturnHook (OS_TCB  *ptcb)  //任务返回的钩子函数
{
#if OS_APP_HOOKS_EN > 0uApp_TaskReturnHook(ptcb);
#else(void)ptcb;
#endif
}
#endif

8. 统计任务调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSTaskStatHook (void) //统计任务钩子函数
{
#if OS_APP_HOOKS_EN > 0uApp_TaskStatHook();
#endif
}
#endif

9. 任务堆结构初始化函数

  c语言的函数运行需要栈来支持,局部变量就是栈这种数据结构来实现的。栈其实就是os管理内存的一种方式,os是通过栈指针sp来管理栈内存的。在单片机裸机程序中,整个程序使用一个栈,这个栈是跟main共用的栈。在os中则不一样,因为os中有任务的概念,任务在宏观上实现并行,需要现场的保护和恢复,所以不同的任务就不能共用栈。每个任务都要自己的私有栈。

OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{OS_STK *stk;(void)opt;                                   /* 'opt' 并没有用到,防止编译器提示警告  */stk       = ptos;                            /* 加载栈指针 *///发生中断后,xPSR, PC, LR, R12, R3-R0被自动保存在栈中    *(stk)    = (INT32U)0x01000000uL;            /* xPSR                                               */*(--stk)  = (INT32U)task;                    /* Entry Point(任务的入口)                            */*(--stk)  = (INT32U)OS_TaskReturn;           /* R14 (LR)                                           */*(--stk)  = (INT32U)0x12121212uL;            /* R12                                                */*(--stk)  = (INT32U)0x03030303uL;            /* R3                                                 */*(--stk)  = (INT32U)0x02020202uL;            /* R2                                                 */*(--stk)  = (INT32U)0x01010101uL;            /* R1                                                 */*(--stk)  = (INT32U)p_arg;                   /* R0 : 变量                                          *//* 剩下的寄存器需要手动保存在堆栈         */                                             *(--stk)  = (INT32U)0x11111111uL;            /* R11                                                */*(--stk)  = (INT32U)0x10101010uL;            /* R10                                                */*(--stk)  = (INT32U)0x09090909uL;            /* R9                                                 */*(--stk)  = (INT32U)0x08080808uL;            /* R8                                                 */*(--stk)  = (INT32U)0x07070707uL;            /* R7                                                 */*(--stk)  = (INT32U)0x06060606uL;            /* R6                                                 */*(--stk)  = (INT32U)0x05050505uL;            /* R5                                                 */*(--stk)  = (INT32U)0x04040404uL;            /* R4                                                 */return (stk);
}

  OSTaskStkInit()的作用就是对任务的栈内存进行初始化,我们每创建一个任务,都应该调用这个函数对任务的私有栈进行初始化,之后再去使用。
参数1: 指向任务的执行代码
参数2: 传给任务的调用时的参数
参数3: ptos指向栈顶
  ARM是满降栈,也就是sp指针指向的内容都是满的,但是一开始ptos指向的是栈的最上方,而刚开始的时候该位置肯定为空,所以ptos指向的是”free”的。
参数4: 可选项,起到改变函数行为的效果,这是用于扩展的。但是uCOS-II暂时没用到。

  在CM3内核中,函数发生中断后,xPSR,PC,LR,R12,R3-R0会被自动保存到栈中,R11-R4如果需要保存,需要手动保存。OSTaskStkInit()既然是在初始化这份栈,所以需要模拟被中断后的样子。代码中,R1-R12、R4-R11都没什么意义,目的在于方便调试,但是,
(1) xPSR=0x01000000L,xPSR的T位(第24位)置1,否则第一次执行任务时就Fault
(2) PC必须指向任务入口
(3) R14=任务返回函数
(4) R0用于传递任务的参数,等于p_arg

10. 切换任务时被调用的钩子函数

#if (OS_CPU_HOOKS_EN > 0u) && (OS_TASK_SW_HOOK_EN > 0u)
void  OSTaskSwHook (void)   //切换任务时被调用的钩子函数
{
#if OS_APP_HOOKS_EN > 0u    //如果有定义应用任务App_TaskSwHook();       //应用任务切换调用的钩子函数
#endif
}
#endif

11. 初始任务控制块化时调用的钩子函数

#if OS_CPU_HOOKS_EN > 0u
void  OSTCBInitHook (OS_TCB *ptcb)  //初始任务控制块化时调用的钩子函数
{
#if OS_APP_HOOKS_EN > 0uApp_TCBInitHook(ptcb);
#else(void)ptcb;
#endif
}
#endif

  TCB即Task Control Block,任务控制块,记录了系统中每个任务的状态、属性信息。

12. 时钟节拍到了以后调用的钩子函数

#if (OS_CPU_HOOKS_EN > 0u) && (OS_TIME_TICK_HOOK_EN > 0u)
void  OSTimeTickHook (void)
{
#if OS_APP_HOOKS_EN > 0uApp_TimeTickHook();         //应用程序的时钟节拍钩子函数
#endif#if OS_TMR_EN > 0u              //如果有启动定时器管理OSTmrCtr++;                 //计时全局变量OSTmrCtr自加1//如果时间到了if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {OSTmrCtr = 0;   //计时清零OSTmrSignal();  //发送信号量OSTmrSignal(初始值为0)//以便软件定时器扫面任务OSTmr-Task能请求到信号量继续运行}
#endif
}
#endif

13. SysTick超时后执行的函数

void  OS_CPU_SysTickHandler (void)
{/* 进入临界区,OSIntNesting是全局变量,操作该变量时希望不被中断打扰 */OS_CPU_SR  cpu_sr;OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR          */OSIntNesting++;/* 退出临界区 */OS_EXIT_CRITICAL();OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */OSIntExit();                                 /* Tell uC/OS-II that we are leaving the ISR          */
}

14. 初始化SysTick定时器

void  OS_CPU_SysTickInit (INT32U  cnts)
{//使能SysTick定时器OS_CPU_CM3_NVIC_ST_RELOAD = cnts - 1u;/* Set prio of SysTick handler to min prio.           *///使能SysTick定时器中断OS_CPU_CM3_NVIC_PRIO_ST   = OS_CPU_CM3_NVIC_PRIO_MIN;/* Enable timer.                                      */OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC | OS_CPU_CM3_NVIC_ST_CTRL_ENABLE;/* Enable timer interrupt.                            */OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_INTEN;
}

  OS_CPU_SysTickInit会被第一个任务调用,用于初始化SysTick定时器。

  OS_CPU_SysTickHandler(void)和OS_CPU_SysTickInit (INT32U cnts)在移植的时候,我们会注释掉,取而代之的是STM32标准外设库的函数。

  在本文件中,涉及到任务的很多概念,如TCB任务控制块、任务调度、统计/空闲任务等,这些将在下来的文章中介绍。

os_cpu_c.c相关推荐

  1. 启动之OS_CPU_C

    任务堆栈结构的初始化 在uC/OS-II中,任务是一个无限循环,任务之间也不会互相调用,但是uC/OS-II总是执行优先级最高的任务,假定当前有一个更高优先级的任务进入就绪状态,为了保证原来低优先级任 ...

  2. 使用bc45编译ucos-II的配置过程

    1.将ucos_ii的源代码解压到c盘根目录下形成SOFTWARE文件夹(使用网上盛传的压缩文件SOFTWARE.RAR) 2.将bc45安装在c盘根目录下,形成bc45文件夹,从别的地方复制tasm ...

  3. RTOS之uCOS-II源码下载及源码目录结构、常见的RTOS!

    RTOS有众多种,用得最火的是FreeRTOS,因为它即使用于商业途径,也是开源免费的:其次是就是uCOS-II和uCOS-III.uCOS-II用于商业途径是需要付费的,但是对于学习研究却是免费的. ...

  4. ARM学习方法大杂烩,高手经验之谈,内容完全来自互联网

    一步一步学习uCOS和ARM体系结构的心得 学习必备条件: 1.一块开发板--例如44B0开发板,建议初学者不要去购买那些ARM9体系结构的,因为作为初学者来说ARM9体系的东西是很复杂的,买块ARM ...

  5. STM32迷你板UCOSII系统移植

    写在前面: 所需要下载的UCOSII代码链接:https://pan.baidu.com/s/1D_IyXhODEa5oVUdDv-GJrQ 提取码:mte3 本文结构 1.UCOSII简介 2.UC ...

  6. μC/OS-I移植需要编写的文件

    移植μC/OS-II到一个新的体系结构上需要提供2个或3个文件: OS_CPU.H(C语言头文件) OS_CPU_C.C(C程序源文件) OS_CPU_A.ASM(汇编程序源文件) 移植代码包括的内容 ...

  7. UCOS 操作系统 安装配置环境

    一.下载Borland C++ 4.5或Borland C++ 5.0和Turbo Assembler 5.0(TASM 5.0) 二.安装Borland C++ 4.5/5.0(我的安装在C:/BC ...

  8. μC-/OS II(一) PC编译环境的搭建

    这个系列博文是关于对<嵌入式实时操作系统 μC-/OS II>(第二版)的学习笔记 μC-/OS II (一)  PC编译器环境的搭建 1.关于编译器 采用Borland C++ 4.5作 ...

  9. uCOS-II中的OS_CPU.h,OS_CPU_A.s,OS_CPU.c

    μC/OS-Ⅱ的移植集中在OS_CPU.h,OS_CPU_A.s,OS_CPU.c这三个文件上,下面分别详细介绍三个文件中的函数和需要修改或者编写的代码. 1. OS_CPU.h的移植 该文件定义了和 ...

最新文章

  1. php 会话控制 文件上传
  2. 详细讲解在Spring中进行集成测试AbstractDependencyInjectionSpringContextTests
  3. 无法定位程序输入点dxgiget_美国ABB TZIDC 智能定位器调试方法
  4. (二十七)【2021 WWW】Learning Intents behind Interactions with Knowledge Graph for Recommendation
  5. 黄冈中学首页布局(自己做的)
  6. Android学习笔记(二)——TextView常用属性以及下划线、跑马灯设置
  7. bmp转YUV RGB转YUV HM学习
  8. java IO 超详细讲解
  9. JQuery常用属性整理
  10. QML入门教程(1): Qt Quick与QML介绍
  11. SAT写作例子之Frank Lloyd Wright
  12. [大洋] Unity3D架构系列之- FSM有限状态机设计一至四
  13. android实现vr 功能,VR模式成亮点:属于Android N的10大新功能
  14. 不一样的课程表,不一样的Excle--用Excle进行设计(12):网状结构
  15. vue将链接转为二维码的方法即插件
  16. Windows11系统下Edge如何兼容IE浏览器
  17. [配置文件]_start.wzd
  18. 远程监控tomcat运行
  19. Mac电脑使用:下载安装SourceTree的步骤以及使用方法
  20. 有关于python的论文_有关python的论文

热门文章

  1. 【Python】记录抓包分析自动领取芝麻HTTP每日免费IP(成品+教程)
  2. macOS如何查看pdm文件
  3. MySQL使用gpfs共享磁盘_GPFS文件系统笔记
  4. Python游戏开发,Python实现童年小游戏推箱子 附带源码
  5. 数据仓库——数据采集与同步【系统埋点设计】
  6. java bll dal_C#中三层架构UI、BLL、DAL、Model实际操作
  7. 高德地图:实现3D模型轨迹回放效果(类似百度地图汽车模型路书)
  8. 动态规划算法之资源分配问题及其空间优化方案
  9. MATLAB | 入门——学习笔记
  10. LUT预设KREATIV WEDDING LUTS VOL4