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

📄 core.c

📁 Bycore是一个嵌入式操作系统内核。Bycore包括内存管理、任务管理、中断管理、任务互斥、同步与通信管理等功能。Bycore全部由C语言完成
💻 C
📖 第 1 页 / 共 2 页
字号:
/** *  core.c - Task management. * *  Copyright (C) 2008  ZhangHu *  All rights reserved. *  E-MAIL: anmnmnly@gmail.com * *  This program is free software: you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation, either version 3 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program.  If not, see <http://www.gnu.org/licenses/>. */#include "include/types.h"#include "include/list.h"#include "include/core.h"#include "include/mem.h"#include "include/sem.h"#include "include/irq.h"extern void device_init(void);/* Initialize all devices */extern void Main(void); /* A routine where users start to write their codes */extern uword_t int_cnt; /* The number of interruption nesting */extern word_t int_flag; /* Interruption flag */static tcb_t idle_tcb;  /* TCB space of idle task */static stk_t idle_stk[IDLE_TASK_STACK_SIZE]; /* Stack space of idle task */static tcb_t init_tcb;  /* TCB space of initial task */static stk_t init_stk[INIT_TASK_STACK_SIZE]; /* Stack space of initial task */static lword_t idle_cnt;        /* Records the number of times of idle task */static list_t ptask[MAX_PRIO];  /* Ready queue */static list_t psleep;           /* Sleep queue */static list_t pdelay;           /* Delay queue */static list_t *pglobal;         /* A temporary pointer used by scheduler() */static uword_t highprio;        /* The hightest priority */static list_t task;             /* The head of all tasks chain */static uword_t sysclock;        /* System clock count */tcb_t *pnewtcb; /* Pointer to the TCB of the next running task */tcb_t *pcurtcb; /* Pointer to the TCB of running task *//* The following variables and arrays used to find out * the highest priority in all tasks. */static uword_t prio_rdy_grup;static uword_t prio_rdy[READY_NUM];const uword_t prio_mask[] =  {    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};const uword_t prio_decision[] =  {    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x0F */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x1F */    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x2F */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x3F */    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x4F */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x5F */    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x6F */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x7F */    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x8F */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0x9F */    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0xAF */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0xBF */    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0xCF */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0xDF */    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,  /* 0x00-0xEF */    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0   /* 0x00-0xFF */};/** * chk_task_id - Check the existence of a task ID. * @task_id: A task ID. * @return: return FALSE if task id is exist. * * @notes: just traversal the task list, and Comparing the two task IDs. */static word_t chk_task_id(uword_t task_id) {    tcb_t *ptcb;    list_t *plist = task.next;    if(plist == &task) {        return TRUE;    }    do {        ptcb = mac_find_entry(plist, tcb_t, task_link);        if(ptcb->id == task_id) {            return FALSE;        }        plist = plist->next;    } while(plist != task.next);    return TRUE;}/** * get_max_prio - Get the max priority in ready queue. * @return: The hightest priority in ready queue. * * @notes: */static uword_t get_max_prio(void) {    uword_t high;    uword_t low;    uword_t prio;    high = prio_decision[prio_rdy_grup];    low = prio_decision[prio_rdy[high]];    prio = (high << 3) + low;    return prio;}/** * add_tcb_ready - Insert a TCB into ready queue according to it's priority. * @ptcb: pointer to the TCB that will be inserted to ready queue. * @return: * * @notes: */void add_tcb_rdy(tcb_t *ptcb) {    uword_t prio = ptcb->prio;    if((prio_rdy[prio >> 3] &prio_mask[prio &0x07]) == 0) {        prio_rdy_grup |= prio_mask[prio >> 3];        prio_rdy[prio >> 3] |= prio_mask[prio &0x07];    }    add_node_list_rear(&ptask[prio], &ptcb->link);}/** * del_tcb_rdy: Delete a TCB in ready queue according to it's start address. * @ptcb: Pointer to the TCB that will be deleted from ready queue. * @return: The link list address of deleted TCB. * * @notes: */list_t *del_tcb_rdy(tcb_t *ptcb) {    uword_t prio = ptcb->prio;    list_t *renode = &ptcb->link;    if(ptcb->id == IDLE_TASK_ID && ptcb->prio == IDLE_TASK_PRIO) {        return NULL;    } else {        /* TCBs have existed in ready queue */        if(ptask[prio].next !=  &ptask[prio] && ptask[prio].prev !=           &ptask[prio]) {            /* There is only one TCB in ready queue currently */            if((ptask[prio].next == renode) && (ptask[prio].prev == renode))            if(!(prio_rdy[prio >> 3] &= ~prio_mask[prio &0x07])) {                prio_rdy_grup &= ~prio_mask[prio >> 3];            }            return (del_node_list(&ptask[prio], renode));        }    }    return NULL;}/** * add_tcb_sleep: Inserte a TCB to sleep queue. * @ptcb: Pointer to the TCB that will be inserted to sleep queue. * @return: * * @notes: */void add_tcb_sleep(tcb_t *ptcb) {    add_node_list_rear(&psleep, &ptcb->link);}/** * del_tcb_sleep: Delete a TCB from sleep queue. * @ptcb: Pointer to the TCB that will be deleted from sleep queue. * @return: * * @notes: */list_t *del_tcb_sleep(tcb_t *ptcb) {    return (del_node_list(&psleep, &ptcb->link));}/** * add_tcb_delay: Inserte a TCB to delay queue. * @ptcb: Pointer to the TCB that will be inserted to delay queue. * @return: * * @notes: */void add_tcb_delay(tcb_t *ptcb) {    add_node_list_rear(&psleep, &ptcb->link);}/** * del_tcb_delay: Delete a TCB from delay queue. * @ptcb: Pointer to the TCB that will be deleted from delay queue. * @return: * * @notes: */list_t *del_tcb_delay(tcb_t *ptcb) {    return (del_node_list(&psleep, &ptcb->link));}/** * scheduler - Estimate whether higher task has ready, and decide *             which task will be excuted. * @return: * * @notes: */void scheduler(void) {    mac_disable_irq();    if(int_flag == TRUE) {        int_cnt--;    }    if(int_cnt != 0) {        mac_enable_irq();        return ;    }    highprio = get_max_prio(); /* get the hightest priority */    if((pcurtcb != NULL) && (pcurtcb->prio <= highprio) &&  \        (pcurtcb->status == T_READY)) {        pglobal = &pcurtcb->link;    } else {        pglobal = ptask[highprio].next;    }    do {        if((pnewtcb = mac_find_entry(pglobal, tcb_t, link)) != NULL) {            if(pnewtcb->exe_time >= pnewtcb->slice_time) {                pnewtcb->exe_time = 0;                pglobal = pglobal->next;            } else {                break;            }        }    } while(1);    if(pnewtcb != pcurtcb) {        ptask[pnewtcb->prio].next = &pnewtcb->link;        if(ptask[pnewtcb->prio].prev == &pnewtcb->link) {            ptask[pnewtcb->prio].prev = (ptask[pnewtcb->prio].prev)->prev;        }        if(int_flag == FALSE) {            if(pcurtcb == NULL) {                TaskStart();            } else {                TaskSwitch();            }        } else if(int_flag == TRUE) {            int_flag = FALSE;            if(pcurtcb == NULL) {                TaskIntStart();            } else {                TaskIntSw();            }        }    } else if(int_flag == TRUE) {        int_flag = FALSE;        TaskContinue();    }}/** * idle_task - This task runs when there are no task ready. * @return: * * @note: This task is at ready status forever. */static void idle_task(void) {    while(1) {        mac_disable_irq();        idle_cnt++;        mac_enable_irq();    }}/** * idle_task - Initial task. * @return: * * @note: This task is the first application task in Bycore. */static void Init(void){	device_init();	Main();	osSleep();}/** * cre_sys_task - Crate a TCB for new task. * @ptask: Pointer to start addrees of task. * @taskid: Task ID. * @prio: The priority of task. * @time: Slice time. * @pstk: Stack size that the task ask for. * @return: * * @notes: */static word_t create_task(void(*pTask)(), tcb_t *pTcb, uword_t TaskID,                            uword_t Prio, uword_t Time, word_t *pSpace,                            uword_t StkSize) {    word_t *space = pSpace;    tcb_t *tcb = pTcb;    tcb->pstart = pSpace;    if(chk_task_id(TaskID) == FALSE) {        return FALSE;    }    /* Initialize the TCB space */    if((tcb == NULL) || (space == NULL) ||       (Prio >= MAX_PRIO) || (Time == 0)) {        return FALSE;    }#if STACK == DOWN    space += StkSize - 1;#endif    *space = (word_t)pTask; /* Store the entry address of task */    tcb->context = space;#if STACK == DOWN    space--;#else    space++;#endif    /* Initialize task stack */    init_context(space);    tcb->id = TaskID;    tcb->prio = Prio;    tcb->slice_time = Time;    tcb->exe_time = 0;    tcb->delay_time = 0;    tcb->status = T_READY;    tcb->sem_link.next = NULL;    tcb->fd_node.next = NULL;

⌨️ 快捷键说明

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