C- UART DMA TX/RX体系结构



可能的重复:
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端口的回调函数,以便它...

  1. 不会悬挂系统等待响应。(某种超时)
  2. 如果响应的读数太早,它将将响应限制在一起
  3. 运输返回将表示消息的末尾

基本理论就是这样:

//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>

相关内容

  • 没有找到相关文章

最新更新