快速入門
EventOS Nano非常簡單,除原始碼外,只需要實作三個代碼,就可以使用EventOS Nano撰寫程式
- main.c main函式,初始化和啟動EventOS
- eos_port.c 如EventOS在特定平臺上的介面實作,就是EventOS Nano移植的相關代碼
- eos_led.c LED的閃爍狀態機,LED燈閃爍,類似于單片機界的hello world
如下對每一個檔案進行詳細說明:
1.main.c
EventOS初始化->訂閱表初始化->LED狀態機初始化->EventOS啟動
/* include ------------------------------------------------------------------ */
#include "eventos.h" // EventOS Nano頭檔案
#include "event_def.h" // 事件主題的列舉
#include "eos_led.h" // LED燈閃爍狀態機
/* define ------------------------------------------------------------------- */
static eos_u32_t eos_sub_table[Event_Max]; // 訂閱表資料空間
/* main function ------------------------------------------------------------ */
int main(void)
{
if (SysTick_Config(SystemCoreClock / 1000) != 0)
while (1);
eos_init(); // EventOS初始化
#if (EOS_USE_PUB_SUB != 0)
eos_sub_init(eos_sub_table, Event_Max); // 訂閱表初始化
#endif
#if (EOS_USE_SM_MODE != 0)
eos_sm_led_init(); // LED狀態機初始化
#endif
eos_reactor_led_init();
eos_run(); // EventOS啟動
return 0;
}
在QP和EventOS Nano中,事件主題的定義是使用列舉來定義的,但反觀很多事件驅動和訊息驅動的應用,如ROS和MQTT的實作,其事件(訊息)的定義,是使用字串的,二者各有利弊,列舉的好處是節省RAM和ROM,適合資源受限的場合,字串的好處是,使用方便,不產生耦合,利于實作分布式,
事件主題event_def.h的定義如下:
#include "eventos.h"
enum {
Event_Test = Event_User, // 事件主題的定義從Event_User開始,小于Event_User的是系統事件,
Event_Time_500ms,
Event_Time_1000ms,
Event_ActEnd,
Event_Max
};
2.eos_port.c
eos_port.c是硬體或平臺依賴檔案
#include "eventos.h"
// 進入臨界區,關閉全域中斷
void eos_port_critical_enter(void)
{
__disable_irq(); // 當IDE為MDK時,面向ARM Cortex-M系列,可以參考實作
}
// 退出臨界區,開啟全域中斷
void eos_port_critical_exit(void)
{
__enable_irq(); // 當IDE為MDK時,面向ARM Cortex-M系列,可以參考實作
}
// 斷言介面,EventOS Nano推崇防御式編程,內部運用了大量的斷言檢查程式運行的合法性
eos_u32_t eos_error_id = 0;
void eos_port_assert(eos_u32_t error_id)
{
// 斷言資訊的列印,
SEGGER_RTT_printf(0, "------------------------------------\n");
SEGGER_RTT_printf(0, "ASSERT >>> Module: EventOS Nano, ErrorId: %d.\n", error_id);
SEGGER_RTT_printf(0, "------------------------------------\n");
eos_error_id = error_id;
while (1)
{
/* User code */
}
}
// 空閑回呼函式:當EventOS Nano沒有任何事件需要處理的時候,會呼叫此函式
// 可以實作:硬體設備的輪訓、亂數的計算等,如果沒有,實作一個空函式即可
void eos_hook_idle(void)
{
}
// 啟動回呼函式
// 在EventOS Nano初始化完畢,且狀態機運行之前,會呼叫這個回呼函式,這里可以對硬體設備進行初始化、對功能模塊或者中間件進行初始化等,
void eos_hook_start(void)
{
// 硬體初始化
/* User code */
// 功能模塊初始化
/* User code */
}
// 停止回呼函式
// 在EventOS Nano進入斷言后,或者用戶呼叫eventos_stop函式將EventOS停止后,此回呼函式會被呼叫
// 這個函式主要用于有序關閉敏感設備(關閉電機運行),或者向外界提供資訊(打開報警器,顯示報警界面,或者列印報警資訊等),
void eos_hook_stop(void)
{
// 有序關閉敏感設備
motor_stop(Motor_Left);
motor_stop(Motor_Right);
// 顯示必要資訊
led_set_status(LedStatus_Stop);
}
3.eos_led.c和eos_led.h
eos_led.c中描述了狀態機是如何使用的
/* include ------------------------------------------------------------------ */
#include "eos_led.h" // 模塊頭檔案
#include "eventos.h" // EventOS頭檔案
#include "event_def.h" // 事件定義頭檔案
#include <stdio.h> // 標準輸入輸出庫
/* data structure ----------------------------------------------------------- */
typedef struct eos_led_tag { // LED類
eos_sm_t super;
eos_bool_t status;
} eos_led_t;
static eos_led_t led; // led物件,單例模式
/* static state function ---------------------------------------------------- */
// 初始狀態
static eos_ret_t state_init(eos_led_t * const me, eos_event_t const * const e);
// Led的ON狀態
static eos_ret_t state_on(eos_led_t * const me, eos_event_t const * const e);
// Led的Off狀態
static eos_ret_t state_off(eos_led_t * const me, eos_event_t const * const e);
/* api ---------------------------------------------------- */
void eos_led_init(void)
{
static eos_u32_t queue[32]; // 事件佇列
eos_sm_init(&led.super, 1, queue, 32); // 狀態機初始化
// 狀態機啟動,以state_init作為初始狀態,
eos_sm_start(&led.super, EOS_STATE_CAST(state_init));
led.status = 0;
}
/* static state function ---------------------------------------------------- */
static eos_ret_t state_init(eos_led_t * const me, eos_event_t const * const e)
{
// 訂閱事件Event_Time_500ms
EOS_EVENT_SUB(Event_Time_500ms);
// 使事件Event_Time_500ms,每隔500ms就被發送一次,
eos_event_pub_period(Event_Time_500ms, 500);
// EOS_TRAN是個回呼介面
return EOS_TRAN(state_off);
}
/*每500ms,訂閱的500ms事件會發布一次,切換on/off狀態,并進入對應函式的Event_Enter狀態執行*/
static eos_ret_t state_on(eos_led_t * const me, eos_event_t const * const e)
{
switch (e->topic) {
case Event_Enter: // 狀態state_on的進入事件
printf("State On!\n");
me->status = 1;
return EOS_Ret_Handled;
case Event_Time_500ms: // 收到Event_Time_500ms,跳轉到state_off
return EOS_TRAN(state_off);
default:
return EOS_SUPER(eos_state_top);
}
}
static eos_ret_t state_off(eos_led_t * const me, eos_event_t const * const e)
{
switch (e->topic) {
case Event_Enter: // 狀態state_off的進入事件
printf("State Off!\n");
me->status = 0;
return EOS_Ret_Handled;
case Event_Time_500ms: // 收到Event_Time_500ms,跳轉到state_on
return EOS_TRAN(state_on);
default:
return EOS_SUPER(eos_state_top);
}
}
倉庫地址:https://gitee.com/event-os/eventos.git
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/499582.html
標籤:嵌入式
