ZCM在嵌入式MCU(RTTHREAD)上线程通讯实现

从ZCM通讯简介中我们了解到ZCM还适用于多线程应用,能够提供稳定的内部通讯机制。基于此功能实现了一个内部通讯的demo工程,实现原理:发布订阅使用通一个队列,发布时往队列中写入数据,zcm获取从同一个队列中获取数据,然后按照协议解析,就能拿到一个线程中发布的数据,并根据订阅的主题回调对应的函数执行相应的功能,此demo使用轮询的方式来获取队列中的数据,会性能不足,只是提供一种思路;需要线程中的发布订阅模型还请参考uorb来实现。

  1. 实现ZCM的发送接收功能函数

    size_t serial_get(uint8_t* data, size_t nData, void* usr)
    {
    if(recv_send_buf != NULL)
    {
    return rt_ringbuffer_get(recv_send_buf, data, nData);
    }
    return 0;
    }

    size_t serial_put(const uint8_t* data, size_t nData, void* usr)
    {
    if(recv_send_buf != NULL)
    {
    return rt_ringbuffer_put(recv_send_buf, data, nData);
    }
    return 0;
    }

2.创建ZCM对象,订阅主题

复制代码
struct rt_ringbuffer* recv_send_buf = NULL;
zcm_trans_t * serial_trans = NULL;
zcm_t * serial_zcm = NULL;

int main(void)
{
    rt_thread_t tid;
    int count = 1;
    /* set LED0 pin mode to output */
    recv_send_buf = rt_ringbuffer_create(4096);
    if(recv_send_buf == NULL)
    {
        rt_kprintf("recv send buf malloc failed\r\n");
    }
    
    serial_trans = zcm_trans_generic_serial_create(serial_get, serial_put, serial_trans, tick_now, NULL, 1514, 2048);
    serial_zcm = zcm_create_from_trans(serial_trans);
     zcm_subscribe(serial_zcm, "example", example_1_handle, NULL);
    zcm_subscribe(serial_zcm, "example", example_2_handle, NULL);
    zcm_subscribe(serial_zcm, "example", example_3_handle, NULL);
    return RT_EOK;
}

3。创建2个线程,一个线程用数据数据刷新获取订阅的主题执行回调功能,一个用发布主题主题消息到总线中。

复制代码
int64_t tick_now(void* usr)
{
    return rt_tick_get();
}

void example_1_handle(const zcm_recv_buf_t* rbuf, const char* channel, void* usr)
{
    rt_kprintf("%s, %d, %d\r\n", channel, rbuf->data_size,*((uint32_t *)rbuf->data));
}

void example_2_handle(const zcm_recv_buf_t* rbuf, const char* channel, void* usr)
{
    rt_kprintf("%s, %d, %d\r\n", channel, rbuf->data_size,*((uint32_t *)rbuf->data));
}

void example_3_handle(const zcm_recv_buf_t* rbuf, const char* channel, void* usr)
{
    rt_kprintf("%s, %d, %d\r\n", channel, rbuf->data_size,*((uint32_t *)rbuf->data));
}

void task_entry_1(void* param)
{

    while(1)
    {
        zcm_flush(serial_zcm);
        rt_thread_delay(1);
    }
}

void task_entry_2(void* param)
{
    uint32_t dt = 0;
    while(1)
    {
        dt++;
        zcm_publish(serial_zcm, "example", (uint8_t *)&dt, 1);
        rt_thread_delay(10);
    }
}



int main(void)
{
    rt_thread_t tid;
    int count = 1;
    /* set LED0 pin mode to output */
    recv_send_buf = rt_ringbuffer_create(4096);
    if(recv_send_buf == NULL)
    {
        rt_kprintf("recv send buf malloc failed\r\n");
    }
    
    serial_trans = zcm_trans_generic_serial_create(serial_get, serial_put, serial_trans, tick_now, NULL, 1514, 2048);
    serial_zcm = zcm_create_from_trans(serial_trans);
     zcm_subscribe(serial_zcm, "example", example_1_handle, NULL);
    zcm_subscribe(serial_zcm, "example", example_2_handle, NULL);
    zcm_subscribe(serial_zcm, "example", example_3_handle, NULL);
    tid = rt_thread_create("task_1", task_entry_1, RT_NULL, 1024, 9, 10);
    rt_thread_startup(tid);
    //tid = rt_thread_create("task_2", task_entry_2, RT_NULL, 1024, 10, 10);
    //rt_thread_startup(tid);
    uint32_t dt = 0;
    while(1)
    {
        dt++;
        zcm_publish(serial_zcm, "example", (uint8_t *)&dt, 1);
        rt_kprintf("send :%d\r\n", dt);
        rt_thread_delay(10);
    }
    return RT_EOK;
}
  1. 从嵌入式MCU中运行后,我们会发现三个订阅都会被回调(example_1_handle,example_2_handle,example_3_handle),并将接收的打印出来。
相关推荐
智闲电子设计17 分钟前
STM32 独立看门狗 IWDG 实战:系统跑飞,它来兜底复位
stm32·单片机·嵌入式硬件
qeen871 小时前
【数据结构】自平衡二叉搜索树各种旋转算法原理解析及AVL树的C++实现
数据结构·c++·算法
zcmodeltech2 小时前
智能制造教学实训沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的工业机器人-智慧工厂-数字孪生全场景联动方案
数据库·stm32·嵌入式硬件·机器人·制造·多分类
lucas_AI2 小时前
1.2B 小模型赢过 235B 大模型:NaviDC-OCR 把文档解析卷明白了
人工智能·深度学习·算法
程序员与背包客_CoderZ2 小时前
Linux D-Bus通信协议详解:从入门到C/C++编码实战
linux·服务器·c语言·c++·嵌入式硬件·嵌入式软件·dbus
冻柠檬飞冰走茶2 小时前
PTA基础编程题目集 7-35有理数均值(C++语言实现)
开发语言·数据结构·c++·算法·均值算法
民乐团扒谱机3 小时前
【微实验】倒谱算法(Cepstrum)深度解析:原理、数学推导与代码实现
人工智能·算法·语音识别
嵌入式阿蔡3 小时前
HAL库 vs LL库 vs 寄存器:到底用哪个?
c语言·stm32·单片机·嵌入式硬件·嵌入式实时数据库
Nil2084 小时前
leetcode 189轮转数组
数据结构·算法·leetcode
-dzk-4 小时前
【动态规划】LC 118.杨辉三角
算法·动态规划