فهرست منبع

增加计划消息功能,去掉原循环消息,更新README.md,更新例程

slyant 3 سال پیش
والد
کامیت
7f2003a29c
4فایلهای تغییر یافته به همراه88 افزوده شده و 371 حذف شده
  1. 10 24
      README.md
  2. 9 24
      examples/task_msg_bus_sample.c
  3. 8 17
      inc/task_msg_bus.h
  4. 61 306
      src/task_msg_bus.c

+ 10 - 24
README.md

@@ -2,7 +2,7 @@
 
 ## 1、介绍
 
-这个软件包实现了基于RT-Thread的消息总线,可以轻松的实现线程间的同步和消息收发,支持文本、数字、结构体等任意复杂的消息类型的发送和接收。当有多个线程订阅消费消息时,不会增加内存的使用,通过设置消息释放的钩子函数,实现内存的自动回收。
+这个软件包实现了基于RT-Thread的消息总线,可以轻松的实现线程间的同步和消息收发,支持文本、数字、结构体等任意复杂的消息类型的发送和接收。当有多个线程订阅消费消息时,不会增加内存的使用,如果消息对象使用了动态内存地址引用,通过设置消息释放的钩子函数,实现内存的自动回收。
 
 ### 1.1 目录结构
 
@@ -17,7 +17,7 @@ TaskMsgBus package 遵循 Apache license v2.0 许可,详见 `LICENSE` 文件
 
 ### 1.3 依赖
 
-无。当开启Json消息类型支持时,会自动选中cJSON软件包。
+无。
 
 ## 2、如何打开 TaskMsgBus package
 
@@ -28,15 +28,14 @@ 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 stack size [384]
             task message thread priority [5]
             [*]task msg name define in user file 'task_msg_bus_user_def.h'
-            [*]task msg format using json
             [*]task msg object using dynamic memory
             [*]Enable TaskMsgBus Sample
 
 ```
-
+或者直接下载源码,添加到项目中编译即可
 ## 3、使用 TaskMsgBus package
 
 按上述方法打开TaskMsgBus package,启用示例,编译工程,即可在控制台看到示例运行结果:
@@ -52,14 +51,14 @@ RT-Thread online packages
 | 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); | 停止定时循环消息发布 |
+| rt_err_t task_msg_scheduled_append(enum task_msg_name msg_name, void *msg_obj, rt_size_t msg_size); | 添加一个计划消息,但不发送 |
+| rt_err_t task_msg_scheduled_start(enum task_msg_name msg_name, int delay_ms, rt_uint32_t repeat, int interval_ms); | 启动一个计划消息(如果之前没有添加过,将自动添加一个无消息体的计划消息):当repeat=0时,先延时delay_ms毫秒发送1次消息后,再按interval_ms毫秒间隔周期性循环发送消息;当repeat=1时,interval_ms参数无效,将延时delay_ms毫秒发送1次消息;当repeat>1时,先延时delay_ms毫秒发送1次消息后,再按interval_ms毫秒间隔周期性循环发送(repeat-1)次消息|
+| rt_err_t task_msg_scheduled_restart(enum task_msg_name msg_name); | 重新启动一个计划消息(将重置定时器) |
+| rt_err_t task_msg_scheduled_stop(enum task_msg_name msg_name); | 停止一个计划消息 |
+| void task_msg_scheduled_delete(enum task_msg_name msg_name); | 删除一个计划消息 |
 | 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); | 阻塞等待指定订阅者的消息 |
+| rt_err_t task_msg_wait_until(int subscriber_id, rt_int32_t timeout_ms, struct task_msg_args **out_args); | 阻塞等待指定订阅者订阅的消息 |
 | void task_msg_release(task_msg_args_t args); | 释放已经消费的消息 |
 | void task_msg_subscriber_delete(int subscriber_id); | 删除一个消息订阅者 |
 
@@ -276,20 +275,7 @@ static void msg_wait_any_thread_entry(void *params)
             }
             else if(args->msg_name==TASK_MSG_NET_REDAY)
             {
-            #ifdef TASK_MSG_USING_JSON
-                cJSON *root = cJSON_Parse(args->msg_obj);
-                if(root)
-                {
-                    int net_reday, id;
-                    cJSON_item_get_number(root, "net_reday", &net_reday);
-                    cJSON_item_get_number(root, "id", &id);
-                    const char *ip = cJSON_item_get_string(root, "ip");
-                    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 if(args->msg_name==TASK_MSG_2)
             {

+ 9 - 24
examples/task_msg_bus_sample.c

@@ -1,8 +1,5 @@
 #include <board.h>
 #include "task_msg_bus.h"
-#ifdef TASK_MSG_USING_JSON
-#include "cJSON_util.h"
-#endif
 
 #define LOG_TAG              "sample"
 #define LOG_LVL              LOG_LVL_DBG
@@ -37,7 +34,7 @@ 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);
+    rt_free(msg_3->buffer);
 }
 #endif
 
@@ -102,21 +99,8 @@ static void msg_wait_any_thread_entry(void *params)
             }
             else if (args->msg_name == TASK_MSG_NET_REDAY)
             {
-#ifdef TASK_MSG_USING_JSON
-                cJSON *root = cJSON_Parse(args->msg_obj);
-                if(root)
-                {
-                    int net_reday, id;
-                    cJSON_item_get_number(root, "net_reday", &net_reday);
-                    cJSON_item_get_number(root, "id", &id);
-                    const char *ip = cJSON_item_get_string(root, "ip");
-                    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 if (args->msg_name == TASK_MSG_2)
             {
@@ -189,9 +173,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 };
+            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;
@@ -213,18 +198,18 @@ static void msg_publish_thread_entry(void *params)
 static int task_msg_bus_sample(void)
 {
     //初始化消息总线(线程栈大小, 优先级, 时间片)
-    task_msg_bus_init(512, 11, 10);
+    task_msg_bus_init();
     //订阅消息
     task_msg_subscribe(TASK_MSG_NET_REDAY, net_reday_callback);
     task_msg_subscribe(TASK_MSG_OS_REDAY, os_reday_callback);
     //创建一个等待消息的线程
-    rt_thread_t t_wait = rt_thread_create("msg_wt", msg_wait_thread_entry, RT_NULL, 512, 17, 10);
+    rt_thread_t t_wait = rt_thread_create("msg_wt", msg_wait_thread_entry, RT_NULL, 1024, 17, 20);
     rt_thread_startup(t_wait);
     //创建一个同时等待多个消息的线程
-    rt_thread_t t_wait_any = rt_thread_create("msg_wa", msg_wait_any_thread_entry, RT_NULL, 1024, 16, 10);
+    rt_thread_t t_wait_any = rt_thread_create("msg_wa", msg_wait_any_thread_entry, RT_NULL, 1024, 16, 20);
     rt_thread_startup(t_wait_any);
     //创建一个发布消息的线程
-    rt_thread_t t_publish = rt_thread_create("msg_pub", msg_publish_thread_entry, RT_NULL, 512, 15, 10);
+    rt_thread_t t_publish = rt_thread_create("msg_pub", msg_publish_thread_entry, RT_NULL, 1024, 15, 20);
     rt_thread_startup(t_publish);
 
     return RT_EOK;

+ 8 - 17
inc/task_msg_bus.h

@@ -68,15 +68,6 @@ struct task_msg_dup_release_hook
     void *(*dup)(void *args);
     void (*release)(void *args);
 };
-//
-//struct task_msg_loop
-//{
-//    enum task_msg_name msg_name;
-//    void *msg_obj;
-//    rt_uint32_t msg_size;
-//    rt_timer_t timer;
-//};
-//typedef struct task_msg_loop *task_msg_loop_t;
 
 struct task_msg_timer_node
 {
@@ -90,18 +81,18 @@ struct task_msg_timer_node
 };
 typedef struct task_msg_timer_node *task_msg_timer_node_t;
 
+int task_msg_bus_init(void);
 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);
 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);
-//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);
+
+rt_err_t task_msg_scheduled_append(enum task_msg_name msg_name, void *msg_obj, rt_size_t msg_size);
+rt_err_t task_msg_scheduled_start(enum task_msg_name msg_name, int delay_ms, rt_uint32_t repeat, int interval_ms);
+rt_err_t task_msg_scheduled_restart(enum task_msg_name msg_name);
+rt_err_t task_msg_scheduled_stop(enum task_msg_name msg_name);
+void task_msg_scheduled_delete(enum task_msg_name msg_name);
+
 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);

+ 61 - 306
src/task_msg_bus.c

@@ -14,6 +14,15 @@
 #define DBG_LVL DBG_LOG
 #include <rtdbg.h>
 
+#ifndef TASK_MSG_THREAD_STACK_SIZE
+#define TASK_MSG_THREAD_STACK_SIZE 384
+#endif
+#ifndef TASK_MSG_THREAD_PRIORITY
+#define TASK_MSG_THREAD_PRIORITY 5
+#endif
+
+//#define TASK_MSG_USING_DYNAMIC_MEMORY
+
 static rt_bool_t task_msg_bus_init_tag = RT_FALSE;
 static struct rt_mailbox msg_mb;
 static rt_uint8_t mbpool[128];
@@ -541,6 +550,7 @@ rt_err_t task_msg_scheduled_append(enum task_msg_name msg_name, void *msg_obj, r
     node->args = msg_args;
     rt_slist_init(&(node->slist));
     rt_mutex_take(&msg_tlck, RT_WAITING_FOREVER);
+    task_msg_scheduled_delete(msg_name);
     rt_slist_append(&msg_timer_slist, &(node->slist));
     rt_mutex_release(&msg_tlck);
 
@@ -553,7 +563,23 @@ static void scheduled_timeout_callback(void *params)
     rt_ubase_t msg_name = (rt_ubase_t) (item->args->msg_name);
     rt_mb_send(&msg_mb, msg_name);
 }
-
+/**
+ * Restart a schedule message(can be used in ISR)
+ * @param msg_name: message name
+ * @return error code
+ */
+rt_err_t task_msg_scheduled_restart(enum task_msg_name msg_name)
+{
+    rt_mb_send(&msg_mb, (rt_ubase_t) msg_name);
+}
+/**
+ * Start a schedule message, if it has not been added before, a message without parameters will be automatically added
+ * @param msg_name: message name
+ * @param delay_ms: delay time(ms)
+ * @param repeat: repeat count(0:infinite)
+ * @param interval_ms: interval time(ms)
+ * @return error code
+ */
 rt_err_t task_msg_scheduled_start(enum task_msg_name msg_name, int delay_ms, rt_uint32_t repeat, int interval_ms)
 {
     rt_err_t res;
@@ -565,16 +591,23 @@ rt_err_t task_msg_scheduled_start(enum task_msg_name msg_name, int delay_ms, rt_
         if (item->args->msg_name == msg_name)
         {
             msg_exist = RT_TRUE;
-            if (rt_object_get_type(&(item->timer.parent)) != RT_Object_Class_Timer)
-            {
-                char name[RT_NAME_MAX];
-                rt_snprintf(name, RT_NAME_MAX, "schtim%d", msg_name);
-                rt_timer_init(&(item->timer), name, scheduled_timeout_callback, item, rt_tick_from_millisecond(delay_ms),
-                RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
-            }
             item->interval = rt_tick_from_millisecond(interval_ms);
             item->repeat = repeat;
             item->do_count = 0;
+            int delay_tick = rt_tick_from_millisecond(delay_ms);
+            if (rt_object_get_type(&(item->timer.parent)) == RT_Object_Class_Timer)
+            {
+                rt_timer_control(&(item->timer), RT_TIMER_CTRL_SET_TIME, &delay_tick);
+                rt_timer_control(&(item->timer), RT_TIMER_CTRL_SET_ONESHOT, RT_NULL);
+            }
+            else
+            {
+                char name[RT_NAME_MAX];
+                rt_snprintf(name, RT_NAME_MAX, "sch%d", msg_name);
+                rt_timer_init(&(item->timer), name, scheduled_timeout_callback, item,
+                        rt_tick_from_millisecond(delay_ms),
+                        RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
+            }
             res = rt_timer_start(&(item->timer));
             item->stop = RT_FALSE;
             break;
@@ -584,14 +617,18 @@ rt_err_t task_msg_scheduled_start(enum task_msg_name msg_name, int delay_ms, rt_
     if (!msg_exist)
     {
         res = task_msg_scheduled_append(msg_name, RT_NULL, 0);
-        if (res)
+        if (res == RT_EOK)
         {
             res = task_msg_scheduled_start(msg_name, delay_ms, repeat, interval_ms);
         }
     }
     return res;
 }
-
+/**
+ * Stop a schedule message
+ * @param msg_name: message name
+ * @return error code
+ */
 rt_err_t task_msg_scheduled_stop(enum task_msg_name msg_name)
 {
     rt_err_t res = RT_EOK;
@@ -612,8 +649,11 @@ rt_err_t task_msg_scheduled_stop(enum task_msg_name msg_name)
     rt_mutex_release(&msg_tlck);
     return res;
 }
-
-rt_err_t task_msg_scheduled_delete(enum task_msg_name msg_name)
+/**
+ * Delete a schedule message
+ * @param msg_name: message name
+ */
+void task_msg_scheduled_delete(enum task_msg_name msg_name)
 {
     task_msg_timer_node_t item;
     rt_mutex_take(&msg_tlck, RT_WAITING_FOREVER);
@@ -661,292 +701,6 @@ rt_err_t task_msg_publish(enum task_msg_name msg_name, const char *msg_text)
     }
     return task_msg_publish_obj(msg_name, msg_obj, args_size);
 }
-
-//static void msg_timing_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);
-//    if (msg_timing->msg_obj)
-//    {
-//#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-//        if (dup_release_hooks[msg_timing->msg_name].release)
-//        {
-//            RT_ASSERT(dup_release_hooks[msg_timing->msg_name].msg_name == msg_timing->msg_name)
-//            dup_release_hooks[msg_timing->msg_name].release(msg_timing->msg_obj);
-//        }
-//#endif
-//        rt_free(msg_timing->msg_obj);
-//        msg_timing->msg_obj = RT_NULL;
-//    }
-//    rt_timer_delete(msg_timing->timer);
-//    msg_timing->timer = RT_NULL;
-//    rt_free(msg_timing);
-//}
-///**
-// * Publish a delay message object.
-// * @param delay_ms: delay ms
-// * @param msg_name: message name
-// * @param msg_obj: message object
-// * @param msg_size: message size
-// * @return error code
-// */
-//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 msg_loop = rt_calloc(1, sizeof(struct task_msg_loop));
-//    if (msg_loop == RT_NULL)
-//        return -RT_ENOMEM;
-//
-//    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 (dup_release_hooks[msg_name].dup)
-//        {
-//            RT_ASSERT(dup_release_hooks[msg_name].msg_name == msg_name);
-//            msg_loop->msg_obj = dup_release_hooks[msg_name].dup(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)
-//        {
-//            rt_free(msg_loop);
-//            return -RT_ENOMEM;
-//        }
-//        rt_memcpy(msg_loop->msg_obj, msg_obj, msg_size);
-//#endif
-//        msg_loop->msg_size = msg_size;
-//    }
-//    char name[RT_NAME_MAX];
-//    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 (dup_release_hooks[msg_name].release)
-//            {
-//                RT_ASSERT(dup_release_hooks[msg_name].msg_name == msg_name);
-//                dup_release_hooks[msg_name].release(msg_obj);
-//            }
-//#endif
-//            rt_free(msg_loop->msg_obj);
-//        }
-//        rt_free(msg_loop);
-//        return -RT_ENOMEM;
-//    }
-//
-//    rt_err_t rst = rt_timer_start(msg_loop->timer);
-//    if (rst != RT_EOK)
-//    {
-//        if (msg_loop->msg_obj)
-//        {
-//#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-//            if (dup_release_hooks[msg_name].release)
-//            {
-//                RT_ASSERT(dup_release_hooks[msg_name].msg_name == msg_name);
-//                dup_release_hooks[msg_name].release(msg_obj);
-//            }
-//#endif
-//            rt_free(msg_loop->msg_obj);
-//        }
-//        rt_timer_delete(msg_loop->timer);
-//        rt_free(msg_loop);
-//    }
-//
-//    return rst;
-//}
-///**
-// * Publish a delay text message.
-// * @param delay_ms: delay ms
-// * @param msg_name: message name
-// * @param msg_text: message text
-// * @return error code
-// */
-//rt_err_t task_msg_delay_publish(rt_uint32_t delay_ms, enum task_msg_name msg_name, const char *msg_text)
-//{
-//    void *msg_obj = (void *) msg_text;
-//    rt_size_t args_size = 0;
-//    if (msg_obj)
-//    {
-//        args_size = rt_strlen(msg_text) + 1;
-//    }
-//    return task_msg_delay_publish_obj(delay_ms, msg_name, msg_obj, args_size);
-//}
-//
-//static void msg_loop_timeout(void *params)
-//{
-//    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
-// */
-//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)
-//{
-//    if (msg_loop == 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 (dup_release_hooks[msg_name].release)
-//            {
-//                RT_ASSERT(dup_release_hooks[msg_name].msg_name == msg_name);
-//                dup_release_hooks[msg_name].release(msg_obj);
-//            }
-//#endif
-//            rt_free(msg_loop->msg_obj);
-//        }
-//    }
-//    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 (dup_release_hooks[msg_name].dup)
-//        {
-//            RT_ASSERT(dup_release_hooks[msg_name].msg_name == msg_name);
-//            msg_loop->msg_obj = dup_release_hooks[msg_name].dup(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)
-//        {
-//            return -RT_ENOMEM;
-//        }
-//        rt_memcpy(msg_loop->msg_obj, msg_obj, msg_size);
-//#endif
-//        msg_loop->msg_size = msg_size;
-//    }
-//
-//    return rt_timer_start(msg_loop->timer);
-//}
-//
-///**
-// * stop a loop message
-// * @param msg_loop
-// * @return error code
-// */
-//rt_err_t task_msg_loop_stop(task_msg_loop_t msg_loop)
-//{
-//    if (msg_loop == RT_NULL || msg_loop->timer == RT_NULL)
-//        return -RT_EEMPTY;
-//
-//    return rt_timer_stop(msg_loop->timer);
-//}
-///**
-// * delete a loop message
-// * @param msg_loop
-// * @return error code
-// */
-//rt_err_t task_msg_loop_delete(task_msg_loop_t msg_loop)
-//{
-//    rt_err_t rst;
-//
-//    if (msg_loop == RT_NULL)
-//        return -RT_EEMPTY;
-//
-//    if (msg_loop->timer)
-//    {
-//        rt_timer_stop(msg_loop->timer);
-//        rst = rt_timer_delete(msg_loop->timer);
-//        if (rst == RT_EOK)
-//            msg_loop->timer = RT_NULL;
-//    }
-//    if (rst == RT_EOK)
-//    {
-//        if (msg_loop->msg_obj)
-//        {
-//#ifdef TASK_MSG_USING_DYNAMIC_MEMORY
-//            if (dup_release_hooks[msg_loop->msg_name].release)
-//            {
-//                RT_ASSERT(dup_release_hooks[msg_loop->msg_name].msg_name == msg_loop->msg_name);
-//                dup_release_hooks[msg_loop->msg_name].release(msg_loop->msg_obj);
-//            }
-//#endif
-//            rt_free(msg_loop->msg_obj);
-//        }
-//        msg_loop->msg_obj = RT_NULL;
-//        msg_loop->msg_size = 0;
-//        rt_free(msg_loop);
-//    }
-//
-//    return rst;
-//}
 /**
  * Initialize the callback slist array.
  */
@@ -1041,31 +795,32 @@ static void task_msg_mb_thread_entry(void *params)
             {
                 if (item->args->msg_name == name)
                 {
-                    rt_bool_t restart = RT_FALSE;
+                    rt_bool_t resend = RT_FALSE;
                     task_msg_publish_obj(name, item->args->msg_obj, item->args->msg_size);
                     if (item->stop)
                     { //停止
-                        restart = RT_FALSE;
+                        resend = RT_FALSE;
                     }
                     else if (item->repeat == 0)
                     { //无限重复
-                        restart = RT_TRUE;
+                        item->do_count++;
+                        resend = RT_TRUE;
                     }
                     else
                     {
                         item->do_count++;
                         if (item->do_count < item->repeat)
                         {
-                            restart = RT_TRUE;
+                            resend = RT_TRUE;
                         }
                         else
                         {
-                            restart = RT_FALSE;
+                            resend = RT_FALSE;
                         }
                     }
-                    if (restart)
+                    if (resend)
                     {
-                        if(item->do_count==1)
+                        if (item->do_count == 1)
                         {
                             rt_timer_control(&(item->timer), RT_TIMER_CTRL_SET_TIME, &(item->interval));
                             rt_timer_control(&(item->timer), RT_TIMER_CTRL_SET_PERIODIC, RT_NULL);
@@ -1073,7 +828,7 @@ static void task_msg_mb_thread_entry(void *params)
                         rt_timer_start(&(item->timer));
                         item->stop = RT_FALSE;
                     }
-                    else
+                    else if (!item->stop)
                     {
                         rt_timer_stop(&(item->timer));
                         item->stop = RT_TRUE;