使用代码RS485组件
问题
Q1:在读取到数据之后,会再进行数据读取么?
会在进行数据读取的。
Q2:会出现数据接收到一半,开始解析的情况么?
不会出现,在485的接收函数里面,会有等待超时时间,通过设置等待超时时间,可以判断一帧数据是否接收完成。
超时时间设置,该函数里面hinst->timeout = tmo_ms;设置了超时时间。
int rs485_set_recv_tmo(rs485_inst_t * hinst, int tmo_ms)
{
if (hinst == RT_NULL)
{
LOG_E("rs485 set recv timeout fail. hinst is NULL.");
return(-RT_ERROR);
}
hinst->timeout = tmo_ms;
LOG_D("rs485 set recv timeout success. the value is %d.", tmo_ms);
return(RT_EOK);
}
在初始化的时候,int rs485_connect(rs485_inst_t * hinst)该函数里面通过hinst->serial->rx_indicate = rs485_recv_ind_hook;设置了串口接收回调函数,该回调函数如下所示,在这个回调函数里面,每次接收到数据之后,都会发送485接收到数据的标志位。该标志位是用于判断一帧数据是否接收完成来使用的。
static rt_err_t rs485_recv_ind_hook(rt_device_t dev, rt_size_t size)
{
rs485_inst_t *hinst = (rs485_inst_t *)(dev->device_data);
if (hinst->evt)
{
rt_event_send(hinst->evt, RS485_EVT_RX_IND);
}
return(RT_EOK);
}
在int rs485_recv(rs485_inst_t hinst, void buf, int size)函数里面,下面接收代码,下面的图是根据改代码解析出来的流程图。在485接收里面是可以实现接收完整的一帧数据的。
通过参考该链接RT-Thread-rt_sem_control()函数RT-Thread问答社区 - RT-Thread,可知 rt_event_control(hinst->evt, RT_IPC_CMD_RESET, RT_NULL);这一行的代码是重新初始化相关时间集,并将因该事件集产生的挂起操作重新进行唤醒。
while(size)
{
int len = rt_device_read(hinst->serial, 0, (char *)buf + recv_len, size);
if (len)
{
recv_len += len;
size -= len;
continue;
}
rt_event_control(hinst->evt, RT_IPC_CMD_RESET, RT_NULL);
if (recv_len)
{
if (rt_event_recv(hinst->evt, RS485_EVT_RX_IND,
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), hinst->byte_tmo, &recved) != RT_EOK)
{
break;
}
}
else
{
if (rt_event_recv(hinst->evt, (RS485_EVT_RX_IND | RS485_EVT_RX_BREAK),
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), hinst->timeout, &recved) != RT_EOK)
{
break;
}
if ((recved & RS485_EVT_RX_BREAK) != 0)
{
rt_mutex_release(hinst->lock);
rt_thread_delay(2);
return(0);
}
}
}
rt_mutex_release(hinst->lock);
return(recv_len);
原作者:于周斐