嵌入式--轮询调度模块

这篇博客详细介绍了如何在裸机环境中实现一个用于时间片调度的轮询模块。模块包括初始化、退出、任务处理等功能,并提供了消息传递机制。通过宏定义简化了代码,适配不同编译器,并且包含了示例代码展示如何注册和处理任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

嵌入式–轮询调度模块

参考别人设计,感谢大佬的付出。此模块用在裸机中作为时间片调用,代码层次清晰,并非所有编译器支持,谨慎使用。

头文件 module.h

#ifndef __MODULE_H
#define __MODULE_H

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/* define variable --------------------------------------------------------*/
#define  DEFINE_CONN(type, var, line)   type  var##line
#define  DEFINE_TYPE(type, prefix)      DEFINE_CONN(type, prefix, __LINE__)

#define DECLARE_TYPE(type, var)     type type##var
#define ABTAIN_TYPE(type, var)      type##var


#if defined(__CC_ARM) || defined(__GNUC__) /* ARM,GCC*/
    #define SECTION(x)                  __attribute__((section(x)))
    #define USED                        __attribute__((used))
#elif defined (__ICCARM__)              /*IAR */
    #define SECTION(x)                  @ x
    #define USED                        __root
#else
    #error "Current tool chain haven't supported yet!"
#endif

typedef struct{
    void (*init)(void);             //初始化接口
}InitItem_t;

typedef struct{
    void (*exit)(void);             //初始化接口
}ExitItem_t;

typedef struct{
    const char *name;               //模块名称    
    void (*handle)(void);           //初始化接口
    unsigned int interval;          //轮询间隔
    unsigned int *timer;            //指向定时器指针
}TaskItem_t;

#define Module_Init(func)           \
    USED DEFINE_TYPE(const InitItem_t, init_tbl_##func)\
    SECTION("init.item.1") = {func}
    
#define Module_Exit(func)           \
    USED DEFINE_TYPE(const ExitItem_t, exit_tbl_##func)\
    SECTION("exit.item.1") = {func}    

#define Timer_Register(name, handle, interval)                \
    static unsigned int __task_timer_##handle;              \
    USED DEFINE_TYPE(const TaskItem_t, task_item_##handle)  \
    SECTION("task.item.1") = {name,handle, interval, &__task_timer_##handle}
    
#define Task_Register(name, handle)                \
    USED DEFINE_TYPE(const TaskItem_t, task_item_##handle)  \
    SECTION("task.item.1") = {name,handle, 0, NULL}

// 数据报传送
typedef struct{
    const char* name;       // 标识
    void* msg;              // 内容
    int   size;             // 内容大小
    bool  flg;              // 数据更新标识
}Msg_Item_t;    

// 注意,每个标识在注册的时候,msg的大小已确定
#define MSG_Register(name, type, var)           \
    static DECLARE_TYPE(type, var);             \
    USED DECLARE_TYPE(Msg_Item_t, type##var)    \
    SECTION("msg.item.1") = {name, (void*)&ABTAIN_TYPE(type, var), sizeof(type), false}
    
void Task_IncTick(void);
    
unsigned int Task_GetTick(void);
    
void SysModule_Init(void);
    
void SysModule_Exit(void);  
    
void SysTask_Process(void);

bool Msg_Send(const char* name, void* msg);

bool Msg_Recv(char* name, void* msg, int size);

#ifdef __cplusplus
}
#endif    
    
#endif

源文件 module.c

#include <string.h>
#include <stdlib.h>

#include "module.h"


static volatile unsigned int s_Task_Tick = 0;

static void NullProcess(void){}

const USED InitItem_t init_tbl_start SECTION("init.item.0") = {
    NullProcess
};

const USED InitItem_t init_tbl_end SECTION("init.item.2") = {       
    NullProcess
};

const USED ExitItem_t exit_tbl_start SECTION("exit.item.0") = {
    NullProcess
};

const USED ExitItem_t exit_tbl_end SECTION("exit.item.2") = {       
    NullProcess
};

const USED TaskItem_t task_tbl_start SECTION("task.item.0") = {     
    "", NullProcess
};

const USED TaskItem_t task_tbl_end SECTION("task.item.2") = {       
    "", NullProcess
};

void Task_IncTick(void)
{
    ++s_Task_Tick;
}

unsigned int Task_GetTick(void)
{
    return s_Task_Tick;
}

void SysModule_Init(void)
{
    const InitItem_t *it = &init_tbl_start;
    while(it < &init_tbl_end)
    {
        if(!it->init)
        {
            break;
        }
        it++->init();
    }  
}

void SysModule_Exit(void)
{
    const ExitItem_t *it = &exit_tbl_start;
    while(it < &exit_tbl_end)
    {
        if(!it->exit)
        {
            break;
        }
        it++->exit();
    }  
}

void SysTask_Process(void)
{
    const TaskItem_t *t;
    for (t = &task_tbl_start + 1; t < &task_tbl_end; t++) 
    {
        if(!t->timer)
        {
            if(t->handle)
            {
                t->handle();
            }
            continue;
        }
        
        if((Task_GetTick() - *t->timer) >= t->interval) 
        {
            *t->timer = Task_GetTick();
            if(t->handle)
            {
                t->handle();
            }
        }
    }
}

Msg_Item_t msg_tbl_start  __attribute__((section("msg.item.0"))) = {
    "", (void*)0, 0
};

Msg_Item_t msg_tbl_end  __attribute__((section("msg.item.2"))) = {       
    "", (void*)0, 0
};

bool Msg_Send(const char* name, void* msg)
{
    Msg_Item_t *it = &msg_tbl_start;
    while(it < &msg_tbl_end)
    {
        if(strcmp(it->name, name) == 0)
        {
            memcpy(it->msg, msg, it->size);
            it->flg = true;
            return true;
        }
        
        it++;
    }
    
    return false;
}

bool Msg_Recv(char* name, void* msg, int size)
{
    if(!msg)
    {
        return false;
    }
    
    Msg_Item_t *it = &msg_tbl_start;
    while(it++ < &msg_tbl_end)
    {
        if(strcmp(it->name, name) == 0)
        {
            if(it->flg == false)
            {
                return false;
            }
            
            if(size < it->size)
            {
                return false;
            }
            
            memcpy(msg, it->msg, it->size);
            it->flg = false;
            return true;
        }
    }
    
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值