⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 system.c

📁 一个小型的嵌入式操作系统内核,可用于多种硬件平台
💻 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 + -