OS_CPU_C.C修改部分:增加OSTaskReturnHook
删除OS_CPU_SysTickHandler()
#define SYSCLK_FREQ_72MHz 72000000
#define OS_TICKS_PER_SEC 200u // Set the number of ticks in one second
系统滴答服务是5ms 1次,每秒200次
OSCtxSw任务切换函数
OSIntCtxSw()中断中切换任务
这里是在中断中切换函数时的入口,最终任务切换在PendSV_Handler中完成,代码和上面的代码是基本一样的,区别在于在执行该函数时硬件无需再保存cpu寄存器,因为在调用之前已经发生了中断,已经保存过了。
BX LR
lr就是连接寄存器(Link Register, LR),在ARM体系中LR的特殊用途有两种:一是用来保存子程序返回地址;二是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或减2),因此在各种异常模式下可以根据LR的值返回到异常发生前的相应位置继续执行。
当通过BL或BLX指令调用子程序时,硬件自动将子程序返回地址保存在R14寄存器中。在子程序返回时,把LR的值复制到程序计数器PC即可实现子程序返回。
OSPrioCur和OSPrioHighRdy存放的是用户应用任务的优先级
OSTCBCur和OSTCBHighRdy二者都指向用户任务的任务控制块。
/**********************************************************************************************/
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
PS:
将全局变量OSPrioCur地址给R0,即R0=&OSPrioCur,
将全局变量OSPrioHighRdy地址给R1,即R1=& OSPrioHighRdy,
R2 = *R1 = OSPrioHighRdy,
将R2的值赋给*R0,即*(& OSPrioCur)= OSPrioHighRdy。
/*****************************************************************************************/
/*****************************************************************************************/
LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
/*******************************************************************************************/
注释OS_CPU_SysTickInit()
注释void OS_CPU_SysTickHandler (void)
OS_CPU.H修改部分: 删除Critical Section Management
OS_CPU_A.ASM修改部分:CODE GENERATION DIRECTIVES
LDR R4, =NVIC_INT_CTRL ;rigger the PendSV exception (causes context switch)
LDR R5, =NVIC_PENDSVSET 置PENDSV中断触发,中断开启后就能进入PENDSV中断了
CRITICAL SECTION METHOD 3 FUNCTIONS包含:R0,R1替换成R4,R5
OSStartHighRdy部分
PendSV_Handler部分R0,R1修改不完全
OSTaskStkInit()并未修改
。
临界区管理
#define OS_CRITICAL_METHOD 3u
#if OS_CRITICAL_METHOD == 3u
#define OS_ENTER_CRITICAL()
{
cpu_sr = OS_CPU_SR_Save();
}
#define OS_EXIT_CRITICAL()
{
OS_CPU_SR_Restore(cpu_sr );
}
# end if
采用方法3进入临界区,即在进入临界区的时候,保存寄存器的值到变量,然后关中断;在离开临界区的时候,开中断,然后将变量的值送回register。
OS_CPU_SR_Save
MRS R0, PRIMASK ; Set prio int mask to mask all (except faults)
CPSID I
BX LR
//
OS_CPU_SR_Restore
MSR PRIMASK, R0
BX LR
PRIMASK是1位的寄存器,被置位后,可以屏蔽除不可屏蔽中断NMI之外的所有中断
移植工作包括以下几个内容:
- 用#define设置一个常量的值(OS_CPU.H)
- 声明10个数据类型(OS_CPU.H)
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /*Unsigned 8bit quantity */
typedef signed char INT8S; /* Signed 8bit quantity */
typedef unsigned short INT16U; /* Unsigned 16bit quantity */
typedef signed short INT16S; /* Signed 16bit quantity */
typedef unsigned int INT32U; /* Unsigned 32bit quantity */
typedef signed int INT32S; /* Signed 32bit quantity */
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide*/
typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
- 用#define声明三个宏(OS_CPU.H)
- 用C语言编写六个简单的函数(OS_CPU_C.C)
- 编写四个汇编语言函数(OS_CPU_A.ASM)