📄 os_cpu_c.c
字号:
在本移植中就是这么作的。用#define语句定义的常数OS_CPU_HOOKS_EN(见OS_CFG.H)应该置为1.该函数由OSTaskCreate()或
OSTaskCreateExt()调用,用来初始化任务堆栈。将堆栈的结构初始化成看起来好像刚刚发生过中断一样,处理器的所有寄存器被推入堆栈。
当调用OSTaskCreate()或OSTaskCreateExt()建立一个新任务时,须传递的参数是:任务代码的起始地址(task),参数指针(pdata),任务堆栈
顶端的地址(ptos)以及任务的优先级(prio).OSTaskCreateExt()还需要一些其他参数,但与OSTaskStkInit()没有关系。为了合理地初始化
堆栈结构,OSTaskStkInit()只需要以上提到的前三个参数(task,pdata,ptos)。关于opt是调用OSTaskStkInit()函数时须要传递过去的参数
。因为只有OSTaskCreate()函数不支持附加的opt选项,因此,当OSTaskCreate()调用OSTaskStkInit()时,将opt设置为0x0000.
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
* stack frame of the task being created. This function is highly processor specific.
*
* Arguments : task is a pointer to the task code
*
* pdata is a pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
* of the stack.
*
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
* (see uCOS_II.H for OS_TASK_OPT_???).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*
* Note(s) : Interrupts are enabled when your task starts executing. You can change this by setting the
* PSW to 0x0002 instead. In this case, interrupts would be disabled upon task startup. The
* application code would be responsible for enabling interrupts at the beginning of the task
* code. You will need to modify OSTaskIdle() and OSTaskStat() so that they enable
* interrupts. Failure to do this will make your system crash!
*********************************************************************************************************
*/
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
//INT16U
OS_STK *stk;
(void)opt; // opt = opt;//'opt' is not used, prevent warning
stk = ptos; //stk = (INT16U *)ptos; // Load stack pointer
//The task received an optional argument ‘p_arg’. That’s why ‘p_arg’ is passed in R0 when the task is created.
//The initial value of most of the CPU registers is not important so, we decided to initialize them to values
//corresponding to their register number. This makes it convenient when debugging and examining stacks in RAM.
//The initial values are thus useful when the task is first created but, of course, the register values will most
//likely change as the task code is executed.
//代码取决于堆栈的结构。
// Registers stacked as if saved on exception
/*
*(stk) = (INT32U)0x01000000L; // xPSR
*(--stk) = (INT32U)task; // Entry Point
*(--stk) = (INT32U)0xFFFFFFFEL; // R14 (LR)
*(--stk) = (INT32U)0x12121212L; // R12
*(--stk) = (INT32U)0x03030303L; // R3
*(--stk) = (INT32U)0x02020202L; // R2
*(--stk) = (INT32U)0x01010101L; // R1
*(--stk) = (INT32U)pdata; // R0 : argument
// Remaining registers saved on process stack
*(--stk) = (INT32U)0x11111111L; // R11
*(--stk) = (INT32U)0x10101010L; // R10
*(--stk) = (INT32U)0x09090909L; // R9
*(--stk) = (INT32U)0x08080808L; // R8
*(--stk) = (INT32U)0x07070707L; // R7
*(--stk) = (INT32U)0x06060606L; // R6
*(--stk) = (INT32U)0x05050505L; // R5
*(--stk) = (INT32U)0x04040404L; // R4
*/
*(stk) = (INT32U)task; // PC, Entry Point, the code will return immediately to the task when this pops up.
*(--stk) = (INT32U)task; // LR, R14
*(--stk) = (INT32U)0x12121212L; // R12
*(--stk) = (INT32U)0x11111111L; // R11
*(--stk) = (INT32U)0x10101010L; // R10
*(--stk) = (INT32U)0x09090909L; // R9
*(--stk) = (INT32U)0x08080808L; // R8
*(--stk) = (INT32U)0x07070707L; // R7
*(--stk) = (INT32U)0x06060606L; // R6
*(--stk) = (INT32U)0x05050505L; // R5
*(--stk) = (INT32U)0x04040404L; // R4
*(--stk) = (INT32U)0x03030303L; // R3
*(--stk) = (INT32U)0x02020202L; // R2
*(--stk) = (INT32U)0x01010101L; // R1
*(--stk) = (INT32U)pdata; // R0 : argument
*(--stk) = (INT32U)0x01000000L; // xPSR //(INT32U)task;
return ((OS_STK *)stk);
// 堆栈初始化工作结束后,OSTaskStkInit()函数返回新的堆栈栈顶指针,OSTaskCreate()
// 或OSTaskCreateExt()将指针保存在任务的控制块OS_TCB中。
}
/*$PAGE*/
/*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.作任务切换时,会调用OSTaskSwHook()函数。不管任务切换是通过OSCtxSw()函数
实现的,还是通过OSIntCtxSw()函数(见OS_CPU_A.ASM)实现的,都会调用该函数。OSTaskSwHook()可以直接访问OSTCBCur和OSTCBHighRdy这
2个全局变量。OSTCBCur指向被切换出去的任务的任务控制块,而OSTCBHighRdy指向新任务的任务控制块。注意:在调用OSTaskSwHook()期
间,中断一直是关掉的。因此附加代码会影响中断的响应时间,所以尽量使这部分代码减至最少。
*
* Arguments : none
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
* task being switched out (i.e. the preempted task).
**********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskSwHook (void)
{
}
#endif
/*
*********************************************************************************************************
* OSTCBInit() HOOK
*
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.OS_TCBInit()函数在调用
OSTaskCreateHook()之前,会先调用OSTCBInitHook()函数中做一些与初始化控制块OS_TCB有关的处理;在OSTaskCreateHook()中做一些与
初始化任务有关的处理。是否用OSTaskCreateHook()和OSTCBInitHook()函数,完全取决于用户。同OSTaskCreateHook()一样,
OSTCBInitHook()会收到指向新添加任务的任务控制块的指针,而这个新添加任务的任务控制块绝大部分已经初始化完成,但是还没有链接
到已经建立任务的链表中。详见OS_TCBInit()。
*
* Arguments : ptcb is a pointer to the TCB of the task being created.
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSTCBInitHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent Compiler warning */
}
#endif
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.OSTimeTickHook()函数在每个时钟节拍都会被OSTimeTick()调用。实际上,
OSTimeTickHook()是在UCOS真正处理时钟节拍之前被调用的,以便于用户能先处理应急的事务。
*
* Arguments : none
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTimeTickHook (void)
{
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -