compact OS kernel

我們生活周遭存在太多太多的 embedded system ,過去 embedded system 有專屬的 OS,現在 linux 也可以應用在嵌入式環境,不過本版將廣泛討論所有嵌入式系統不只 linux 喔,歡迎有這方面經驗或有興趣的朋友一同進來討論。

版主: chester

compact OS kernel

文章chester » 週二 11月 26, 2002 8:53 am

一個最簡易的 kernel 大概是如此..

代碼: 選擇全部

/*-----------------------------------------------------------------
CopyRight (C) 1999, Dmitry Obukhov, dso@usa.net
--------------------------------------------------------------------

http://www.EmbeddedStuff.com

Compact Real-Time kernel (CRTK) for embedded applications
 * It is really compact. It is not NT and even not CE. But...
 * I wrote ISDN stack, running in this environment, this
 * kernel can run on almost any 8-bit MCU. And it is compact.
 * It means - no problem to add features, no problem to remove.
 * No any line in assembler - you can transfer it in minutes to
 * any new MCU.
 *
 * Of course, this is freeware version does not contains some nice
 * features, such as software task slice control, automatic sleep
 * mode, registers polling, embedded trace etc. If you want a
 * commercial release - please contact me over e-mail.
 * */

#include <stdlib.h>

#define MAXTASK 64
#define NORMAL_EXIT 1

typedef void (* FPTR    )(void); // POINTER TO TIMER INTERRUPT HANDLER
typedef void (* VPTR    )(void *); // POINTER TO TIMER FUNCTION
typedef void (* TPTR    )(unsigned int * , void *); // Pointer to task



typedef struct
{
    unsigned int * status;      // Scheduler checks contents by this pointer
    TPTR           code;        // Task code
    void         * data;        // Task data for use same code for
                                // multiple logical streams
    unsigned int   priority;    // Priority of this task
    unsigned long  id;          // Task ID
    unsigned int   status_mode; // How to check status value (used as bit set)
    unsigned int   prev_status; // Prevoious value of status. Used in
                                // "polling-for-change"
    unsigned int   time_to_live;// Time (in tens of mS) to be in task
} SCELL;

//SCELL         * task;                   // Array of task description cells
SCELL         task[MAXTASK];            // Array of task description cells
int           max_task;                 // Quantity of currently running tasks
FPTR          wakeup_handler;           // Pointer to wake up function
FPTR          sleep_mode_handler;       // pointer to deactivation procedure
unsigned long sleep_mode_count;         // maximum of void loops till sleep
unsigned long void_loops;               // void loops counter
unsigned char enable_sleep;             // flag to enable/disable sleep mode
unsigned long last_id;                  // last ID issued
unsigned int  time_to_be_in_task;       // Value will be decremented in timer
                                        // interrupt handler


void init_scheduler(void)
{
    int i;
    for (i=0;i<MAXTASK;i++)
    {
        task[i].status      = NULL;
        task[i].code        = NULL;
        task[i].data        = NULL;
        task[i].priority    = ~0;//0xFFFF;
        task[i].status_mode = 0; // Not used in this version
        task[i].prev_status = 0;
        task[i].id          = 0; //0 is not valid ID
    }
    max_task = 0;
    last_id  = 0;
    time_to_be_in_task = 0xFFFF;
}

void sort_tasks_according_to_priority(void)
{
    int no_changes;
    int i;
    SCELL tmp;
    if ( max_task<2 ) return; //No tasks or only one - nothing to sort :-)
    no_changes = 0;                     // For loop entry
    while ( !no_changes)                // While all task list was not passed
    {                                   // without any modifications
        no_changes = 1;
        for ( i=0; i<max_task-1; i++)
        {
            if ( task[i].priority > task[i+1].priority)
            {// Task with higher priority located after low priority task
             // Swap it and mark no_changes for next check
                //Copy current task to tmp
                memcpy(&tmp,&task[i],sizeof(SCELL));
                //Move high priority task up
                memcpy(&task[i],&task[i+1],sizeof(SCELL));
                //Move low priority task down
                memcpy(&task[i+1],&tmp,sizeof(SCELL));
                no_changes = 0;
            }
        }
    }
    // Remove all empty tasks
    while ( task[max_task - 1].status == NULL) max_task --;
}


unsigned long install_task(void         * ttstatus,
                           TPTR           tcode,
                           void         * tdata,
                           unsigned int   tpriority,
                           unsigned int   task_mode,
                           unsigned int   time_to_live)
{
   unsigned int * tstatus = (unsigned int *) ttstatus;

   if (max_task>=MAXTASK)
   {
       // OS_ERROR
       // Oops! You have to compile your
       // with larger task pool.
       return 0;
   }
   task[max_task].status       = tstatus;
   task[max_task].code         = tcode;
   task[max_task].data         = tdata;
   task[max_task].priority     = tpriority;
   task[max_task].id           = ++last_id;
   task[max_task].status_mode  = task_mode;
   task[max_task].time_to_live = time_to_live;
   max_task++;
   /* More than 4,294,967,295 tasks was installed (and removed,
    * probably). But something goes wrong. */
   if (!last_id) /* os_error() */;

   sort_tasks_according_to_priority();
   return last_id;
}

unsigned int find_task(unsigned long id)
{
   unsigned int i;
   for ( i=0; i<max_task; i++)
   {
       if ( task[i].id == id) return i;
   }
   return 0xFFFF;
}


void remove_task(unsigned long id)
{
    unsigned int tmp;
    tmp = find_task(id);
    if ( tmp != 0xFFFF)                 // Task is in the list. Remove it.
    {
        task[tmp].status   = NULL;        // Never will be called by scheduler
        task[tmp].priority = 0xFFFF;      // Move to the end of list
        sort_tasks_according_to_priority();
        //max_task--;
    }
}

void uninstall_task(void         * ttstatus,
                    TPTR           tcode,
                    void         * tdata)
{
    unsigned int i;
    for ( i=0; i<max_task; i++)
    {
      // This 3 parameters identifies the task
      // Each one can be used with different data but together we never kill
      // wrong task
       if ( task[i].status == ttstatus &&
            task[i].code   == tcode &&
            task[i].data   == tdata)
       {
         task[i].status   = NULL;        // Never will be called by scheduler
         task[i].priority = 0xFFFF;      // Move to the end of list
         sort_tasks_according_to_priority();
         //max_task--;
         return;
       }
    }
}

void change_task_priority(unsigned long id, unsigned int p)
{
    unsigned int tmp;
    tmp = find_task(id);
    if ( tmp != 0xFFFF)                 // Task is in the list.
    {
        task[tmp].priority = p;           // Change priority
        sort_tasks_according_to_priority();  // Arrange list
    }
}

int stop_scheduler;

void scheduler(void)
{
    int current_task;
    stop_scheduler = 0;
    current_task = 0;
    while (!stop_scheduler)
    {
        if ( *task[current_task].status )
        {
            /////////////////////////////////////////////////////////////////
            // ----------------------------------------------TASK ENTRY POINT
            /////////////////////////////////////////////////////////////////
            (task[current_task].code)(task[current_task].status, ////////////
                                      task[current_task].data);  ////////////
            /////////////////////////////////////////////////////////////////
            current_task = 0; // Restart from task with lowest priority
        }
        else if (++current_task >= max_task)
        {
            current_task = 0;
        }
    }
}

void os_shutdown(int code)
{
    stop_scheduler = code;
}

#define CRTK_TASK(x) void x(unsigned int * task_status, void * task_data)

/*---------------------------------------------------------------
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * --------------------------------------------------------------
 * ------------------------------------------------------------*/


void hardware_init(void)
{
    // turn on your whistles here
}

void os_init(void)
{
    // A lot of stuff and
    init_scheduler();
}

void os_finish(void)
{
    // empty in free version
}

void application_finish(void)
{
    // empty in free version
}


// Actually this 3 functions are in different module

unsigned int  task_flag;                 // increment it in interrupt
unsigned long task_counter;
unsigned int  run_always;

CRTK_TASK(just_dummy_task)
{
    unsigned int * flag = (unsigned int *) task_status;
    unsigned long * count = (unsigned long *) task_data;

    *flag = 0;
    (*count) ++;

    // Blink a lamp, write "Hello, world"
}


CRTK_TASK(read_keyboard)
{
    unsigned int * flag = (unsigned int *) task_status;

    if (kbhit()) *flag = getch();
    if (*flag == 0x1B) os_shutdown(NORMAL_EXIT);
}


void application_init(void)
{
    install_task(&task_flag,            // if this integer not zero
                  just_dummy_task,      // Call this function
                 &task_counter,         // With pointer to this structure
                 0x1000,                // Task priority
                 0,0);                  // Not used in public version

    run_always = 0xFFFF;

    install_task(&run_always,            // if this integer not zero
                  read_keyboard,      // Call this function
                  NULL,         // With pointer to this structure
                 0xFFFF,                // Task priority
                 0,0);                  // Not used in public version

}



void main(void)                         // Here is a C program start point
{
   void far * memory;
   hardware_init();                     // User must write this function.
                                        // It is specific to user's hardware

   os_init();                           // Init all kernel's stuff

   application_init();                  // User must write this function.
                                        // It is specific to user's
                                        // application

   scheduler();                         // Let it go!!!!

   application_finish();                // Finish all application activity
                                        // and clear all allocated buffers

   os_finish();                         // Now this code has meaning for
                                        // PC_EMULATION only. If program
                                        // runs on the board, this code is
                                        // unreachable
}


CK.
頭像
chester
版面大總管
版面大總管
 
文章: 56
註冊時間: 週四 11月 14, 2002 9:42 pm
來自: taipei

re:compact OS kernel

文章mobile2 » 週六 11月 13, 2004 11:35 pm

請問一下, 你所列的這段程式是出自哪裡呢?? :shock:
mobile2
可愛的小學生
可愛的小學生
 
文章: 4
註冊時間: 週二 3月 23, 2004 5:24 pm

re:compact OS kernel

文章Linkey » 週六 11月 13, 2004 11:42 pm

上面不是有網址?
不過不是給個人電腦用的 8-)
Linkey
可愛的小學生
可愛的小學生
 
文章: 37
註冊時間: 週四 3月 25, 2004 9:31 pm

Re: re:compact OS kernel

文章mobile2 » 週日 11月 14, 2004 12:10 am

Linkey 寫:上面不是有網址?
不過不是給個人電腦用的 8-)


有阿, 是不是這個
http://www.EmbeddedStuff.com
但是連過去以後被自動轉向到
http://lb1.netster.com/Index.asp?Site=Z ... Zi5jb20%3D

覺得很奇怪, 所以才問一下... :-o

另外, 你說, "不是給個人電腦用的"..這是神麼意思阿?? :shock:
mobile2
可愛的小學生
可愛的小學生
 
文章: 4
註冊時間: 週二 3月 23, 2004 5:24 pm

re:compact OS kernel

文章d2207197 » 週日 11月 14, 2004 2:11 am

最開頭他有寫
代碼: 選擇全部
this kernel can run on almost any 8-bit MCU

不然您試試在您的個人電腦上使用此 kernel 試試看
頭像
d2207197
鑽研的研究生
鑽研的研究生
 
文章: 1763
註冊時間: 週二 5月 27, 2003 9:57 pm
來自: 火星

Re: re:compact OS kernel

文章Linkey » 週日 11月 14, 2004 2:26 am

d2207197 寫:最開頭他有寫
代碼: 選擇全部
this kernel can run on almost any 8-bit MCU

不然您試試在您的個人電腦上使用此 kernel 試試看

任天堂是8bit的嗎? :-P
Linkey
可愛的小學生
可愛的小學生
 
文章: 37
註冊時間: 週四 3月 25, 2004 9:31 pm

re:compact OS kernel

文章訪客 » 週日 11月 28, 2004 11:17 pm

看是任天堂那一個機種的, 8, 16, 32 bits 都有呀... :-D

- Dream
訪客
 

re:compact OS kernel

文章訪客 » 週日 11月 28, 2004 11:41 pm

CK,
1. 在建立一個 Task 時, 有呼叫到一個 void x(unsigned int * task_status, void * task_data), 您有這一段 code 嗎?

2. 此 compact OS kernel 對於記憶體資源管理的部分沒有看到, 雖然我們在開發小型的系統時, 不常用到, 但除錯時很好用耶... :-D

- Dream
訪客
 


回到 embedded system

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客

cron