嵌入式开发--300行代码实现操作系统cola_os

一、前言

        刚开始学习写代码时代码都会放在主循环中,通过while(1)不停的轮训。如果想做一个时间触发的任务,比如做一个100ms闪烁一次的LED,通常的写法是创建一个1ms定时器,在定时中断中变量自加,当变量加到100ms标志置位,然后在主循环中切换LED状态,本次实现的OS原理就是基于该原理实现的,准确的说这只是一个多任务链表的轮询。在很多MCU开发中,功能很简单,实时性要求不强,如果使用RTOS显得太浪费,任务多了管理不当又很乱,所以才会想起做一个轮询的任务管理。为体现出高大上,所以命名为cola_os。(如有问题,欢迎指正)

二、例程

目的:创建两个定时任务,500msLED切换一次状态,每1s串口打印一次数据;

任务创建代码

#include "cola_os.h"
#include "app.h"
#include 
#include "bsp.h"
#include "led.h"
#include "config.h"

task_t timer_500ms,timer_1s;


//led每500ms状态改变一次
static void timer_500ms_cb(uint32_t event)
{
    led_toggle();
}
//led每500ms状态改变一次
static void timer_1s_cb(uint32_t event)
{
    os_log("timer 1s......\r\n");
}


void app_init(void)
{
    cola_timer_create(&timer_500ms,timer_500ms_cb);
    cola_timer_start(&timer_500ms,TIMER_ALWAYS,500);
    cola_timer_create(&timer_1s,timer_1s_cb);
    cola_timer_start(&timer_1s,TIMER_ALWAYS,1000);
}

运行结果:

嵌入式开发--300行代码实现操作系统cola_os_第1张图片是不是很容易就实现了。

三、源代码解析(代码注释写的很详细了)

1.头文件

#ifndef _COLA_OS_H_
#define _COLA_OS_H_


#include 
#include 



//任务事件
enum EVENT_SIG
{
    SIG_ALARM = 1 << 0,
    SIG_DATA  = 1 << 1,
    SIG_NOTE  = 1 << 2,
    SIG_UART  = 1 << 3,
    SIG_RADIO = 1 << 4,
    SIG_GPRS  = 1 << 5,
    SIG_USR1  = 1 << 8,
    SIG_USR2  = 1 << 9,
    SYS_EVENT_MSG  = 1 << 15,
};


enum
{
    TIMER_ALWAYS     = 0x00,
    TIMER_ONE_SHOT   = 0x01,
};


typedef void (*cbFunc)(uint32_t event);

typedef struct task_s
{
    uint8_t     timerNum;    //定时编号
    uint32_t    period;      //定时周期
    bool        oneShot;     //true只执行一次
    bool        start;       //开始启动
    uint32_t    timerTick;   //定时计数
    bool        run;         //任务运行标志 
    bool        taskFlag;    //任务标志是主任务还是定时任务
    uint32_t    event;       //驱动事件  
    cbFunc      func;        //回调函数
    struct task_s *next;
}task_t;

/*
    主循环任务创建
*/
int cola_task_create(task_t *task,cbFunc func);
/*
    主循环任务删除
*/
int cola_task_delete(task_t *task);
/*
    任务遍历,放到while(1)循环中
*/
void cola_task_loop(void);
/*
    定时任务创建
*/
int cola_timer_create(task_t *timer,cbFunc func);
/*
    启动定时任务
    one_shot:TIMER_ALWAYS   循环定时
              TIMER_ONE_SHOT 只运行一次
    time_ms :定时时间
*/
int cola_timer_start(task_t *timer,bool one_shot,uint32_t time_ms);
/*
    停止定时任务
*/
int cola_timer_stop(task_t *timer);

/*
    定时任务遍历,放到1ms ticker中
*/
void cola_timer_ticker(void);
/*
    设置任务事件
*/
int  cola_set_event(task_t *task,uint32_t sig_id);
/*
    取消任务事件
*/
int  cola_clear_event(task_t *task,uint32_t sig_id);

#endif 

2.C文件

#include "cola_os.h"
#include 
#include "bsp.h"
enum
{
    TASK_TASK   = 0x00,
    TASK_TIMER  = 0x01,
};

static struct task_s *task_list = NULL;
static volatile  uint8_t task_num = 0;

/*
    查找任务是否存在
*/
static bool cola_task_is_exists( task_t *task )
{
    task_t* cur = task_list;
    while( cur != NULL )
    {
        if( cur->timerNum == task->timerNum )
        {
            return true;
        }
        cur = cur->next;
    }
    return false;
}

/*
    创建任务
*/
int cola_task_create(task_t *task,cbFunc func)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    enter_critical();
    if((NULL == task )||(cola_task_is_exists(task)))
    {
        exit_critical();
        return false;
    }
    task->taskFlag  = TASK_TASK;
    task->start     = true;
    task->run       = true; 
    task->func      = func;
    task->event     = 0;
    if(NULL == task_list)
    {
        task_num++;
        task->timerNum = task_num;
        task_list = task;
        task_list->next = NULL;
    }
    else
    {
        while((cur->next != NULL))
        {
            cur = cur->next;
        }
        task_num++;
        task->timerNum = task_num;
        cur->next = task;
        task->next = NULL;
    }
    exit_critical();
    return true;
}

/*
  删除指定任务
*/
int cola_task_delete(task_t *task)
{
    task_t *cur  = task_list;
    task_t *tmp  = NULL;
    OS_CPU_SR cpu_sr;
    enter_critical();
    while( cur != NULL )
    {
        if( cur->timerNum == task->timerNum )
        {
            tmp = cur->next;
            cur->next = tmp->next;
            exit_critical();
            return true;
        }
        cur = cur->next;
    }
    exit_critical();
    return false;
}
/*
  循环遍历任务链表
*/
void cola_task_loop(void)
{
    uint32_t events;
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    
    while( cur != NULL )
    {
        if(cur->run)
        {
            if(NULL !=cur->func)
            {
                events = cur->event;
                if(events)
                {
                    enter_critical();
                    cur->event = 0;
                    exit_critical();
                }
                cur->func(events);                
            }
            if(TASK_TIMER == cur->taskFlag)
            {
                enter_critical();
                cur->run = false;
                exit_critical();
            }
            if((cur->oneShot)&&(TASK_TIMER == cur->taskFlag))
            {
               cur->start = false; 
            }
        }
        cur = cur->next;
    }
}

/*
  定时器创建
*/
int cola_timer_create(task_t *timer,cbFunc func)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    enter_critical();
    
    if((NULL == timer )||(cola_task_is_exists(timer)))
    {
        exit_critical();
        return false;
    }
    timer->taskFlag  = TASK_TIMER;
    timer->run       = false;
    timer->period    = 0;
    timer->oneShot   = true;
    timer->start     = false;
    timer->timerTick = 0;
    timer->func      = func;
    timer->event     = 0;
    if(NULL == task_list)
    {
        task_num++;
        timer->timerNum = task_num;
        task_list = timer;
        task_list->next = NULL;
    }
    else
    {
        while(cur->next != NULL)
        {
            cur = cur->next;
        }
        task_num++;
        timer->timerNum = task_num;
        cur->next = timer;
        timer->next = NULL;
    }
    exit_critical();
    return true;
    
}

/*
  定时器启动
*/
int cola_timer_start(task_t *timer,bool one_shot,uint32_t time_ms)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    enter_critical();
    while( cur != NULL )
    {
        if( cur->timerNum == timer->timerNum )
        {
            timer->period    = time_ms;
            timer->oneShot   = one_shot;
            timer->start     = true;
            timer->timerTick = 0;
            timer->taskFlag  = TASK_TIMER;
            exit_critical();
            return true;
        }
        cur = cur->next;
    }
    exit_critical();
    return false;
}
/*
  定时器停止
*/
int cola_timer_stop(task_t *timer)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    enter_critical();
    while( cur != NULL )
    {
        if( cur->timerNum == timer->timerNum )
        {
            timer->start     = false;
            exit_critical();
            return true;
        }
        cur = cur->next;
    }
    exit_critical();
    return false;
}
/*
  定时信息轮训
*/
void cola_timer_ticker(void)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    while( cur != NULL )
    {
        if((TASK_TIMER == cur->taskFlag)&& cur->start)
        {
            if(++cur->timerTick >= cur->period)
            {
                cur->timerTick = 0;
                if(cur->func != NULL)
                {
                    enter_critical();                   
                    cur->run = true;
                    exit_critical();
                }
            }
        }
        cur = cur->next;
    }
}

/*
  设置事件
*/
int cola_set_event(task_t *task,uint32_t sig_id)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    enter_critical();
    while( cur != NULL )
    {
        if( cur->timerNum == task->timerNum )
        {
            cur->event |= sig_id;
            exit_critical();
            return true;
        }
        cur = cur->next;
    }
    exit_critical();
    return false;
}
/*
  清除事件
*/
int  cola_clear_event(task_t *task,uint32_t sig_id)
{
    task_t *cur  = task_list;
    OS_CPU_SR cpu_sr;
    enter_critical();
    while( cur != NULL )
    {
        if( cur->timerNum == task->timerNum )
        {
            cur->event &= ~(sig_id);
            exit_critical();
            return true;
        }
        cur = cur->next;
    }
    exit_critical();
    return false;
}

四、国际惯例-代码下载

CSDN:https://download.csdn.net/download/ziqi5543/11812514

gitlab:https://gitee.com/schuck/cola_os

你可能感兴趣的:(OS)