1.新增状态机功能。

This commit is contained in:
MacRsh
2023-10-14 11:15:40 +08:00
parent 23f3610e20
commit fcfbc93a3b
4 changed files with 65 additions and 33 deletions

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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_ */