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

📄 os_core.c.bak

📁 本RTOS参考 usOS-II, ARM-RTX
💻 BAK
📖 第 1 页 / 共 2 页
字号:
#include "include.h"

#define DEBUG
#define OS_TASK_SWITCH

extern uint8 idata STACK[1];
//堆栈首地址
uint8 data gStack;

//当前任务号
uint8 data OSCurrentTaskID;

//下一个任务号
//uint8 data OSNextTaskID; 


uint8 const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00};

//uint8 data OS_IRQ_Sum;//中断计数器

uint8 xdata taskMAX_stack[24];

uint8  code  OSUnMapTbl[] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             */
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             */
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             */
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             */
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             */
};
// 上面256的表可以简化为16*2的表,查表麻烦点,不过说不定最后占用代码空间更大
// 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  //0Xx0 0Xx1 0Xx2 0Xx3....0XxE 0XxF
// 0, 4, 5, 4, 6, 4, 5, 4, 7, 4, 5, 4, 6, 4, 5, 4,  //0X00 0X10 0X20 0X30....0XE0 0XF0

uint8   data         OSRdyGrp;                        // Ready list group
uint8   data         OSRdyTbl[OS_RDY_TBL_SIZE];       // Table of tasks which are ready to run

OS_TCB data Tasks_TCB[OS_MAX_TASKS];

extern void Push_Reg (void);
extern void Pop_Reg (void);



//功能描述: 系统开始运行时初始化
void OSInit(void) SMALL
{uint8 i;
    
    gStack=STACK-2; //堆栈的首地址
    //OS_IRQ_Sum = 0;
    
    OSRdyGrp=0;//就绪组标志
    memset(OSRdyTbl, 0, OS_RDY_TBL_SIZE);///就绪组内标志
    
    OSCurrentTaskID = OS_MAX_TASKS-1;//当前任务为系统任务
    
    //OSCPUInit();//初始化任务表
    for (i = 0; i < OS_MAX_TASKS; i++)
    {
       Tasks_TCB[i].pTask          = 0;      // Load Stack pointer in TCB
       //Tasks_TCB[i].OSTCBPrio    = i;  // Load task priority into TCB
       Tasks_TCB[i].OSTCBStat      = INACTIVE; //OS_STAT_RDY;    // Task is ready to run
       Tasks_TCB[i].OSTCBDly       = 0;              //Task is not delayed
       //Tasks_TCB[i].stk            = stk;
       Tasks_TCB[i].size           = 0;
       Tasks_TCB[i].stk_used       = 0;
    }
    
}

/*
该函数将创建一个系统任务

*/
//#pragma disable  //禁止所有中断
void os_sys_init(pFUN task)//( void (*task)(void) )
{char xdata *pstack;
 //char idata *stack_bottom;
 //uint8  IEtemp;
 uint16 addr;
 
    
    OS_AllIRQ_Unable(); //总中断禁止
    //IEtemp=Read_data(SP--);//将堆栈中的中断标志读出来 #pragma disable  //禁止所有中断
    
    OSInit();
    
    
    //系统任务地址
    addr=Read_data(SP--);     //读出刚才压入堆栈的函数地址.高地址
    addr <<= 8;
    addr += Read_data(SP) ;//Read_data(SP-1);  //读出刚才压入堆栈的函数地址.低地址.有错
    SP++;

    
    //保存系统任务
    Tasks_TCB[OS_MAX_TASKS-1].pTask          = (void code *)addr;  // Load Stack pointer in TCB
    //Tasks_TCB[OS_MAX_TASKS-1].OSTCBPrio      = (INT8U)priority;  // Load task priority into TCB
    Tasks_TCB[OS_MAX_TASKS-1].OSTCBStat      = READY; //OS_STAT_RDY;    // Task is ready to run
    Tasks_TCB[OS_MAX_TASKS-1].OSTCBDly       = 0;              //Task is not delayed
    Tasks_TCB[OS_MAX_TASKS-1].stk            = taskMAX_stack;
    Tasks_TCB[OS_MAX_TASKS-1].size           = sizeof(taskMAX_stack);
    Tasks_TCB[OS_MAX_TASKS-1].stk_used       = (2+13);
        
    pstack=Tasks_TCB[OS_MAX_TASKS-1].stk;
    
    //系统任务就绪
    //OSTaskResume(OS_MAX_TASKS-1);
    OSRdyGrp               |= OSMapTbl[(OS_MAX_TASKS-1)>>3];     //prio>>3-->prio/8
    OSRdyTbl[(OS_MAX_TASKS-1)>>3]      |= OSMapTbl[(OS_MAX_TASKS-1)&0x07];   //prio&0x07-->prio%8
    
    
    //将task函数地址替换为进入该函数后地址,该函数退出后将执行task函数
    task();//该函数里面会打开中断
    //addr = (uint16)task;
    //Write_data( ++SP, addr );
    //Write_data( ++SP, addr>>8 );
    //Write_data( ++SP, IEtemp );
    
}

/*------------------------------------------------------------------*-
创建任务

* pFunction--任务地址
* prio--优先级

task,   Task to create 
prio,   Task priority (1-254)
stk,    Pointer to the task's stack
size,   Number of bytes in the stack

任务创建后进入就绪状态
-*------------------------------------------------------------------*/
#pragma disable  //禁止所有中断

OS_TID  os_tsk_create_user( pFUN task, U8 prio, void* stk, STK_SIZE_BIT size ) SMALL 
{//OS_TCB    *ptcb;
 char xdata *pstack;
 uint16 i;
    
    //OS_ENTER_CRITICAL();
//    IrqAll_Unable();    //总中断禁止  IrqT0_Unable();   //定时器0中断禁止
    
    //ptcb=&Tasks_TCB[prio];
    if (Tasks_TCB[prio].pTask == NULL)
    {
        Tasks_TCB[prio].pTask          = task;      // Load Stack pointer in TCB
        //Tasks_TCB[prio].OSTCBPrio      = (INT8U)priority;  // Load task priority into TCB
        Tasks_TCB[prio].OSTCBStat      = READY; //OS_STAT_RDY;    // Task is ready to run
        Tasks_TCB[prio].OSTCBDly       = 0;              //Task is not delayed
        Tasks_TCB[prio].stk            = stk;
        Tasks_TCB[prio].size           = size;//size必须比2+13大
        Tasks_TCB[prio].stk_used       = 2+13;//2个任务地址+13个特殊功能寄存器
        
        //设置任务就绪表,让任务就绪
        OSRdyGrp               |= OSMapTbl[prio>>3];     //prio>>3-->prio/8
        OSRdyTbl[prio>>3]      |= OSMapTbl[prio&0x07];   //prio&0x07-->prio%8
        
        //堆栈初始化
        //OSTaskStkInit(task, prio);
        pstack=Tasks_TCB[prio].stk;
        
        *pstack++ = (uint8)task;     //任务低地址进栈
        *pstack++ = (uint16)task>>8; //任务高地址进栈
        for(i=0; i<Tasks_TCB[prio].size; i++)//初始化清空堆栈
        {
           *pstack++ = 0;
        }
        return (prio);
    }
    //OS_EXIT_CRITICAL();
//    IrqAll_Enable();    //总中断允许 IrqT0_Enable();          //打开T0中断允许
    return (0);
}    

#ifndef OS_TASK_SWITCH
//功能描述: 系统时钟中断服务函数
//#pragma disable  //禁止所有中断
void OSTickISR(void) interrupt 1  //OS_TIME_ISR
{uint8 data IEtemp;
    
    //TH0=T0H_COUNTER;
    //TL0=T0L_COUNTER;
    
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    //IE &= B0000_0000; //IE &= B0000_0001; //保留外部中断原来状态,屏蔽掉其他中断
    

//#if EN_TIMER_SHARING > 0
    if(TH0==0)//==0说明是定时器溢出中断,!=0表示是软件设置的定时器中断
    {
       TH0=T0H_COUNTER;
       TL0=T0L_COUNTER;
       OSTimeTick();           //调用系统时钟处理函数
    }//
    
//#else
//  OSIntSendSignal(TIME_ISR_TASK_ID); // 唤醒ID为TIME_ISR_TASK_ID的任务
//#endif
    
    
    OSIntExit();                       //在完全退出中断时,才进行任务切换
    
    //OS_AllIRQ_Enable(); //总中断允许
    IE=IEtemp;  //恢复所有中断状态
}
#else
    
#endif

/*
堆栈保存内容:
数据堆栈+函数地址+特殊功能积存器

//功能描述: 中断退出处理函数,在此进行中断后的任务切换
//IRQ_Stack_Bottom任务中断后的堆栈栈顶
//在退出中断时,不让进栈的数据出栈。在完全退出中断时,才进行任务切换,
1.1 保存当前任务堆栈
1.2 保存任务特殊功能寄存器
1.3 保存任务堆栈+任务特殊功能寄存器->堆栈备份空间
1.4 切换任务
2.1 从堆栈备份空间->恢复新的就绪的任务的堆栈
2.2 恢复任务特殊功能寄存器
2.3 将新任务原来断点地址压入堆栈
*/
void OSIntExit(void)    SMALL
{char idata * stack_bottom;
 char xdata * stack_bottom_bak;
 //uint16 addr;
 uint16 old_addr;
 uint8 old_taskid;//
    
    old_taskid=OSCurrentTaskID;
    OSFindNextRunningTask();        //查找下一个就绪的任务
    if(old_taskid==OSCurrentTaskID) //任务不切换
      return;
    
    Tasks_TCB[OSCurrentTaskID].OSTCBStat = RUNNING; //任务运行中
    //系统不备份调用本函数压入的堆栈
    old_addr=Read_data(SP--);     //读出刚才压入堆栈的函数地址.高地址
    old_addr <<= 8;
    old_addr += Read_data(SP--);  //读出刚才压入堆栈的函数地址.低地址
    
    stack_bottom=gStack+1;//当前任务堆栈底地址
    stack_bottom_bak=Tasks_TCB[old_taskid].stk;//当前任务堆栈底备份地址
    
    //1.3 保存任务堆栈+任务特殊功能寄存器->堆栈备份空间
    Tasks_TCB[old_taskid].stk_used=SP-gStack;//任务堆栈已经使用数量
    memcpy(stack_bottom_bak, stack_bottom, SP-gStack);
    
    //1.4 切换任务.前面已经执行过
    //OSFindNextRunningTask();        //查找下一个就绪的任务
    
    //2.1 从堆栈备份空间->恢复新的就绪的任务的堆栈
    stack_bottom=gStack+1;//当前任务堆栈底地址
    stack_bottom_bak=Tasks_TCB[OSCurrentTaskID].stk;//当前任务堆栈底备份地址
    SP=gStack+Tasks_TCB[OSCurrentTaskID].stk_used;//新任务恢复堆栈后,堆栈指针的位置
    
    memcpy(stack_bottom, stack_bottom_bak, Tasks_TCB[OSCurrentTaskID].stk_used);//将保存的堆栈数据拷贝到堆栈区
    
//    //2.2 恢复任务特殊功能寄存器
//  #ifdef DEBUG
//    //方便在本文件中调试,查看代码方便,将多占2byte堆栈,和一点代码空间
//    Pop_Reg();
//    SP -= 13;
//  #else
//    #pragma ASM
//    #pragma ENDASM
//  #endif
    //2.3 将新任务原来断点地址压入堆栈
    //addr = (uint16)Tasks_TCB[OSCurrentTaskID].pTask;//将新任务原来断点地址压入堆栈,在该函数退出后将恢复运行
    //Write_data( ++SP, addr );
    //Write_data( ++SP, addr>>8 );
    //Write_data( ++SP, SPtemp );//恢复中断标志
    
    Write_data( ++SP, old_addr );
    Write_data( ++SP, old_addr>>8 );
}

//功能描述: 系统时钟处理函数,处理各个任务的延时
//任务延时减为0,就进入就绪状态
//中断中调用, 各任务等待时间-1
void  OSTimeTick(void)  SMALL
{uint8 prio;
 //OS_TCB    *ptcb;
    
    //ptcb=&Tasks_TCB[0];
    for ( prio = 0; prio < OS_LOWEST_PRIO; prio++)//,ptcb++ )
    {
        if(Tasks_TCB[prio].OSTCBDly != 0 && Tasks_TCB[prio].OSTCBDly != 0xffff)
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -