可能的重复:
UART ISR TX RX体系结构
我现在正在使用一个Ti Micro,其中包括DMA UART驱动程序和支持并行任务的操作系统。UART驱动程序的功能包括:
- 静态void haluartinitdma(void);
- 静态void haluartopendma(haluartcfg_t *config);
- static uint16 haluartreaddma(uint8 *buf,uint16 len);
- static uint16 haluartwritedma(uint8 *buf,uint16 len);
- 静态void haluartpolldma(void);
- static uint16 haluartrxavaildma(void);
- 静态void haluartsuspenddma(void);
- 静态无效haluartresumedma(void);
我正在尝试与另一个接受带有马车退货终止消息的外围沟通,然后随后响应了马车返回。
我很好奇构建这种通信状态机器的最佳方法。我的问题是设计UART端口的回调函数,以便它...
- 不会悬挂系统等待响应。(某种超时)
- 如果响应的读数太早,它将将响应限制在一起
- 运输返回将表示消息的末尾
基本理论就是这样:
//send messsage to peripheral
HalUARTWriteDMA("txr",4);
//wait a little bit for the device to process the message
//start reading from the peripheral
do {
//how many bytes are at the RX port?
int len = HalUARTRxAvailDMA();
//Read those bytes
HalUARTReadDMA(msg, len);
//append the rx msg to the buffer
strcat(rxbuf, msg)
//does the response contain a CR?
} while(strchr(rxbuf, 0x0D));
这个想法有几个明显的缺陷。我希望有人可以分享一些有关如何进行这种交流的想法?
谢谢!
如果您打算阻止线程等待消息,则设计时有一个直接的问题 - 这是使用变量大小的消息,而CR
作为定界符。p>我想HalUARTReadDMA()
旨在阻止调用线程,直到收到len
字节,因此您显然无法可靠地使用它来阻止可变长度消息。
代码看起来像(做几个假设):
while (1)
{
static const size_t bufferSize = sizeof(Message_t);
uint8_t buffer[bufferSize];
// blocks until message received
unsigned len = HalUARTReadDMA(buffer, bufferSize);
if (len == bufferSize)
processMessage(buffer);
}
对于使用不涉及轮询的可变大小的消息的问题,没有特别好或可靠的解决方案 - 除非DMA控制器可以为您检测消息结束分界符。
如果您无法更改消息格式,则最好通过中断驱动的IO来限制您在接收单个消息字节的接收时(尤其是在UART的情况下,数据速率相对较低)。
,除非您的DMA驱动程序具有接受缓冲指针队列的功能,否则在接收CR并自行移动到下一个缓冲指针时会产生中断迭代RX数据,寻找Cr。
如果您必须迭代数据,则可以在"经典" ISR中进行此操作,从RX FIFO逐一获取字符,然后将它们推入缓冲区,直到收到CR为止。
然后,您可以将缓冲指针排队为合适的圆形队列,从另一个"空"缓冲区的另一个圆形池队列中获取另一个缓冲区的另一个缓冲区,请发出信号量的信号,以便将要处理该消息的线程通过OS运行并从ISR退出,以便立即进行重新安排。
RX线程可以取消消息,对其进行处理,然后将其申请到池队列以通过ISR重复使用。
连续搜索使用strchr()的CR的完整缓冲区不太可能特别有效或容易 - CR可能位于DMA缓冲区的中间,您可以参与自由的部分缓冲区的数据复制。/p>
。