首页 技术 正文
技术 2022年11月21日
0 收藏 458 点赞 4,589 浏览 1937 个字

os_cpu_c.c文件

该文件主要是根据处理器平台特点完成任务堆栈初始化函数OSTaskStkInit以及其他几个用户Hook函数的编写,其中必须要实现的函数是OSTaskStkInit(在创建任务函数中被调用),且该函数与处理器关系密切,是系统中任务能够正常切换的基础;其他几个Hook函数,可以不包含任何代码,但是必须声明;

第一部分

任务堆栈初始化函数OSTaskStkInit();

初始化任务堆栈,主要是为任务切换服务的;

以Cortex-M3内核为例:响应异常的第一个行动,就是自动保存现场的必要部分:依次把xPSR, PC, LR, R12以及R3‐R0由硬件自动压入适当的堆栈 ,R11-R4 如果需要保存,只能手工保存 ;

因此 OSTaskStkInit()的工作就是在任务自己的栈中保存 cpu 的所有寄存器值,且按照上述特定顺序入栈出栈;

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; /* 任务入口(PC)*/
*(--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 : argument */ /* 剩下的寄存器保存在进程堆栈 */
*(--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); /* 返回(TCB)栈顶(用于任务控制块的初始化)*/
}

说明

  • xPSR = 0x01000000uL,xPSR T 位(第 24 位)置 1,否则第一次执行任务时Fault;
  • PC肯定得指向任务入口;
  • R14(LR) = OS_TaskReturn,任务返回处理函数(系统文件os_task.c中定义);
  • R0 用于传递任务函数的参数,因此等于p_arg;
  • 这些寄存器的初始化中,R1-R12初始化的值都是没什么实际意义的,主要是方便调试;

扩展

ATPCS规则,其规定了在子程序调用时的一些基本规则,包括下面3个方面:

  • 各寄存器的使用规则及其相应的名称;
  • 数据栈的使用规则;
  • 参数传递的规则;

以上各方面详细的内容如下:

  • 子程序间通过寄存器R0R3来传递参数,被调用的子程序在返回前无需恢复寄存器R0R3的内容;
  • 子程序中,使用寄存器R4R11来保存局部变量,如果在子程序中使用到了某些寄存器,则子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值;而对于子程序中没有用到的寄存器则不必进行这些操作。在Thumb程序中,通常只能使用寄存器R4R7来保存局部变量;
  • 寄存器R12用作过程中调用时的临时寄存器,记作ip,指令指针;
  • 寄存器R13用作数据栈指针,记作SP,栈指针,在子程序中该寄存器不能用作其他用途,并且在进入子程序的值和退出子程序时的值必须相等;
  • 寄存器R14称为连接寄存器,记作LR,用于保存子程序的返回地址,如果在子程序中保存了返回地址,寄存器R14则可以用作其他用途;
  • 寄存器R15时程序计数器,记作PC,专用;

第二部分

该文件中另外两个比较重要的函数:

  • OS_CPU_SysTickInit()初始化了 SysTick;
  • OS_CPU_SysTickHandler()则是 SysTick 的中断服务函数;
  • 以上两个函数也可以直接使用库函数替代;

其它函数都是些 HOOK,可按照需要使用;

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,075
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,551
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,399
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,811
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,893