一、背景描述
? 在微控制器之间进行数据通信时,大多需要添加无应答重发机制,以增强数据交互和通信的稳定性。
在使用UART通信的双方设备,当一次数据传输发起后,数据传输方需要再次接收到数据接收方反馈的数据(可以称之为应答数据)后,再停止发送重复的数据。这就相当于通信双方的一个监听“心跳”,维持着通信的稳定和健壮性,当然,通信的稳定性受多方面的影响,本文不考虑过多的因素。那么,在基于RTOS的嵌入式微控制器软件的设计过程中,如何来实现UART通信双方无应答重发机制呢。本文就这个话题,分享两种基于RTOS的无应答重发机制。
? 文本以rt-thread操作系统作为RTOS基建,其他RTOS类似,本文的代码实现主要依赖于操作系统下的一些线程同步、或者定时器机制。
二、结构框图
三、基于RTOS的信号量的实现
(3-1)思路描述
? 通过定义一个无应答重发信号量,在发送线程函数中执行无应答重发操作,并接收无应答重发信号量,当没有接收到无应答重发信号量,则重新发起数据重发操作;在接收线程中接收应答码,如果接收到应答码,则发送信号量,如果接收线程接收到了信号量,则结束无应答重发操作。
(3-2)步骤
(3-2-1)定义无应答重发信号量
static struct rt_semaphore no_Ask_resend_sem ;
(3-2-2)定义发送线程入口
static void sendThreadEntry(void *parameter)
{
while(1)
{
if()
{
while(1)
{
rt_device_write());
if(rt_sem_take(&no_Ask_resend_sem, 1000) == RT_OK)
{
break;
}
rt_thread_mdelay(1);
}
}
rt_thread_mdelay(1);
}
}
(3-2-3)定义接收线程入口
static void recvThreadEntry(void *parameter)
{
while(1)
{
......
if()
{
rt_sem_release(&no_Ask_resend_sem);
}
.......
rt_thread_mdelay(1);
}
}
四、基于定时器的实现
(4-1)思路描述
? 创建一个无应答重发定时器。在发送线程中,当执行数据发送后,随后启动无应答重发定时器(在定时器超时处理函数中执行数据发送操作)。在接收线程中,解析是否接收到了的应答码,如果接收到了应答码,则停止无应答重发定时器。
(4-2)步骤
(4-2-1)创建定时器
rt_timer_init(&no_Ask_resend_timer,"no_Ask_send_timer",
no_ask_handler, RT_NULL, NO_ASK_TIME_OUT_PERIOD, RT_TIMER_FLAG_HARD_TIMER);
(4-2-2)定义定时器超时处理函数
static void no_ask_handler(void *parameter)
{
static rt_uint8_t times = 0;
times ++;
if(times > 5)
{
times = 0;
}
com_send_Data(control_code);
}
(4-2-3)定义发送线程入口
static void rs232_tx_thread_entry()
{
while (1)
{
if ()
{
rt_device_write(serial,0,buf,4);
rt_timer_start(&no_Ask_resend_timer);
}
rt_thread_mdelay(1);
}
}
(4-2-4)定义接收线程入口
static void rs232_rx_thread_entry()
{
while (1)
{
......
if()
{
rt_timer_stop(&no_Ask_resend_timer);
}
......
}
}
|