Transplantation of UCOS-II on lpc2210 -- OS _cpu_c.c
CPU: Philips ARM7 lpc2210
OS: uC/OS-II 2.52
IDE: ADS 1.2
Porting an operating system to a CPU architecture requires the following:
1. Have a deep understanding of the target architecture-arm Architecture Reference Manual
2. Have a deep understanding of the operating system principle -- embedded real-time operating system uC/OS-II
3. Have a deep understanding of the compilers used-the analyticdb compiler and connector Manual
4. Have a good understanding of the operating system to be transplanted-embedded real-time operating system uC/OS-II
5. Have a certain understanding of the specific chip used-the chip data manual
Write OS _cpu_c.c
# Define OS _cpu_globals
# Include "config. H"
/*************************************** **************************************** **************************
** Function name: ostaskstkinit
** Function Description: Task Stack initialization code. If this function fails to be called, the system will crash.
** Input: task: Address of the task to start execution
** Pdata: parameters passed to the task
** Ptos: Start position of the task stack
** OPT: additional parameter. The current version is useless for this function. For more information, see the OPT parameter of ostaskcreateext ().
** Output: Stack top pointer position
** Global variables:
** Call module:
**************************************** **************************************** ************************/
OS _stk * ostaskstkinit (void (* task) (void * PD), void * pdata, OS _stk * ptos, int16u OPT)
{
OS _stk * STK;
Opt = OPT;/* 'opt' is not used. The function is to avoid compiler warnings */
STK = ptos;/* Get Stack pointer */
/* Create a task environment. ads1.2 uses the full-decrease stack */
* STK = (OS _stk) task;/* PC (R15 )*/
* -- STK = (OS _stk) task;/* LR (R14 )*/
* -- STK = 0;/* R12 */
* -- STK = 0;/* R11 */
* -- STK = 0;/* R10 */
* -- STK = 0;/* R9 */
* -- STK = 0;/* R8 */
* -- STK = 0;/* R7 */
* -- STK = 0;/* R6 */
* -- STK = 0;/* R5 */
* -- STK = 0;/* R4 */
* -- STK = 0;/* R3 */
* -- STK = 0;/* R2 */
* -- STK = 0;/* R1 */
* -- STK = (unsigned INT) pdata;/* r0, the first parameter is passed using R0 */
* -- STK = (user_using_mode | 0x00);/* spsr, which allows IRQ and FIQ interruption */
* -- STK = 0;/* osentersum ;*/
Return (STK );
}
/*************************************** **************************************** **************************
** Function name: swi_exception
** Function Description: Soft Interrupt exception handling program, which provides some system services
**
** Input: swi_num: function number
** Regs [0] is the first parameter, which is also the return value.
** Regs [1] is the second parameter.
** Regs [2] is the third parameter.
** Regs [3] is the fourth parameter.
** Output: Depends on the function.
**
** Global variable: None
** Call module: None
**
**************************************** **************************************** ************************/
# If OS _self_en> 0
Extern int const _ osfunctionaddr [];
Extern int const _ usrfunctionaddr [];
# Endif
Void swi_exception (INT swi_num, int * regs)
{
OS _tcb * ptcb;
Switch (swi_num)
{
// Case 0x00:/* job switching function OS _task_sw. For details, refer to the OS _cpu_s.s file */
// Break;
// Case 0x01:/* Start the task function osstarthighrdy. For details, refer to the OS _cpu_s.s file */
// Break;
/* When the ARM processor core is interrupted or opened, it is implemented by changing the corresponding bit in CPSR. Program Status Register CPSR due to software interruption
Saved to the spsr. The spsr is restored to the CPSR when the software is terminated and exited. Therefore, the program only needs to change the corresponding control bit in the spsr */
Case 0x02:/* Guanzhong disconnection function OS _enter_critical (), refer to the OS _cpu.h file */
_ ASM
{
Mrs r0, spsr
ORR r0, R0, # noint/* disable IRQ interruption */
MSR spsr_c, R0
}
Osentersum ++;/* add an interrupt nested counter */
Break;
Case 0x03:/* Open interrupt function OS _exit_critical (), refer to OS _cpu.h file */
If (-- osentersum = 0)/* determine whether the nested interrupt is complete */
{
_ ASM
{
Mrs r0, spsr
Bic r0, R0, # noint/* clear IRQ flag, allow interruption */
MSR spsr_c, R0
}
}
Break;
# If OS _self_en> 0
Case 0x40:
/* Return the address of the specified system service function */
/* The function address is saved in array _ osfunctionaddr */
/* Array _ osfunctionaddr needs to be defined separately */
/* Regs [0] is the first parameter, which is also the return value */
/* Regs [1] is the second parameter */
/* Regs [2] is the third parameter */
/* Regs [3] is the fourth parameter */
/* Only one parameter is the index of the system service function */
Regs [0] = _ osfunctionaddr [regs [0];
Break;
Case 0x41:
/* Return the address of the specified user's service function */
/* The function address is saved in array _ usrfunctionaddr */
/* Array _ usrfunctionaddr needs to be defined separately */
/* Regs [0] is the first parameter, which is also the return value */
/* Regs [1] is the second parameter */
/* Regs [2] is the third parameter */
/* Regs [3] is the fourth parameter */
/* Only one parameter is the index of the user service function */
Regs [0] = _ usrfunctionaddr [regs [0];
Break;
Case 0x42:/* start to process the interrupt */
Osintnesting ++;
Break;
Case 0x43:/* determine whether to switch the interrupt */
If (ostcbhighrdy = ostcbcur)
{
Regs [0] = 0;
}
Else
{
Regs [0] = 1;
}
Break;
# Endif
Case 0x80:/* switch the task to system mode */
_ ASM
{
Mrs r0, spsr
Bic r0, R0, # 0x1f/* clear first and then assign a value */
ORR r0, R0, # sys32mode/* set to system mode */
MSR spsr_c, R0
}
Break;
Case 0x81:/* switch the task to user mode */
_ ASM
{
Mrs r0, spsr
Bic r0, R0, # 0x1f
ORR r0, R0, # usr32mode
MSR spsr_c, R0
}
Break;
// 0x82 and 0x83 are used to specify the instruction sets of arm for running a task.
Case 0x82:/* the task is an arm Code */
If (regs [0] <= OS _lowest_prio) // first confirm that the task is valid
{
Ptcb = ostcbpriotbl [regs [0]; // obtain the task control block
If (ptcb! = NULL)
{
Ptcb-> ostcbstkptr [1] & = ~ (1 <5); // pointer to the top of the stack
}
}
Break;
Case 0x83:/* the task is the thumb Code */
If (regs [0] <= OS _lowest_prio)
{
Ptcb = ostcbpriotbl [regs [0];
If (ptcb! = NULL)
{
Ptcb-> ostcbstkptr [1] | = (1 <5 );
}
}
Break;
Default:
Break;
}
}
/*************************************** **************************************** **************************
** Function name: osstarthighrdy
** Function Description: run the first task with osstarthighrdy at UC/OS-II startup,
** The essence is to generate the SWI 1 command
** Input: None
** Output: None
** Global variable: None
** Call module: None
**************************************** **************************************** ************************/
Void osstarthighrdy (void)
{
_ Osstarthighrdy (); // 0x01 function number of SWI, which is used to run tasks with the highest priority
}