首页 > 其他 > 详细

基于事件的单片机程序?

时间:2020-03-01 22:55:46      阅读:76      评论:0      收藏:0      [点我收藏+]

基于事件的单片机程序框架?不知道这个算不算事件驱动,工作中基本是写的裸机程序多,主要用STM32单片机,这样搞能方便程序设计,在MDK中测试OK,母鸡有没啥菜鸡如本人不自知的问题。
程序从大佬程序参考修改得来。
https://github.com/jiejieTop/cmd-parser

代码

  • 数据结构

typedef struct _event {
    char event_flag : 1;                //事件产生的标志位
    event_type_t   event_type;          //事件类型
    const char     *event_name;         //事件名字
    event_handler  handler;             //事件处理函数
} event_t;

方法

  • 初始化事件机制?
/**
  * @brief:         initilize event 
  * @param[in]:     None
  * @retval[out]:   None
  * @author:        guangjieSuper
  * @github:        https://github.com/guangjieSuper
*/
void event_init(void)
{
#if defined(__CC_ARM) || defined(__CLANG_ARM)          /* ARM C Compiler */
    extern const int EVENT_LIST$$Base;
    extern const int EVENT_LIST$$Limit;
    _event_list_begin = (event_t *)&EVENT_LIST$$Base;
    _event_list_end   = (event_t *)&EVENT_LIST$$Limit;
#elif defined (__ICCARM__) || defined(__ICCRX__)      /* for IAR Compiler */
    _cmd_init(__section_begin("EVENT_LIST"), __section_end("EVENT_LIST"));
#endif
}
  • main函数主循环调用
/**
  * @brief:         Event handler
  * @param[in]:     None
  * @retval[out]:   None
  * @author:        guangjieSuper
  * @github:        https://github.com/guangjieSuper
*/
void event_handle_loop(void)
{
    event_t *index;
    for(index = _event_list_begin; index < _event_list_end; index++)
    {
        if(index->event_type == CONTINUOUS_EVENT)
        {
            index->handler();
        }
        else
        {
            if(index->event_flag == EVENT_ON)
            {
                index->handler();
                index->event_flag = EVENT_OFF;
            }    
        }
    }    
}
  • 注册事件

注册事件使用这一个宏函数注册

#define EVENT_EXPORT(event_name,event_type, handler)                              EVENT_USED event_t _##event_name EVENT_SECTION("EVENT_LIST")=                 {                                                                                 EVENT_OFF,                                                                    event_type,                                                                   #event_name,                                                                  (event_handler)&handler                                                   };
  • 发布事件
/**
  * @brief:         post event
  * @param[in]:     event_name event's name
  * @retval[out]:   None
  * @author:        guangjieSuper
  * @github:        https://github.com/guangjieSuper
*/
void post_event(char *event_name)
{
    event_t *index;
    for(index = _event_list_begin; index < _event_list_end; index++)
    {
        if(strncmp(event_name,index->event_name,strlen(index->event_name)) == 0)
        {
            if(index->event_type == ONCE_EVENT)
                index->event_flag = EVENT_ON;
        }
    }
}

使用

#include "event.h"

void event1(void)
{
    printf("1000ms >> RT-Thread\r\n");
}
EVENT_EXPORT(event1,ONCE_EVENT,event1);

void event2(void)
{
    printf("2000ms >> uCos\r\n");
}
EVENT_EXPORT(event2,ONCE_EVENT,event2);

void event3(void)
{
    printf("500ms >> Linux\r\n");
}
EVENT_EXPORT(event3,ONCE_EVENT,event3);

在需要发布事件的地方调用post_event("eventX");(x=1 or 2 or 3)就可以执行event1函数

main函数调用

    while(1)
    {
        software_timer_loop();
        event_handle_loop();
    }

这样做后暂时感觉主函数都不用修改了。

  • 要到主函数中调用执行的函数只要用EVENT_EXPORT(event_name,event_type, handler)
    注册,将event_type设置为一直运行的类型CONTINUOUS_EVENT
  • 对于另一类要定时运行的事件,event_type设置为ONCE_EVENT,使用定时器定时,定时时间到时post_event一下就行了。

如本菜鸡在软件定时器的回调函数中post_event

void timer1_cb(void *parm)
{
    post_event("event1");
}

void timer2_cb(void *parm)
{
    post_event("event2");
}

void timer3_cb(void *parm)
{
    post_event("event3");
} 

基于事件的单片机程序?

原文:https://www.cnblogs.com/AresGuangjie/p/12392709.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!