在prvInitialiseNewTask函数中,有一个步骤7:
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
下面详细讲解这个pxPortInitialiseStack:
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
/* Simulate the stack frame as it would be created by a context switch
interrupt. */
/* Offset added to account for the way the MCU uses the stack on entry/exit
of interrupts, and to ensure alignment. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--;
*pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */
/* Save code space by skipping register initialisation. */
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
/* A save method is being used that requires each task to maintain its
own exec return value. */
pxTopOfStack--;
*pxTopOfStack = portINITIAL_EXEC_RETURN;
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
return pxTopOfStack;
}
表 2.1 寄存器及其功能
寄存器 功能
xPSR 记录 ALU 标志(0 标志,进位标志,负数标志,溢出标志),执行状态,以及
当前正服务的中断号
PRIMASK 除能所有的中断——当然了,不可屏蔽中断(NMI)才不甩它呢。
FAULTMASK 除能所有的 fault——NMI 依然不受影响,而且被除能的 faults 会“上访”,见
后续章节的叙述。
BASEPRI 除能所有优先级不高于某个具体数值的中断。
CONTROL 定义特权状态(见后续章节对特权的叙述),并且决定使用哪一个堆栈指针
1.保存xPSR。
2.保存pxCode。
pxCode是pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters )传进来的pxTaskCode1,
pxTaskCode1是prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL )传进来的pxTaskCode2
pxTaskCode2是 xTaskCreate((TaskFunction_t )start_task, //任务函数
(const char* )“start_task”, //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
传进来的start_task
3.保存prvTaskExitError; (LR)
4.自动保存/* R12, R3, R2 and R1. */(实际观察堆栈地址并未保存,下图)
5.保存pvParameters (R0)
6.portINITIAL_EXEC_RETURN(0xFFFFFFFD)**
合法的EXC_RETURN值及其功能
EXC_RETURN
数值
功能
0xFFFF_FFF1 返回handler模式
0xFFFF_FFF9 返回线程模式,并使用主堆栈(SP=MSP)
0xFFFF_FFFD 返回线程模式,并使用线程堆栈(SP=PSP)
7.自动保存/* R11, R10, R9, R8, R7, R6, R5 and R4. */(实际观察堆栈地址并未保存)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)