📄 system.c
字号:
/**************************************************************************************************
EDL RTOS Kernel
(c) Copyright 2005, Wu Jun
All Rights Reserved
For further information, please visit http://www.enjoydigitallife.com
* Description: None
* History:
Date Remarks
2005-01-06 Created initial version
2005-12-12 Finished the version 2.01
**************************************************************************************************/
#include "datatype.h"
#include "task.h"
#include "bitmap.h"
#include "system.h"
#include "lock.h"
#include <string.h>
#include "k_alloc.h"
/**************************************************************************************************
* Locally used variables definitions
**************************************************************************************************/
static U32 enterIntTimes; /* count how many layers system has nested interrupt, this variable
is only accessed in kernel */
static LOCK kernelLock;
extern void switch_context(TCB *pre, TCB *next );
/**************************************************************************************************
* The address where starts restoring context
**************************************************************************************************/
extern void comm_exit(void);
/**************************************************************************************************
* Description: Initialize variables used in this module
**************************************************************************************************/
void sys_init( void )
{
memset( &kernelLock, 0, sizeof( kernelLock ) );
enterIntTimes = 0;
}
void sys_schedule( void )
{
U32 highestPrio;
DLIST_HEAD *dlist_head;
TCB *preTcb, *nextTcb, *tcb;
/* if scheduler is in interrupt nest, stop scheduling */
if ( enterIntTimes > 1 ){
return;
}
sys_lockKernel();
preTcb = curTskTCB;
/* If no privileged task, we start normal scheduling */
if( ( nextTcb = Privileged_Task_Tcb ) == NULL )
{
/* find the task with highest priority */
highestPrio = bm_findFirstEntry( rdyTskBitmap );
if( highestPrio > 0 )
{
nextTcb = tskTCBTable[highestPrio-1];
/* cycle to the next task with same priority */
tskTCBTable[highestPrio-1] = dl_listEntry(tskTCBTable[highestPrio-1]->tskPrioNode.dlist_head.pre, TCB, tskPrioNode.dlist_head);
}
else
{
/* If no task is at ready status, we schedule the idle task */
nextTcb = &idleTaskTCB;
}
}
if( preTcb != nextTcb )
{
curTskTCB = nextTcb;
switch_context( preTcb, nextTcb );
/* Check exit task list */
while( !dl_listEmpty( &Exit_Task_List ) )
{
dlist_head = Exit_Task_List.pre;
/* Detach the exit task from list */
dl_delNode( dlist_head);
tcb = dl_listEntry( dlist_head, TCB, tskPrioNode.dlist_head );
k_free( (U32 *)tcb->thread.BP ); /* free the stack */
}
}
sys_unlockKernel();
}
void sys_enterInterrupt( void )
{
enterIntTimes++;
}
void sys_leaveInterrupt( void )
{
if( enterIntTimes > 0 )
{
enterIntTimes--;
}
}
U32 sys_enableInterrupt( void )
{
U32 cpu_flags;
__asm
{
MRS R0, CPSR
mov cpu_flags,R0 /* Save old CPU flags */
BIC R0, R0, #NO_INT /* Clear both FIQ and IRQ bits to enable interrupt */
MSR CPSR_c, R0
}
return cpu_flags;
}
U32 sys_disableInterrupt( void )
{
U32 cpu_flags;
__asm
{
MRS R0, CPSR
mov cpu_flags,R0 /* Save old CPU flags */
ORR R0, R0, #NO_INT /* Clear both FIQ and IRQ bits to enable interrupt */
MSR CPSR_c, R0
}
return cpu_flags;
}
void sys_restoreCpuFlags( U32 flags )
{
__asm
{
MSR CPSR_c,R0
}
}
void sys_lockKernel( void )
{
if( ( curTskTCB->kerLock.nestLayers++ ) == 0 ){
curTskTCB->kerLock.cpu_flags = sys_disableInterrupt();
}
}
void sys_unlockKernel( void )
{
if( ( --curTskTCB->kerLock.nestLayers ) == 0 ){
sys_restoreCpuFlags( curTskTCB->kerLock.cpu_flags );
}
}
/**************************************************************************************************
* Description: Initialize a task's stack
**************************************************************************************************/
void sys_initContext( TCB *tcb, void (*tskProc)(void *),void *pdata, void (*exit)( void ), U32 mode_flags )
{
/* Initialize stack */
U32 *sp = (U32 *)tcb->thread.SP;
*( sp ) = (U32)tskProc; /* Entry Point */
*(--( sp )) = (U32)exit; /* R14 (LR) */
*(--( sp )) = (U32)0x12121212L; /* R12 */
*(--( sp )) = (U32)0x11111111L; /* R11 */
*(--( sp )) = (U32)0x10101010L; /* R10 */
*(--( sp )) = (U32)0x09090909L; /* R9 */
*(--( sp )) = (U32)0x08080808L; /* R8 */
*(--( sp )) = (U32)0x07070707L; /* R7 */
*(--( sp )) = (U32)0x06060606L; /* R6 */
*(--( sp )) = (U32)0x05050505L; /* R5 */
*(--( sp )) = (U32)0x04040404L; /* R4 */
*(--( sp )) = (U32)0x03030303L; /* R3 */
*(--( sp )) = (U32)0x02020202L; /* R2 */
*(--( sp )) = (U32)0x01010101L; /* R1 */
*(--( sp )) = (U32)pdata; /* R0 : Argument */
if( mode_flags & TSK_MODE_SYS ){
*(--( sp )) = (U32)ARM_SYS_MODE; /* CPSR (Enable both IRQ and FIQ interrupts) */
}
else{
*(--( sp )) = (U32)ARM_USR_MODE; /* CPSR (Enable both IRQ and FIQ interrupts) */
}
tcb->thread.SP = (U32)sp;
tcb->thread.IP = ( U32 )comm_exit;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -