rt-thread中用消息队列实现广播功能的一种方法

前面几天在逛论坛时看见有人说RTT中没有广播机制,于是心血来潮,想自己动手写一个,于是有了此文.

1 广播机制分析

广播,这个词首先让我想到Android下的广播机制,其是基于Binder来实现的,然而RTT并不是Linux内核的东东,也没有Binder这样的IPC,RTT有自己的一套IPC机制,前面的文章中有说到信号,互斥量,事件,邮箱和消息队列,我们得从这方面动动脑筋.

再回来广播这个词,现实中,电视就是一个广播的例子,我们就以电视来举例,在现实的生活中,不同的人到电视台做节目,然后家家户户就可以在电视机中收到节目了.分析一个这个模型,不同的人到电视台做节目,这里将不同的人暂且叫做广播发送者(广播可以有多个发送方),电视台提供广播发送服务,这里就叫做服务好了,然后每家都可以打开电视机接收电视节目信号,这里每台的电视机就是电视台的一个终端.

因此,这里归结一个,在RTT中,要实现广播机制,首先,广播的发送者是线程,接收者也是线程,做为发送线程和接收线程中间就需要一个服务器,专门实现将发送线程传过来的消息转发给各个已经注册的接收线程.各个接收线程看成是这个服务器的终端.在实现这个功能,首先,作为广播消息的接收终端,那么它得有一定的缓冲能力,得保存一定条数的消息,其次,作为广播的服务器,得唤醒所有等待接收的接收线程.因此,我们得分别给服务器和客户端定义一种数据结构.

2 广播服务器和客户端的控制块

在rtdef.h头文件中,在消息队列宏内添加广播控制块的定义:

//广播服务器的控制块
struct rt_broadcast_server
{
	//客户端节点链表
    rt_list_t client_list;
};
typedef struct rt_broadcast_server *rt_broadcast_server_t;

//广播接客户端的控制块
struct rt_broadcast_client
{    //接收消息队列
     struct rt_messagequeue receive_mq;
	 //客户端节点
     rt_list_t node;
     //此广播客户端对应的服务器
     //rt_broadcast_server_t server;
};
typedef struct rt_broadcast_client *rt_broadcast_client_t;

由上述可见,广播服务器控制块只包含一个链表client_list,用来保存广播客户端. 而广播客户端的控制块定义中,包含了一个消息队列receive_mq,此队列用来缓存来自广播服务器的消息,除此之外,还有一链表节点,用来作链表操作.

3 广播的接口实现

在ipc.c实现其接口:
//初始化广播服务器
rt_err_t rt_broadcast_server_init(rt_broadcast_server_t server)
{
    RT_ASSERT(server !=RT_NULL);

	//初始化客户端链表
    rt_list_init(&(server->client_list));

    return RT_EOK;
}
RTM_EXPORT(rt_broadcast_server_init);
//初始化广播客户端
rt_err_t rt_broadcast_client_init(rt_broadcast_client_t client,
                                    const char *name,
                                    void *msgpool,
                                    rt_size_t   msg_size,
                                    rt_size_t   pool_size,
                                    rt_uint8_t  flag)
{
    rt_err_t err;

    RT_ASSERT(client !=RT_NULL);
   	//使用传入的消息池初始化接收消息队列
    err =rt_mq_init(&client->receive_mq,name,msgpool,msg_size,pool_size,flag);
    if(err !=RT_EOK)
    {
        return err;
    }

	//初始化客户端节点
    rt_list_init(&client->node);
    return RT_EOK;    
}
RTM_EXPORT(rt_broadcast_client_init);
//给广播服务器注册客户端
rt_err_t rt_broadcast_client_regist(rt_broadcast_server_t server,rt_broadcast_client_t client)
{
    register rt_base_t temp;

    RT_ASSERT(server !=RT_NULL);
    RT_ASSERT(client !=RT_NULL);
   	//开关断
    temp = rt_hw_interrupt_disable();
	//将客户端节点注册到到服务器
    rt_list_insert_after(&server->client_list,&client->node);

    //开中断
    rt_hw_interrupt_enable(temp);
    return RT_EOK;
}
RTM_EXPORT(rt_broadcast_client_regist);
//卸载一个客户端
rt_err_t rt_broadcast_client_unregist(rt_broadcast_client_t client)
{
    register rt_base_t temp;

    RT_ASSERT(client !=RT_NULL);
    //关中断
    temp = rt_hw_interrupt_disable();
	//将客户端节点从服务器上移除
    rt_list_remove(
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值