是这样的,我想通过RTT实现一个下位机,它可以接收来自RS232、RS485和其它串口模块的数据,并给出响应。我的想法在串口中断中接收数据,然后通过消息队列发送到数据接收线程,然后将接收到的数据通过消息队列,发送到统一的数据处理线程对数据进行处理。大概的示意图如下:
用RS232的数据来举个例子,RS232数据来了以后触发串口中断,然后通过消息队列发送到RS232的数据接收线程,该线程按照我的交互协议格式对接收的数据进行接收,当一帧数据接收完成以后,就发送一个不定长度的消息给数据处理线程(使用动态内存分配),通知数据处理线程对RS232的数据进行处理,数据处理线程接收到不定长度的消息以后,将消息取出,然后释放消息的内存,最后对取出的消息进行处理给出响应结果。
不知道我这种思路是否合理呢?刚从裸机切换到RTOS,老感觉不放心,请大佬们指教。我将部分关键代码贴出来,如下:
typedef struct
{
rt_uint8_t from; /* 消息来源:FROM_RS232、485... */
rt_uint8_t data_ptr; / 数据块首地址 /
rt_uint32_t data_size; / 数据块大小 */
}S_MSG, P_MSG;
/ RS232串口接收中断 /
void USART2_IRQHandler(void)
{
uint8_t data;
rt_err_t res;
rt_interrupt_enter();
if(USART_GetITStatus(USART2, USART_INT_RDNE) != RESET)
{
data = USART_ReceiveData(USART2);
res = rt_mq_send (rs232_recv_mq, &data, 1);/ 发送一个字节的消息给RS232数据接收线程,同时该消息队列也可以作为数据接收缓冲区防止丢包 /
if( res != RT_EOK )
{
while(1);
}
}
rt_interrupt_leave();
}
/ RS232数据接收线程 */
void rs232_thread_entry(void p)
{
rt_err_t res;
uint8_t data;
S_MSG msg_ptr;
while(1)
{
res = rt_mq_recv(rs232_recv_mq, &data, 1, RT_WAITING_FOREVER);
if( res == RT_EOK )
{
....这里有一些协议的判断被省略了,这不重要,总之就是判断一帧数据接收完成...
if( rs232_port.recv_len == length + 3 )/ 到这里表示一帧数据接收完成了 /
{
msg_ptr.data_size = rs232_port.recv_len;/ 记录数据长度 /
msg_ptr.from = FROM_RS232; / 记录数据源 /
msg_ptr.data_ptr = rt_malloc(msg_ptr.data_size);/ 为不定长度的消息数据区分配内存 /
if( msg_ptr.data_ptr == RT_NULL )
{
while(1);
}
rt_memcpy(msg_ptr.data_ptr, rs232_port.recv_buff, msg_ptr.data_size);/ 数据拷贝 /
res = rt_mq_send(host_msg_mq, &msg_ptr, sizeof(msg_ptr));/ 发送消息给数据处理线程 /
if( res != RT_EOK )
{
rt_free(msg_ptr.data_ptr);
while(1);
}
}
}
}
}
/ 数据处理线程 */
void host_if_thread_entry(void p)
{
rt_err_t res;
P_HOST p_host = &host_handle;
S_MSG msg_ptr;
while(1)
{
res = rt_mq_recv(host_msg_mq, &msg_ptr, sizeof(msg_ptr), RT_WAITING_FOREVER);/ 接收不定长消息 /
if( res == RT_EOK )
{
rt_memcpy(p_host->recv_buff, msg_ptr.data_ptr, msg_ptr.data_size);/ 将消息取出,释放消息内存 /
p_host->recv_len = msg_ptr.data_size;
p_host->msg.from = msg_ptr.from;
rt_free(msg_ptr.data_ptr);
host_if_handle(p_host);/ 数据处理 /
if( p_host->msg.from == FROM_RS232 )/ 返回应答 */
{
rs232_send_data(p_host->send_buff, p_host->send_len);
}
}
}
}
更多回帖