📄 os_cpu_c.c
字号:
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* (c) Copyright 2002, Micrium, Inc., weston, FL
* All Rights Reserved
*
*
* NEC 78K4 Specific code
*
* File : OS_CPU_C.C
* By : Satel Oy
*********************************************************************************************************
*/
#ifdef __IAR_SYSTEMS_ICC
#include <In78400.h>
#include <78f4216.h>
#endif
#define OS_CPU_GLOBALS
#include "includes.h"
#define PUSHALL _ASM("PUSH RP0,RP1,RP2,RP3"); \
_ASM("PUSH RG4"); \
_ASM("PUSH RG5"); \
_ASM("PUSH RG6"); \
_ASM("PUSH RG7")
#define POPALL _ASM("POP RG7"); \
_ASM("POP RG6"); \
_ASM("POP RG5"); \
_ASM("POP RG4"); \
_ASM("POP RP0,RP1,RP2,RP3")
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
* (BEGINNING)
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments : none
*
* Note(s) : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSInitHookBegin (void)
{
}
#endif
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
* (END)
*
* Description: This function is called by OSInit() at the end of OSInit().
*
* Arguments : none
*
* Note(s) : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSInitHookEnd (void)
{
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : ptcb is a pointer to the task control block of the task being created.
*
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskCreateHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
#endif
/*
*********************************************************************************************************
* TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : ptcb is a pointer to the task control block of the task being deleted.
*
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskDelHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
#endif
/*
*********************************************************************************************************
* IDLE TASK HOOK
*
* Description: This function is called by the idle task. This hook has been added to allow you to do
* such things as STOP the CPU to conserve power.
*
* Arguments : none
*
* Note(s) : 1) Interrupts are enabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
void OSTaskIdleHook (void)
{
}
#endif
/*
*********************************************************************************************************
* STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-II's statistics task. This allows your
* application to add functionality to the statistics task.
*
* Arguments : none
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskStatHook (void)
{
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE A TASK'S STACK
*
* 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.
*********************************************************************************************************
*/
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
INT8U *stk;
opt = opt; /* 'opt' is not used, prevent warning */
stk = (INT8U *)ptos; /* Load stack pointer */
*stk-- = 0x00;
*stk-- = 0x00;
/* Ram is always on 78400 16bit addressable area */
*stk-- = (INT8U)((INT32U)(pdata) >> 8 );
*stk-- = (INT8U)((INT32U)pdata);
*stk-- = 0x0F & (INT8U)((INT32U)(task) >> 16 ); /* 7-4 PSWhigh, 3-0 PChigh */
*stk-- = 0x08; /* PSW */
*stk-- = (INT8U)((INT32U)(task) >> 8 );
*stk-- = (INT8U)((INT32U)task);
*stk-- = 0x11; /* RP0 */
*stk-- = 0x22;
*stk-- = 0x33; /* RP1 */
*stk-- = 0x44;
*stk-- = 0x55; /* RP2 */
*stk-- = 0x66;
*stk-- = 0x77; /* RP3 */
*stk-- = 0x88;
*stk-- = 0xBB; /* RG4 */
*stk-- = 0xCC;
*stk-- = 0xDD;
*stk-- = 0xEE; /* RG5 */
*stk-- = 0xFF;
*stk-- = 0x00;
*stk-- = 0x11; /* RG6 */
*stk-- = 0x22;
*stk-- = 0x33;
*stk-- = 0x44; /* RG7 */
*stk-- = 0x55;
*stk = 0x66;
return ((OS_STK *)stk);
}
/*$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.
*
* 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.
*
* 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.
*
* 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
/*
**********************************************************************************************************
* START MULTITASKING
* void OSStartHighRdy(void)
*
* Note : OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Set OSRunning to TRUE,
* c) Switch to the highest priority task.
**********************************************************************************************************
*/
void OSStartHighRdy (void)
{
#if OS_CPU_HOOKS_EN
OSTaskSwHook();
#endif
OSRunning = 1;
_ASM(" MOVG RG4, N:OSTCBHighRdy");
_ASM(" MOVG WHL, [RG4]");
_ASM(" MOVG SP, WHL");
POPALL;
_ASM("RETI");
}
/*
**********************************************************************************************************
* INTERRUPT LEVEL CONTEXT SWITCH
**********************************************************************************************************
*/
void OSIntCtxSw (void)
{
/* Value 19 should be counted from push's from OsIntExit, see manual */
_ASM("ADDWG SP,#19");
/* *OSTCBCur = SP */
_ASM(" MOVG RG4, N:OSTCBCur");
_ASM(" MOVG WHL, SP");
_ASM(" MOVG [RG4], WHL");
#if OS_CPU_HOOKS_EN
OSTaskSwHook();
#endif
_ASM( "MOV R1, N:OSPrioHighRdy" );
_ASM( "MOV N:OSPrioCur, R1" );
_ASM( "MOVG RG4, N:OSTCBHighRdy" );
_ASM( "MOVG N:OSTCBCur, RG4" );
_ASM( "MOVG RG4, N:OSTCBHighRdy" );
_ASM( "MOVG WHL, [RG4]" );
_ASM( "MOVG SP, WHL" );
POPALL;
#if 0
/* If OS_EXIT_CRITICAL() is something else than _EI() this should enabled */
_DI( );
OS_EXIT_CRITICAL();
#endif
_ASM(" RETI");
}
#pragma codeseg(RCODE)
/*
**********************************************************************************************************
* TASK LEVEL CONTEXT SWITCH
**********************************************************************************************************
*/
interrupt [BRK_vect] void OSCtxSw (void)
{
_EI();
PUSHALL;
/* *OSTCBCur = SP */
_ASM(" MOVG RG4, N:OSTCBCur");
_ASM(" MOVG WHL, SP");
_ASM(" MOVG [RG4], WHL");
#if OS_CPU_HOOKS_EN
OSTaskSwHook( );
#endif
_ASM( "MOV R1, N:OSPrioHighRdy" );
_ASM( "MOV N:OSPrioCur, R1" );
_ASM( "MOVG RG4, N:OSTCBHighRdy" );
_ASM( "MOVG N:OSTCBCur, RG4" );
_ASM(" MOVG RG4, N:OSTCBHighRdy");
_ASM(" MOVG WHL, [RG4]");
_ASM(" MOVG SP, WHL");
POPALL;
OS_EXIT_CRITICAL();
/* _ASM(" RETI"); */
}
/*
**********************************************************************************************************
* TICK ISR
**********************************************************************************************************
*/
interrupt [INTTM8_vect] void OS_Timer (void)
{
_ASM( "PUSH RP0" );
_ASM( "MOV R1, F:OSIntNesting" );
_ASM( "ADD R1, #0x1" );
_ASM( "MOV F:OSIntNesting, R1" );
_ASM( "POP RP0" );
OSTimeTick(); /* Notify uC/OS-II that a tick has occured */
PUSHALL;
OSIntExit(); /* Notify uC/OS-II about end of ISR */
POPALL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -