目录
前言
在创建完一个任务后,下一步要做的就是启动任务,本文对Free RTOS V10.0.1的启动任务的源码进行分析
一、创建空闲任务
创建空闲任务的目的:
1)释放被删除任务的TCB与栈 (清理内存)
2)在没有其他任务时,供CPU运行的任务。
二、启动调度器
2.1.设置PendSV和systick中断为最低优先级
在Free RTOS中,所有的中断优先级都大于任务的优先级,即最小的中断优先级>最大的任务优先级
PendCV和systick中断是为Task服务的,所以需要将PendCV和systick的优先级设置为最低。
/* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
2.2.使能systick中断
systick与其他定时器不同,systick属于内核定时器,是一个24位的倒计数定时器。
有4个寄存器控制systick定时器。systick在rtos中作为心脏,每1ms产生一次中断,在中断中切换任务。
寄存器名称 | 地址 |
---|---|
systick控制和状态寄存器 | 0xE000_E010 |
systick重装载数值寄存器 | 0xE000_E014 |
systick当前数值寄存器 | 0xE000_E018 |
systick校准数值寄存器 | 0xE000_E01C |
/* Stop and clear the SysTick. */
portNVIC_SYSTICK_CTRL_REG = 0UL;/* 控制和状态寄存器复位 */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;/* 当前数值寄存器复位 */
/* Configure SysTick to interrupt at the requested rate. */
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
三、触发SVC异常、启动第一个任务
启动任务部分使用汇编实现。任务在SVC异常中断中完成启动。
3.1.触发SVC异常
__asm void prvStartFirstTask( void )
{
PRESERVE8
/* Use the NVIC offset register to locate the stack. */
ldr r0, =0xE000ED08 /* 向量表偏移寄存器地址 */
ldr r0, [r0]
ldr r0, [r0] /* 此时R0保存的地址和启动文件中的__initial_sp一样 */
/* Set the msp back to the start of the stack. */
msr msp, r0 /* MSP指向__initial_sp */
/* Globally enable interrupts. */
cpsie i
cpsie f
dsb /* 数据同步屏障Data Synchronization Barrier */
isb /* 指令同步屏障Instruction synchronization barrier */
/* Call SVC to start the first task. */
svc 0 /* 开启SVC异常 启动pxCurrentTCB指向的任务 */
nop
nop
}
3.2.SVC异常中断函数
发生SVC异常后,会执行一下操作
1)硬件保存寄存器值
2)LR寄存器保存一个特殊地址
3)调用C函数
4)返回LR地址,硬件恢复寄存器值
__asm void vPortSVCHandler( void )
{
PRESERVE8
ldr r3, =pxCurrentTCB /* Restore the context. */
ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
ldmia r0!, {r4-r11} /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
msr psp, r0 /* Restore the task stack pointer. */
isb
mov r0, #0
msr basepri, r0
orr r14, #0xd
bx r14
}
总结
详细过程查看Free RTOS源码 和《ARM Cortex-M3与Cortex-M4权威指南》