Просмотр исходного кода

修复延时消息及定时消息的一些bug,更新readme文档,更新版本号为v2.1.0

slyant 5 лет назад
Родитель
Сommit
fb6ebbba6e
6 измененных файлов с 356 добавлено и 135 удалено
  1. 51 17
      README.md
  2. 69 39
      examples/task_msg_bus_sample.c
  3. 9 8
      examples/task_msg_bus_user_def.h
  4. 7 6
      inc/task_msg_bus.h
  5. 17 16
      inc/task_msg_bus_def.h
  6. 203 49
      src/task_msg_bus.c

+ 51 - 17
README.md

@@ -28,6 +28,8 @@ RT-Thread online packages
     system packages --->
         [*]TaskMsgBus: For sending and receiving json/text/object messages between threads based on RT-Thread
         TaskMsgBus --->
+            task message thread stack size [256]
+            task message thread priority [5]
             [*]task msg name define in user file 'task_msg_user_def.h'
             [*]task msg format using json
             [*]task msg object using dynamic memory
@@ -45,10 +47,16 @@ RT-Thread online packages
 | API        | 功能                     |
 | -------------- | ------------------------ |
 | rt_err_t task_msg_bus_init(rt_uint32_t stack_size, rt_uint8_t  priority, rt_uint32_t tick); | 初始化消息总线 |
-| rt_err_t task_msg_subscribe(enum task_msg_name msg_name, void(*callback)(task_msg_args_t msg_args));                                    | 订阅消息 |
+| rt_err_t task_msg_subscribe(enum task_msg_name msg_name, void(*callback)(task_msg_args_t msg_args)); | 订阅消息 |
 | rt_err_t task_msg_unsubscribe(enum task_msg_name msg_name, void(*callback)(task_msg_args_t msg_args)); | 取消订阅消息 |
 | rt_err_t task_msg_publish(enum task_msg_name msg_name, const char *msg_text);  | 发布text/json消息 |
 | rt_err_t task_msg_publish_obj(enum task_msg_name msg_name, void *msg_obj, rt_size_t msg_size); | 发布任意数据类型消息 |
+| rt_err_t task_msg_delay_publish(rt_uint32_t delay_ms, enum task_msg_name msg_name, const char *msg_text); | 延时发布text/json消息 |
+| rt_err_t task_msg_delay_publish_obj(rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj, rt_size_t msg_size); | 延时发布任意数据类型消息 |
+| task_msg_loop_t task_msg_loop_create(void); | 创建定时循环消息对象,返回定时循环消息对象句柄 |
+| rt_err_t task_msg_loop_delete(task_msg_loop_t msg_loop); | 停止并删除定时循环消息对象 |
+| rt_err_t task_msg_loop_start(task_msg_loop_t msg_loop, rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj, rt_size_t msg_size); | 启动定时循环消息发布 |
+| rt_err_t task_msg_loop_stop(task_msg_loop_t msg_loop); | 停止定时循环消息发布 |
 | int task_msg_subscriber_create(enum task_msg_name msg_name); | 创建一个消息订阅者,返回订阅者ID |
 | int task_msg_subscriber_create2(const enum task_msg_name *msg_name_list, rt_uint8_t msg_name_list_len); | 创建一个可以订阅多个主题的消息订阅者,返回订阅者ID |
 | rt_err_t task_msg_wait_until(int subscriber_id, rt_int32_t timeout_ms, struct task_msg_args **out_args); | 阻塞等待指定订阅者的消息 |
@@ -93,27 +101,52 @@ struct msg_3_def
 ```
 
 
-如果要在结构体的指针类型的字段中动态分配内存,需要在前面的包管理器中启用[task msg object using dynamic memory],同时,需要定义释放该消息涉及动态分配内存的钩子函数,例如:
+如果要在结构体的指针类型的字段中动态分配内存,需要在前面的包管理器中启用[task msg object using dynamic memory],同时,需要定义复制和释放该消息的钩子函数,例如:
 
 ```
-extern void msg_3_release_hook(void *args);
-#define task_msg_release_hooks {\
-        {TASK_MSG_OS_REDAY, RT_NULL},   \
-        {TASK_MSG_NET_REDAY, RT_NULL},  \
-        {TASK_MSG_1, RT_NULL},          \
-        {TASK_MSG_2, RT_NULL},          \
-        {TASK_MSG_3, msg_3_release_hook},          \
-        {TASK_MSG_4, RT_NULL},          \
-        {TASK_MSG_5, RT_NULL},          \
-    }
+    extern void *msg_3_dump_hook(void *args);
+    extern void msg_3_release_hook(void *args);
+    #define task_msg_dump_release_hooks {\
+            {TASK_MSG_OS_REDAY,     RT_NULL, RT_NULL},          \
+            {TASK_MSG_NET_REDAY,    RT_NULL, RT_NULL},          \
+            {TASK_MSG_1,            RT_NULL, RT_NULL},          \
+            {TASK_MSG_2,            RT_NULL, RT_NULL},          \
+            {TASK_MSG_3,            msg_3_dump_hook, msg_3_release_hook},   \
+            {TASK_MSG_4,            RT_NULL, RT_NULL},          \
+            {TASK_MSG_5,            RT_NULL, RT_NULL},          \
+        }
 ```
 
 在用户的 *.c 文件中实现此钩子函数,例如:
 ```
+void *msg_3_dump_hook(void *args)
+{
+    struct msg_3_def *msg_3 = (struct msg_3_def *) args;
+    struct msg_3_def *r_msg_3 = rt_calloc(1, sizeof(struct msg_3_def));
+    if (r_msg_3 == RT_NULL)
+    {
+        return RT_NULL;
+    }
+
+    rt_memcpy((rt_uint8_t *) r_msg_3, (rt_uint8_t *) msg_3, sizeof(struct msg_3_def));
+    if (msg_3->buffer && msg_3->buffer_size > 0)
+    {
+        r_msg_3->buffer = rt_calloc(1, msg_3->buffer_size);
+        if (r_msg_3->buffer == RT_NULL)
+        {
+            rt_free(r_msg_3);
+            return RT_NULL;
+        }
+        rt_memcpy(r_msg_3->buffer, msg_3->buffer, msg_3->buffer_size);
+        r_msg_3->buffer_size = msg_3->buffer_size;
+    }
+
+    return r_msg_3;
+}
 void msg_3_release_hook(void *args)
 {
-    struct msg_3_def *msg_3 = (struct msg_3_def *)args;
-    if(msg_3->buffer)
+    struct msg_3_def *msg_3 = (struct msg_3_def *) args;
+    if (msg_3->buffer)
         rt_free(msg_3->buffer);
 }
 ```
@@ -122,7 +155,7 @@ void msg_3_release_hook(void *args)
 * 初始化
 
 ```
-task_msg_bus_init(512, 11, 10); //初始化消息总线(线程栈大小, 优先级, 时间片)
+task_msg_bus_init(); //初始化消息总线,已经导入到组件自动初始化函数INIT_COMPONENT_EXPORT(task_msg_bus_init)
 ```
 
 调用此函数将动态创建1个消息总线的消息分发线程
@@ -184,6 +217,7 @@ msg_3.buffer = rt_calloc(1, 32);
 rt_memcpy(msg_3.buffer, buffer_test, 32);
 msg_3.buffer_size = 32;
 task_msg_publish_obj(TASK_MSG_3, &msg_3, sizeof(struct msg_3_def));
+rt_free(msg_3.buffer);
 ```
 
 * 以线程阻塞的方式接收消息
@@ -278,7 +312,7 @@ static void msg_wait_any_thread_entry(void *params)
         {
             //可以做其它操作,在此期间发布的消息不会丢失
         }
-    }    
+    }
 }
 
 rt_thread_t t_wait_any = rt_thread_create("msg_wa", msg_wait_any_thread_entry, RT_NULL, 1024, 16, 10);
@@ -288,7 +322,7 @@ rt_thread_startup(t_wait_any);
 
 ## 4、注意事项
 
-* 不要在订阅消息的回调函数中执行耗时的操作,否则,请在单独的线程中,使用task_msg_wait_until来处理需要关注的消息。
+* 不要在订阅消息的回调函数中执行消耗资源的操作,否则,请在单独的线程中,使用task_msg_wait_until来处理需要关注的消息。
 
 * 如果使用了结构体数据类型的消息,同时在结构体中定义了指针,且动态分配了内存,一定要设置释放内存的钩子函数,否则会造成内存泄露。
 

+ 69 - 39
examples/task_msg_bus_sample.c

@@ -9,18 +9,43 @@
 #include <ulog.h>
 
 #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-    void msg_3_release_hook(void *args)
+void *msg_3_dump_hook(void *args)
+{
+    struct msg_3_def *msg_3 = (struct msg_3_def *) args;
+    struct msg_3_def *r_msg_3 = rt_calloc(1, sizeof(struct msg_3_def));
+    if (r_msg_3 == RT_NULL)
     {
-        struct msg_3_def *msg_3 = (struct msg_3_def *)args;
-        if(msg_3->buffer)
-            rt_free(msg_3->buffer);
+        return RT_NULL;
+    }
+
+    rt_memcpy((rt_uint8_t *) r_msg_3, (rt_uint8_t *) msg_3, sizeof(struct msg_3_def));
+    if (msg_3->buffer && msg_3->buffer_size > 0)
+    {
+        r_msg_3->buffer = rt_calloc(1, msg_3->buffer_size);
+        if (r_msg_3->buffer == RT_NULL)
+        {
+            rt_free(r_msg_3);
+            return RT_NULL;
+        }
+        rt_memcpy(r_msg_3->buffer, msg_3->buffer, msg_3->buffer_size);
+        r_msg_3->buffer_size = msg_3->buffer_size;
     }
+
+    return r_msg_3;
+}
+void msg_3_release_hook(void *args)
+{
+    struct msg_3_def *msg_3 = (struct msg_3_def *) args;
+    if (msg_3->buffer)
+        rt_free(msg_3->buffer);
+}
 #endif
 
 static void net_reday_callback(task_msg_args_t args)
 {
     //这里不要做耗时操作
-    LOG_D("[net_reday_callback]:TASK_MSG_NET_REDAY => args->msg_name:%d, args->msg_obj:%s", args->msg_name, args->msg_obj);
+    LOG_D("[net_reday_callback]:TASK_MSG_NET_REDAY => args->msg_name:%d, args->msg_obj:%s", args->msg_name,
+            args->msg_obj);
 }
 
 static void os_reday_callback(task_msg_args_t args)
@@ -35,15 +60,17 @@ static void msg_wait_thread_entry(void *params)
     task_msg_args_t args;
     //创建消息订阅者
     int subscriber_id = task_msg_subscriber_create(TASK_MSG_NET_REDAY);
-    if(subscriber_id < 0) return;
+    if (subscriber_id < 0)
+        return;
 
-    while(1)
+    while (1)
     {
         rst = task_msg_wait_until(subscriber_id, 50, &args);
-        if(rst==RT_EOK)
+        if (rst == RT_EOK)
         {
-            LOG_D("[task_msg_wait_until]:TASK_MSG_NET_REDAY => args.msg_name:%d, args.msg_obj:%s", args->msg_name, args->msg_obj);
-            rt_thread_mdelay(200);//模拟耗时操作,在此期间发布的消息不会丢失
+            LOG_D("[task_msg_wait_until]:TASK_MSG_NET_REDAY => args.msg_name:%d, args.msg_obj:%s", args->msg_name,
+                    args->msg_obj);
+            rt_thread_mdelay(200); //模拟耗时操作,在此期间发布的消息不会丢失
             //释放消息
             task_msg_release(args);
         }
@@ -57,23 +84,25 @@ static void msg_wait_any_thread_entry(void *params)
 {
     rt_err_t rst;
     task_msg_args_t args = RT_NULL;
-    const enum task_msg_name name_list[4] = {TASK_MSG_OS_REDAY, TASK_MSG_NET_REDAY, TASK_MSG_2, TASK_MSG_3};
+    const enum task_msg_name name_list[4] = { TASK_MSG_OS_REDAY, TASK_MSG_NET_REDAY, TASK_MSG_2, TASK_MSG_3 };
     //创建 多消息订阅者
-    int subscriber_id = task_msg_subscriber_create2(name_list, sizeof(name_list)/sizeof(enum task_msg_name));
-    if(subscriber_id < 0) return;
+    int subscriber_id = task_msg_subscriber_create2(name_list, sizeof(name_list) / sizeof(enum task_msg_name));
+    if (subscriber_id < 0)
+        return;
 
-    while(1)
+    while (1)
     {
         rst = task_msg_wait_until(subscriber_id, 50, &args);
-        if(rst==RT_EOK)
+        if (rst == RT_EOK)
         {
-            if(args->msg_name==TASK_MSG_OS_REDAY)
+            if (args->msg_name == TASK_MSG_OS_REDAY)
             {
-                LOG_D("[task_msg_wait_any]:TASK_MSG_OS_REDAY => msg_obj is null:%s", args->msg_obj==RT_NULL ? "true" : "false");
+                LOG_D("[task_msg_wait_any]:TASK_MSG_OS_REDAY => msg_obj is null:%s",
+                        args->msg_obj==RT_NULL ? "true" : "false");
             }
-            else if(args->msg_name==TASK_MSG_NET_REDAY)
+            else if (args->msg_name == TASK_MSG_NET_REDAY)
             {
-            #ifdef TASK_MSG_USING_JSON
+#ifdef TASK_MSG_USING_JSON
                 cJSON *root = cJSON_Parse(args->msg_obj);
                 if(root)
                 {
@@ -84,24 +113,25 @@ static void msg_wait_any_thread_entry(void *params)
                     LOG_D("[task_msg_wait_any]:TASK_MSG_NET_REDAY => net_reday:%s, ip:%s, id:%d", (net_reday==0 ? "false" : "true"), ip, id);
                     cJSON_Delete(root);
                 }
-            #else
-                LOG_D("[task_msg_wait_any]:TASK_MSG_NET_REDAY => args.msg_name:%d, args.msg_obj:%s", args->msg_name, args->msg_obj);
-            #endif
+#else
+                LOG_D("[task_msg_wait_any]:TASK_MSG_NET_REDAY => args.msg_name:%d, args.msg_obj:%s", args->msg_name,
+                        args->msg_obj);
+#endif
             }
-            else if(args->msg_name==TASK_MSG_2)
+            else if (args->msg_name == TASK_MSG_2)
             {
-                struct msg_2_def *msg_2 = (struct msg_2_def *)args->msg_obj;
+                struct msg_2_def *msg_2 = (struct msg_2_def *) args->msg_obj;
                 LOG_D("[task_msg_wait_any]:TASK_MSG_2 => msg_2.id:%d, msg_2.name:%s", msg_2->id, msg_2->name);
             }
-        #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-            else if(args->msg_name==TASK_MSG_3)
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+            else if (args->msg_name == TASK_MSG_3)
             {
-                struct msg_3_def *msg_3 = (struct msg_3_def *)args->msg_obj;
+                struct msg_3_def *msg_3 = (struct msg_3_def *) args->msg_obj;
                 LOG_D("[task_msg_wait_any]:TASK_MSG_3 => msg_3.id:%d, msg_3.name:%s", msg_3->id, msg_3->name);
                 LOG_HEX("[task_msg_wait_any]:TASK_MSG_3 => msg_3.buffer", 16, msg_3->buffer, msg_3->buffer_size);
             }
-        #endif
-            rt_thread_mdelay(200);//模拟耗时操作,在此期间发布的消息不会丢失
+#endif
+            rt_thread_mdelay(200);            //模拟耗时操作,在此期间发布的消息不会丢失
             //释放消息
             task_msg_release(args);
         }
@@ -109,7 +139,7 @@ static void msg_wait_any_thread_entry(void *params)
         {
             //可以做其它操作,在此期间发布的消息不会丢失
         }
-    }    
+    }
 }
 
 static void msg_publish_thread_entry(void *params)
@@ -119,7 +149,7 @@ static void msg_publish_thread_entry(void *params)
     rt_thread_mdelay(1000);
     while (1)
     {
-        if(i % 4 == 0)
+        if (i % 4 == 0)
         {
             //不带消息内容
             task_msg_publish(TASK_MSG_OS_REDAY, RT_NULL);
@@ -130,7 +160,7 @@ static void msg_publish_thread_entry(void *params)
             rt_thread_mdelay(10);
             task_msg_publish(TASK_MSG_OS_REDAY, RT_NULL);
         }
-        else if(i % 4 == 1)
+        else if (i % 4 == 1)
         {
             //json/text消息
             rt_snprintf(msg_text, 50, "{\"net_reday\":%d,\"ip\":\"%s\",\"id\":%ld}", 1, "10.0.0.20", i);
@@ -142,7 +172,7 @@ static void msg_publish_thread_entry(void *params)
             rt_thread_mdelay(10);
             task_msg_publish(TASK_MSG_NET_REDAY, msg_text);
         }
-        else if(i % 4 == 2)
+        else if (i % 4 == 2)
         {
             //结构体类型的消息(内部字段无动态内存分配)
             struct msg_2_def msg_2;
@@ -158,11 +188,10 @@ static void msg_publish_thread_entry(void *params)
         }
         else
         {
-        #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-            const char buffer_test[32] = {
-                0x0F, 0x51, 0xEE, 0x89, 0x9D, 0x40, 0x80, 0x22, 0x63, 0x44, 0x43, 0x39, 0x55, 0x2D, 0x12, 0xA1,
-                0x1C, 0x91, 0xE5, 0x2C, 0xC4, 0x6A, 0x62, 0x5B, 0xB6, 0x41, 0xF0, 0xF7, 0x75, 0x48, 0x05, 0xE9
-            };
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+            const char buffer_test[32] = { 0x0F, 0x51, 0xEE, 0x89, 0x9D, 0x40, 0x80, 0x22, 0x63, 0x44, 0x43, 0x39, 0x55,
+                    0x2D, 0x12, 0xA1, 0x1C, 0x91, 0xE5, 0x2C, 0xC4, 0x6A, 0x62, 0x5B, 0xB6, 0x41, 0xF0, 0xF7, 0x75,
+                    0x48, 0x05, 0xE9 };
             //结构体类型的消息(内部字段有动态内存分配)
             struct msg_3_def msg_3;
             msg_3.id = i;
@@ -171,7 +200,8 @@ static void msg_publish_thread_entry(void *params)
             rt_memcpy(msg_3.buffer, buffer_test, 32);
             msg_3.buffer_size = 32;
             task_msg_publish_obj(TASK_MSG_3, &msg_3, sizeof(struct msg_3_def));
-        #endif
+            rt_free(msg_3.buffer);
+#endif
             break;
         }
 

+ 9 - 8
examples/task_msg_bus_user_def.h

@@ -26,15 +26,16 @@ enum task_msg_name{
         rt_uint8_t *buffer;
         rt_size_t buffer_size;
     };
+    extern void *msg_3_dump_hook(void *args);
     extern void msg_3_release_hook(void *args);
-    #define task_msg_release_hooks {\
-            {TASK_MSG_OS_REDAY, RT_NULL},   \
-            {TASK_MSG_NET_REDAY, RT_NULL},  \
-            {TASK_MSG_1, RT_NULL},          \
-            {TASK_MSG_2, RT_NULL},          \
-            {TASK_MSG_3, msg_3_release_hook},          \
-            {TASK_MSG_4, RT_NULL},          \
-            {TASK_MSG_5, RT_NULL},          \
+    #define task_msg_dump_release_hooks {\
+            {TASK_MSG_OS_REDAY,     RT_NULL, RT_NULL},          \
+            {TASK_MSG_NET_REDAY,    RT_NULL, RT_NULL},          \
+            {TASK_MSG_1,            RT_NULL, RT_NULL},          \
+            {TASK_MSG_2,            RT_NULL, RT_NULL},          \
+            {TASK_MSG_3,            msg_3_dump_hook, msg_3_release_hook},   \
+            {TASK_MSG_4,            RT_NULL, RT_NULL},          \
+            {TASK_MSG_5,            RT_NULL, RT_NULL},          \
         }
 #endif
 

+ 7 - 6
inc/task_msg_bus.h

@@ -61,10 +61,11 @@ struct task_msg_wait_node
 };
 typedef struct task_msg_wait_node *task_msg_wait_node_t;
 
-struct task_msg_release_hook
+struct task_msg_dump_release_hook
 {
     enum task_msg_name msg_name;
-    void (*hook)(void *args);
+    void *(*dump)(void *args);
+    void (*release)(void *args);
 };
 
 struct task_msg_loop
@@ -83,11 +84,11 @@ rt_err_t task_msg_publish_obj(enum task_msg_name msg_name, void *msg_obj, rt_siz
 rt_err_t task_msg_delay_publish(rt_uint32_t delay_ms, enum task_msg_name msg_name, const char *msg_text);
 rt_err_t task_msg_delay_publish_obj(rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj,
         rt_size_t msg_size);
-task_msg_loop_t task_msg_loop_create(rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj,
+task_msg_loop_t task_msg_loop_create(void);
+rt_err_t task_msg_loop_delete(task_msg_loop_t msg_loop);
+rt_err_t task_msg_loop_start(task_msg_loop_t msg_loop, rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj,
         rt_size_t msg_size);
-rt_err_t task_msg_loop_delete(task_msg_loop_t msg_timing);
-rt_err_t task_msg_loop_start(task_msg_loop_t msg_timing);
-rt_err_t task_msg_loop_stop(task_msg_loop_t msg_timing);
+rt_err_t task_msg_loop_stop(task_msg_loop_t msg_loop);
 int task_msg_subscriber_create(enum task_msg_name msg_name);
 int task_msg_subscriber_create2(const enum task_msg_name *msg_name_list, rt_uint8_t msg_name_list_len);
 void task_msg_subscriber_delete(int subscriber_id);

+ 17 - 16
inc/task_msg_bus_def.h

@@ -12,24 +12,25 @@
 #include <rtthread.h>
 
 #ifdef TASK_MSG_USER_DEF
-    #include "task_msg_bus_user_def.h"
-    #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-        #ifndef task_msg_release_hooks
-            #error "Please define 'task_msg_release_hooks' in the header file:'task_msg_bus_user_def.h"
-        #endif
-    #endif
+#include "task_msg_bus_user_def.h"
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+#ifndef task_msg_dump_release_hooks
+#error "Please define 'task_msg_dump_release_hooks' in the header file:'task_msg_bus_user_def.h"
+#endif
+#endif
 #else
-    enum task_msg_name{
-        TASK_MSG_OS_REDAY = 0,
-        TASK_MSG_NET_REDAY,
-        TASK_MSG_COUNT
-    };
-    #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-        #define task_msg_release_hooks {\
-                {TASK_MSG_OS_REDAY, RT_NULL},   \
-                {TASK_MSG_NET_REDAY, RT_NULL},  \
+enum task_msg_name
+{
+    TASK_MSG_OS_REDAY = 0,
+    TASK_MSG_NET_REDAY,
+    TASK_MSG_COUNT
+};
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+#define task_msg_dump_release_hooks {                    \
+                {TASK_MSG_OS_REDAY, RT_NULL, RT_NULL},   \
+                {TASK_MSG_NET_REDAY, RT_NULL, RT_NULL},  \
             }
-    #endif
+#endif
 #endif
 
 #endif /* TASK_MSG_BUS_DEF_H_ */

+ 203 - 49
src/task_msg_bus.c

@@ -23,7 +23,7 @@ static struct rt_mutex sub_lock;
 static struct rt_mutex wt_lock;
 static rt_slist_t callback_slist_array[TASK_MSG_COUNT];
 #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-static struct task_msg_release_hook release_hooks[TASK_MSG_COUNT] = task_msg_release_hooks;
+static struct task_msg_dump_release_hook dump_release_hooks[TASK_MSG_COUNT] = task_msg_dump_release_hooks;
 #endif
 static rt_slist_t msg_slist = RT_SLIST_OBJECT_INIT(msg_slist);
 static rt_slist_t msg_ref_slist = RT_SLIST_OBJECT_INIT(msg_ref_slist);
@@ -90,10 +90,10 @@ void task_msg_release(task_msg_args_t args)
                 if (item->args->msg_obj)
                 {
 #ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-                    if (release_hooks[item->args->msg_name].hook
-                            && release_hooks[item->args->msg_name].msg_name == item->args->msg_name)
+                    if (dump_release_hooks[item->args->msg_name].release)
                     {
-                        release_hooks[item->args->msg_name].hook(item->args->msg_obj);
+                        RT_ASSERT(dump_release_hooks[item->args->msg_name].msg_name == item->args->msg_name);
+                        dump_release_hooks[item->args->msg_name].release(item->args->msg_obj);
                     }
 #endif
                     rt_free(item->args->msg_obj);
@@ -403,6 +403,35 @@ rt_err_t task_msg_publish_obj(enum task_msg_name msg_name, void *msg_obj, rt_siz
     msg_args->msg_obj = RT_NULL;
     if (msg_obj && msg_size > 0)
     {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+        if (dump_release_hooks[msg_name].dump)
+        {
+            RT_ASSERT(dump_release_hooks[msg_name].msg_name == msg_name);
+            msg_args->msg_obj = dump_release_hooks[msg_name].dump(msg_obj);
+            if (msg_args->msg_obj == RT_NULL)
+            {
+                rt_free(node);
+                rt_free(msg_args);
+                LOG_E("task msg publish failed! msg_args create failed!");
+                return -RT_ENOMEM;
+            }
+        }
+        else
+        {
+            msg_args->msg_obj = rt_calloc(1, msg_size);
+            if (msg_args->msg_obj)
+            {
+                rt_memcpy(msg_args->msg_obj, msg_obj, msg_size);
+            }
+            else
+            {
+                rt_free(node);
+                rt_free(msg_args);
+                LOG_E("task msg publish failed! msg_args create failed!");
+                return -RT_ENOMEM;
+            }
+        }
+#else
         msg_args->msg_obj = rt_calloc(1, msg_size);
         if (msg_args->msg_obj)
         {
@@ -415,6 +444,7 @@ rt_err_t task_msg_publish_obj(enum task_msg_name msg_name, void *msg_obj, rt_siz
             LOG_E("task msg publish failed! msg_args create failed!");
             return -RT_ENOMEM;
         }
+#endif
     }
     node->args = msg_args;
     rt_slist_init(&(node->slist));
@@ -450,6 +480,13 @@ static void msg_timing_timeout(void *params)
     task_msg_publish_obj(msg_timing->msg_name, msg_timing->msg_obj, msg_timing->msg_size);
     if (msg_timing->msg_obj)
     {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+        if (dump_release_hooks[msg_timing->msg_name].release)
+        {
+            RT_ASSERT(dump_release_hooks[msg_timing->msg_name].msg_name == msg_timing->msg_name)
+            dump_release_hooks[msg_timing->msg_name].release(msg_timing->msg_obj);
+        }
+#endif
         rt_free(msg_timing->msg_obj);
         msg_timing->msg_obj = RT_NULL;
     }
@@ -477,6 +514,28 @@ rt_err_t task_msg_delay_publish_obj(rt_uint32_t delay_ms, enum task_msg_name msg
     msg_loop->msg_size = 0;
     if (msg_obj && msg_size > 0)
     {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+        if (dump_release_hooks[msg_name].dump)
+        {
+            RT_ASSERT(dump_release_hooks[msg_name].msg_name == msg_name);
+            msg_loop->msg_obj = dump_release_hooks[msg_name].dump(msg_obj);
+            if (msg_loop->msg_obj == RT_NULL)
+            {
+                rt_free(msg_loop);
+                return -RT_ENOMEM;
+            }
+        }
+        else
+        {
+            msg_loop->msg_obj = rt_calloc(1, msg_size);
+            if (msg_loop->msg_obj == RT_NULL)
+            {
+                rt_free(msg_loop);
+                return -RT_ENOMEM;
+            }
+            rt_memcpy(msg_loop->msg_obj, msg_obj, msg_size);
+        }
+#else
         msg_loop->msg_obj = rt_calloc(1, msg_size);
         if (msg_loop->msg_obj == RT_NULL)
         {
@@ -484,15 +543,30 @@ rt_err_t task_msg_delay_publish_obj(rt_uint32_t delay_ms, enum task_msg_name msg
             return -RT_ENOMEM;
         }
         rt_memcpy(msg_loop->msg_obj, msg_obj, msg_size);
+#endif
     }
     char name[RT_NAME_MAX];
-    rt_snprintf(name, RT_NAME_MAX, "msg_t%d", msg_name);
+    rt_snprintf(name, RT_NAME_MAX, "delay%d", msg_name);
     msg_loop->timer = rt_timer_create(name, msg_timing_timeout, msg_loop, rt_tick_from_millisecond(delay_ms),
     RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
     if (msg_loop->timer == RT_NULL)
     {
         if (msg_loop->msg_obj)
+        {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+            if (dump_release_hooks[msg_name].release)
+            {
+                RT_ASSERT(dump_release_hooks[msg_name].msg_name == msg_name);
+                dump_release_hooks[msg_name].release(msg_obj);
+            }
+            else
+            {
+                rt_free(msg_loop->msg_obj);
+            }
+#else
             rt_free(msg_loop->msg_obj);
+#endif
+        }
         rt_free(msg_loop);
         return -RT_ENOMEM;
     }
@@ -501,7 +575,21 @@ rt_err_t task_msg_delay_publish_obj(rt_uint32_t delay_ms, enum task_msg_name msg
     if (rst != RT_EOK)
     {
         if (msg_loop->msg_obj)
+        {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+            if (dump_release_hooks[msg_name].release)
+            {
+                RT_ASSERT(dump_release_hooks[msg_name].msg_name == msg_name);
+                dump_release_hooks[msg_name].release(msg_obj);
+            }
+            else
+            {
+                rt_free(msg_loop->msg_obj);
+            }
+#else
             rt_free(msg_loop->msg_obj);
+#endif
+        }
         rt_timer_delete(msg_loop->timer);
         rt_free(msg_loop);
     }
@@ -528,98 +616,164 @@ rt_err_t task_msg_delay_publish(rt_uint32_t delay_ms, enum task_msg_name msg_nam
 
 static void msg_loop_timeout(void *params)
 {
-    task_msg_loop_t msg_timing = (task_msg_loop_t) params;
-    task_msg_publish_obj(msg_timing->msg_name, msg_timing->msg_obj, msg_timing->msg_size);
+    task_msg_loop_t msg_loop = (task_msg_loop_t) params;
+    task_msg_publish_obj(msg_loop->msg_name, msg_loop->msg_obj, msg_loop->msg_size);
 }
 /**
  * create a loop message
+ * @return error code
+ */
+task_msg_loop_t task_msg_loop_create(void)
+{
+    task_msg_loop_t msg_loop = rt_calloc(1, sizeof(struct task_msg_loop));
+    if (msg_loop == RT_NULL)
+        return RT_NULL;
+
+    msg_loop->timer = RT_NULL;
+    msg_loop->msg_obj = RT_NULL;
+    msg_loop->msg_size = 0;
+
+    return msg_loop;
+}
+/**
+ * start a loop message
+ * @param msg_loop
  * @param delay_ms
  * @param msg_name
  * @param msg_obj
  * @param msg_size
  * @return error code
  */
-task_msg_loop_t task_msg_loop_create(rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj,
+rt_err_t task_msg_loop_start(task_msg_loop_t msg_loop, rt_uint32_t delay_ms, enum task_msg_name msg_name, void *msg_obj,
         rt_size_t msg_size)
 {
-    task_msg_loop_t msg_loop = rt_calloc(1, sizeof(struct task_msg_loop));
     if (msg_loop == RT_NULL)
-        return RT_NULL;
+        return -RT_EEMPTY;
 
+    if (msg_loop->timer == RT_NULL)
+    {
+        char name[RT_NAME_MAX];
+        rt_snprintf(name, RT_NAME_MAX, "loop%d", msg_name);
+        msg_loop->timer = rt_timer_create(name, msg_loop_timeout, msg_loop, rt_tick_from_millisecond(delay_ms),
+        RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC);
+        if (msg_loop->timer == RT_NULL)
+        {
+            return -RT_ENOMEM;
+        }
+    }
+    else
+    {
+        rt_timer_stop(msg_loop->timer);
+        rt_tick_t delay_tick = rt_tick_from_millisecond(delay_ms);
+        rt_timer_control(msg_loop->timer, RT_TIMER_CTRL_SET_TIME, &delay_tick);
+    }
+    if (msg_loop->msg_obj)
+    {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+        if (dump_release_hooks[msg_name].release)
+        {
+            RT_ASSERT(dump_release_hooks[msg_name].msg_name == msg_name);
+            dump_release_hooks[msg_name].release(msg_obj);
+        }
+        else
+        {
+            rt_free(msg_loop->msg_obj);
+        }
+#else
+        rt_free(msg_loop->msg_obj);
+#endif
+    }
     msg_loop->msg_name = msg_name;
     msg_loop->msg_obj = RT_NULL;
     msg_loop->msg_size = 0;
+
     if (msg_obj && msg_size > 0)
     {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+        if (dump_release_hooks[msg_name].dump)
+        {
+            RT_ASSERT(dump_release_hooks[msg_name].msg_name == msg_name);
+            msg_loop->msg_obj = dump_release_hooks[msg_name].dump(msg_obj);
+            if (msg_loop->msg_obj == RT_NULL)
+            {
+                return -RT_ENOMEM;
+            }
+        }
+        else
+        {
+            msg_loop->msg_obj = rt_calloc(1, msg_size);
+            if (msg_loop->msg_obj == RT_NULL)
+            {
+                return -RT_ENOMEM;
+            }
+            rt_memcpy(msg_loop->msg_obj, msg_obj, msg_size);
+        }
+#else
         msg_loop->msg_obj = rt_calloc(1, msg_size);
         if (msg_loop->msg_obj == RT_NULL)
         {
-            rt_free(msg_loop);
-            return RT_NULL;
+            return -RT_ENOMEM;
         }
         rt_memcpy(msg_loop->msg_obj, msg_obj, msg_size);
-    }
-    char name[RT_NAME_MAX];
-    rt_snprintf(name, RT_NAME_MAX, "msg_l%d", msg_name);
-    msg_loop->timer = rt_timer_create(name, msg_loop_timeout, msg_loop, rt_tick_from_millisecond(delay_ms),
-    RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC);
-    if (msg_loop->timer == RT_NULL)
-    {
-        if (msg_loop->msg_obj)
-            rt_free(msg_loop->msg_obj);
-        rt_free(msg_loop);
-        return RT_NULL;
+#endif
     }
 
-    return msg_loop;
+    return rt_timer_start(msg_loop->timer);
 }
-/**
- * start a loop message
- * @param msg_timing
- * @return error code
- */
-rt_err_t task_msg_loop_start(task_msg_loop_t msg_timing)
-{
-    if (msg_timing == RT_NULL || msg_timing->timer == RT_NULL)
-        return -RT_EEMPTY;
 
-    return rt_timer_start(msg_timing->timer);
-}
 /**
  * stop a loop message
- * @param msg_timing
+ * @param msg_loop
  * @return error code
  */
-rt_err_t task_msg_loop_stop(task_msg_loop_t msg_timing)
+rt_err_t task_msg_loop_stop(task_msg_loop_t msg_loop)
 {
-    if (msg_timing == RT_NULL || msg_timing->timer == RT_NULL)
+    if (msg_loop == RT_NULL || msg_loop->timer == RT_NULL)
         return -RT_EEMPTY;
 
-    return rt_timer_stop(msg_timing->timer);
+    return rt_timer_stop(msg_loop->timer);
 }
 /**
  * delete a loop message
- * @param msg_timing
+ * @param msg_loop
  * @return error code
  */
-rt_err_t task_msg_loop_delete(task_msg_loop_t msg_timing)
+rt_err_t task_msg_loop_delete(task_msg_loop_t msg_loop)
 {
     rt_err_t rst;
 
-    if (msg_timing == RT_NULL)
+    if (msg_loop == RT_NULL)
         return -RT_EEMPTY;
 
-    if (msg_timing->msg_obj)
+    if (msg_loop->timer)
     {
-        rt_free(msg_timing->msg_obj);
-        msg_timing->msg_obj = RT_NULL;
+        rt_timer_stop(msg_loop->timer);
+        rst = rt_timer_delete(msg_loop->timer);
+        if (rst == RT_EOK)
+            msg_loop->timer = RT_NULL;
     }
-    if (msg_timing->timer)
+    if (rst == RT_EOK)
     {
-        rst = rt_timer_delete(msg_timing->timer);
-        msg_timing->timer = RT_NULL;
+        if (msg_loop->msg_obj)
+        {
+#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
+            if (dump_release_hooks[msg_loop->msg_name].release)
+            {
+                RT_ASSERT(dump_release_hooks[msg_loop->msg_name].msg_name == msg_loop->msg_name);
+                dump_release_hooks[msg_loop->msg_name].release(msg_loop->msg_obj);
+            }
+            else
+            {
+                rt_free(msg_loop->msg_obj);
+            }
+#else
+            rt_free(msg_loop->msg_obj);
+#endif
+        }
+        msg_loop->msg_obj = RT_NULL;
+        msg_loop->msg_size = 0;
+        rt_free(msg_loop);
     }
-    rt_free(msg_timing);
 
     return rst;
 }