1.新增状态机功能。
This commit is contained in:
@@ -132,7 +132,7 @@ int main(void)
|
||||
|
||||
/* 启动普通事件 */
|
||||
mr_etask_start(&etask, EVENT_1, MR_ETASK_SFLAG_EVENT, 0, event1_cb, NULL);
|
||||
mr_etask_start(&etask, mr_etask_str_to_id(EVENT_2), MR_ETASK_SFLAG_EVENT, 0, event2_cb, NULL);
|
||||
mr_etask_start(&etask, mr_etask_str2id(EVENT_2), MR_ETASK_SFLAG_EVENT, 0, event2_cb, NULL);
|
||||
|
||||
/* 启动定时事件 */
|
||||
mr_etask_start(&etask, EVENT_3, MR_ETASK_SFLAG_TIMER | MR_ETASK_SFLAG_HARD, 5, event3_cb, NULL);
|
||||
@@ -140,7 +140,9 @@ int main(void)
|
||||
/* 延迟唤醒事件1 */
|
||||
mr_etask_wakeup(&etask, EVENT_1, MR_ETASK_WFLAG_DELAY);
|
||||
/* 立即唤醒事件2 */
|
||||
mr_etask_wakeup(&etask, mr_etask_str_to_id(EVENT_2), MR_ETASK_WFLAG_NOW);
|
||||
mr_etask_wakeup(&etask, mr_etask_str2id(EVENT_2), MR_ETASK_WFLAG_NOW);
|
||||
/* 状态唤醒事件2 */
|
||||
mr_etask_wakeup(&etask, mr_etask_str2id(EVENT_2), MR_ETASK_WFLAG_STATE);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Etask使用指南
|
||||
# etask使用指南
|
||||
|
||||
事件任务框架是是一种用于处理异步事件和任务的编程模型。它提供了一种结构化的方式来管理和调度事件和任务,以便在单线程、多线程或多任务环境中实现高效的并发处理。
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
## 准备
|
||||
|
||||
1. 在 `mrconfig.h` 中 `Module config` 下添加宏开关启用Etask组件。
|
||||
1. 在 `mrconfig.h` 中 `Module config` 下添加宏开关启用etask组件。
|
||||
|
||||
```c
|
||||
//<------------------------------------ Module config ------------------------------------>
|
||||
@@ -101,6 +101,8 @@ void mr_etask_handle(mr_etask_t etask);
|
||||
|
||||
按事件发生顺序处理(FIFO),仅会处理进入处理函数前已发生的事件,防止单一事件循环触发阻塞系统。
|
||||
|
||||
状态事件将在每次事件任务处理结束后运行。
|
||||
|
||||
----------
|
||||
|
||||
## 启动事件
|
||||
@@ -175,13 +177,16 @@ mr_err_t mr_etask_wakeup(mr_etask_t etask, mr_uint32_t id, mr_uint8_t wflag);
|
||||
| MR_ERR_OK | 通知成功 |
|
||||
| 错误码 | 通知失败 |
|
||||
|
||||
- wflag:事件唤醒标志可分为立即唤醒和延迟唤醒,立即唤醒将在调用处直接处理,延迟唤醒则将事件加入事件队列中等待处理。
|
||||
- wflag:事件唤醒标志可分为立即唤醒、延迟唤醒和状态唤醒,立即唤醒将在调用处直接处理,延迟唤醒将事件加入事件队列中等待处理,状态唤醒将事件转换为etask状态事件。
|
||||
|
||||
```c
|
||||
MR_ETASK_WFLAG_NOW /* 立即唤醒 */
|
||||
MR_ETASK_WFLAG_DELAY /* 延迟唤醒 */
|
||||
MR_ETASK_WFLAG_STATE /* 状态唤醒 */
|
||||
```
|
||||
|
||||
状态事件将在每次事件任务处理结束后运行(有且仅有一个状态事件,默认无状态事件)。
|
||||
|
||||
当唤醒事件发生失败(错误码 -5)时,请增加缓冲队列大小或提高事件处理频率(缓冲队列已满,无法及时响应事件,导致事件丢失)。
|
||||
|
||||
----------
|
||||
@@ -189,7 +194,7 @@ MR_ETASK_WFLAG_DELAY /* 延迟唤
|
||||
## 字符串转事件ID
|
||||
|
||||
```c
|
||||
mr_uint32_t mr_etask_str_to_id(const char *string);
|
||||
mr_uint32_t mr_etask_str2id(const char *string);
|
||||
```
|
||||
|
||||
| 参数 | 描述 |
|
||||
@@ -239,7 +244,7 @@ int main(void)
|
||||
|
||||
/* 启动普通事件 */
|
||||
mr_etask_start(&etask, EVENT_1, MR_ETASK_SFLAG_EVENT, 0, event1_cb, NULL);
|
||||
mr_etask_start(&etask, mr_etask_str_to_id(EVENT_2), MR_ETASK_SFLAG_EVENT, 0, event2_cb, NULL);
|
||||
mr_etask_start(&etask, mr_etask_str2id(EVENT_2), MR_ETASK_SFLAG_EVENT, 0, event2_cb, NULL);
|
||||
|
||||
/* 启动定时事件 */
|
||||
mr_etask_start(&etask, EVENT_3, MR_ETASK_SFLAG_TIMER | MR_ETASK_SFLAG_HARD, 5, event3_cb, NULL);
|
||||
@@ -247,7 +252,9 @@ int main(void)
|
||||
/* 延迟唤醒事件1 */
|
||||
mr_etask_wakeup(&etask, EVENT_1, MR_ETASK_WFLAG_DELAY);
|
||||
/* 立即唤醒事件2 */
|
||||
mr_etask_wakeup(&etask, mr_etask_str_to_id(EVENT_2), MR_ETASK_WFLAG_NOW);
|
||||
mr_etask_wakeup(&etask, mr_etask_str2id(EVENT_2), MR_ETASK_WFLAG_NOW);
|
||||
/* 状态唤醒事件2 */
|
||||
mr_etask_wakeup(&etask, mr_etask_str2id(EVENT_2), MR_ETASK_WFLAG_STATE);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -94,17 +94,17 @@ void mr_etask_timing(mr_etask_t etask, mr_event_t event, mr_uint32_t time)
|
||||
mr_interrupt_enable();
|
||||
}
|
||||
|
||||
static void mr_etask_free_task(mr_avl_t tree)
|
||||
static void mr_etask_free_event(mr_avl_t tree)
|
||||
{
|
||||
if (tree->left_child != MR_NULL)
|
||||
{
|
||||
mr_etask_free_task(tree->left_child);
|
||||
mr_etask_free_event(tree->left_child);
|
||||
tree->left_child = MR_NULL;
|
||||
}
|
||||
|
||||
if(tree->right_child != MR_NULL)
|
||||
if (tree->right_child != MR_NULL)
|
||||
{
|
||||
mr_etask_free_task(tree->right_child);
|
||||
mr_etask_free_event(tree->right_child);
|
||||
tree->right_child = MR_NULL;
|
||||
}
|
||||
|
||||
@@ -151,8 +151,8 @@ mr_err_t mr_etask_add(mr_etask_t etask, const char *name, mr_size_t size)
|
||||
pool = mr_malloc(size * sizeof(mr_uint32_t));
|
||||
if (pool == MR_NULL)
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] add failed: [%d]\r\n", name, -MR_ERR_NO_MEMORY);
|
||||
return -MR_ERR_NO_MEMORY;
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] add failed: [%d]\r\n", name, MR_ERR_NO_MEMORY);
|
||||
return MR_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialize the private fields */
|
||||
@@ -160,6 +160,7 @@ mr_err_t mr_etask_add(mr_etask_t etask, const char *name, mr_size_t size)
|
||||
mr_rb_init(&etask->queue, pool, size * sizeof(mr_uint32_t));
|
||||
etask->list = MR_NULL;
|
||||
mr_list_init(&etask->tlist);
|
||||
etask->state = MR_NULL;
|
||||
|
||||
/* Add the object to the container */
|
||||
ret = mr_object_add(&etask->object, name, Mr_Object_Type_Module);
|
||||
@@ -197,9 +198,10 @@ mr_err_t mr_etask_remove(mr_etask_t etask)
|
||||
/* Free the queue */
|
||||
mr_free(etask->queue.buffer);
|
||||
mr_rb_init(&etask->queue, MR_NULL, 0);
|
||||
mr_etask_free_task(etask->list);
|
||||
mr_etask_free_event(etask->list);
|
||||
etask->list = MR_NULL;
|
||||
mr_list_init(&etask->tlist);
|
||||
etask->state = MR_NULL;
|
||||
|
||||
return MR_ERR_OK;
|
||||
}
|
||||
@@ -273,13 +275,21 @@ void mr_etask_handle(mr_etask_t etask)
|
||||
mr_event_t event = (mr_event_t)mr_avl_find(etask->list, id);
|
||||
if (event == MR_NULL)
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] handle [%d] failed: [%d]\r\n", etask->object.name, id, -MR_ERR_NOT_FOUND);
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] handle [%u] failed: [%d]\r\n", etask->object.name, id, MR_ERR_NOT_FOUND);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Call the event callback */
|
||||
event->cb(etask, event->args);
|
||||
}
|
||||
|
||||
if (etask->state != MR_NULL)
|
||||
{
|
||||
mr_event_t event = (mr_event_t)etask->state;
|
||||
|
||||
/* Call the state callback */
|
||||
event->cb(etask, event->args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,22 +315,22 @@ mr_err_t mr_etask_start(mr_etask_t etask,
|
||||
|
||||
MR_ASSERT(etask != MR_NULL);
|
||||
MR_ASSERT(etask->object.type == Mr_Object_Type_Module);
|
||||
MR_ASSERT(((sflags & MR_ETASK_SFLAG_TIMER) == 0) || time != 0);
|
||||
MR_ASSERT(((sflags & MR_ETASK_SFLAG_TIMER) != MR_ETASK_SFLAG_TIMER) || time != 0);
|
||||
MR_ASSERT(cb != MR_NULL);
|
||||
|
||||
/* Check if the event already exists */
|
||||
if (mr_avl_find(etask->list, id) != MR_NULL)
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] start [%d] failed: [%d]\r\n", etask->object.name, id, -MR_ERR_BUSY);
|
||||
return -MR_ERR_BUSY;
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] start [%u] failed: [%d]\r\n", etask->object.name, id, MR_ERR_BUSY);
|
||||
return MR_ERR_BUSY;
|
||||
}
|
||||
|
||||
/* Allocate the event */
|
||||
event = (mr_event_t)mr_malloc(sizeof(struct mr_event));
|
||||
if (event == MR_NULL)
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] start [%d] failed: [%d]\r\n", etask->object.name, id, -MR_ERR_BUSY);
|
||||
return -MR_ERR_NO_MEMORY;
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] start [%u] failed: [%d]\r\n", etask->object.name, id, MR_ERR_BUSY);
|
||||
return MR_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialize the private fields */
|
||||
@@ -364,8 +374,8 @@ mr_err_t mr_etask_stop(mr_etask_t etask, mr_uint32_t id)
|
||||
event = (mr_event_t)mr_avl_find(etask->list, id);
|
||||
if (event == MR_NULL)
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] stop [%d] failed: [%d]\r\n", etask->object.name, id, -MR_ERR_NOT_FOUND);
|
||||
return -MR_ERR_NOT_FOUND;
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] stop [%u] failed: [%d]\r\n", etask->object.name, id, MR_ERR_NOT_FOUND);
|
||||
return MR_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Disable interrupt */
|
||||
@@ -400,14 +410,14 @@ mr_err_t mr_etask_wakeup(mr_etask_t etask, mr_uint32_t id, mr_uint8_t wflag)
|
||||
{
|
||||
MR_ASSERT(etask != MR_NULL);
|
||||
MR_ASSERT(etask->object.type == Mr_Object_Type_Module);
|
||||
MR_ASSERT(wflag == MR_ETASK_WFLAG_NOW || wflag == MR_ETASK_WFLAG_DELAY);
|
||||
MR_ASSERT(wflag == MR_ETASK_WFLAG_DELAY || wflag == MR_ETASK_WFLAG_NOW || wflag == MR_ETASK_WFLAG_STATE);
|
||||
|
||||
if (wflag == MR_ETASK_WFLAG_DELAY)
|
||||
{
|
||||
if (mr_rb_write(&etask->queue, &id, sizeof(id)) != sizeof(id))
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] wakeup [%d] failed: [%d]\r\n", etask->object.name, id, -MR_ERR_BUSY);
|
||||
return -MR_ERR_BUSY;
|
||||
MR_DEBUG_D(DEBUG_TAG, "[%s] wakeup [%u] failed: [%d]\r\n", etask->object.name, id, MR_ERR_BUSY);
|
||||
return MR_ERR_BUSY;
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -415,15 +425,22 @@ mr_err_t mr_etask_wakeup(mr_etask_t etask, mr_uint32_t id, mr_uint8_t wflag)
|
||||
if (event == MR_NULL)
|
||||
{
|
||||
MR_DEBUG_D(DEBUG_TAG,
|
||||
"[%s] wakeup [%d] failed: [%d]\r\n",
|
||||
"[%s] wakeup [%u] failed: [%d]\r\n",
|
||||
etask->object.name,
|
||||
id,
|
||||
-MR_ERR_NOT_FOUND);
|
||||
return -MR_ERR_NOT_FOUND;
|
||||
MR_ERR_NOT_FOUND);
|
||||
return MR_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Call the event callback */
|
||||
event->cb(etask, event->args);
|
||||
if (wflag == MR_ETASK_WFLAG_NOW)
|
||||
{
|
||||
/* Call the event callback */
|
||||
event->cb(etask, event->args);
|
||||
} else
|
||||
{
|
||||
/* Set the state machine */
|
||||
etask->state = (void *)event;
|
||||
}
|
||||
}
|
||||
|
||||
return MR_ERR_OK;
|
||||
@@ -436,7 +453,7 @@ mr_err_t mr_etask_wakeup(mr_etask_t etask, mr_uint32_t id, mr_uint8_t wflag)
|
||||
*
|
||||
* @return The id of the string.
|
||||
*/
|
||||
mr_uint32_t mr_etask_str_to_id(const char *string)
|
||||
mr_uint32_t mr_etask_str2id(const char *string)
|
||||
{
|
||||
mr_uint32_t id = 2166136261u;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ extern "C" {
|
||||
*/
|
||||
#define MR_ETASK_WFLAG_NOW 0x00 /* Wakeup immediately */
|
||||
#define MR_ETASK_WFLAG_DELAY 0x01 /* Wakeup after delay */
|
||||
#define MR_ETASK_WFLAG_STATE 0x02 /* Wakeup by state */
|
||||
|
||||
/**
|
||||
* @def Etask start flag
|
||||
@@ -44,6 +45,7 @@ struct mr_etask
|
||||
struct mr_rb queue; /* Queue */
|
||||
mr_avl_t list; /* Event list */
|
||||
struct mr_list tlist; /* Timing list */
|
||||
void *state; /* State */
|
||||
};
|
||||
typedef struct mr_etask *mr_etask_t; /* Type for etask */
|
||||
|
||||
@@ -64,9 +66,13 @@ mr_err_t mr_etask_start(mr_etask_t etask,
|
||||
void *args);
|
||||
mr_err_t mr_etask_stop(mr_etask_t etask, mr_uint32_t id);
|
||||
mr_err_t mr_etask_wakeup(mr_etask_t etask, mr_uint32_t id, mr_uint8_t wflag);
|
||||
mr_uint32_t mr_etask_str_to_id(const char *string);
|
||||
mr_uint32_t mr_etask_str2id(const char *string);
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ETASK_H_ */
|
||||
Reference in New Issue
Block a user