首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UART DMA Tx/Rx体系结构

UART DMA Tx/Rx体系结构
EN

Stack Overflow用户
提问于 2012-10-22 01:34:35
回答 2查看 4.4K关注 0票数 2

可能重复: UART ISR Tx Rx Architecture

我现在使用的是TI微型设备,它包括DMA UART驱动程序和支持并行任务的操作系统。UART驱动程序的功能包括:

  • 静态空洞HalUARTInitDMA(空洞);
  • 静态HalUARTOpenDMA(halUARTCfg_t *config);
  • 静态uint16 HalUARTReadDMA(uint8 *buf,uint16 len);
  • 静态uint16 HalUARTWriteDMA(uint8 *buf,uint16 len);
  • 静态空洞HalUARTPollDMA(空洞);
  • 静态uint16 HalUARTRxAvailDMA(void);
  • 静态空洞HalUARTSuspendDMA(空洞);
  • 静态空洞HalUARTResumeDMA(空洞);

我正在尝试与另一个外围设备通信,它接受以回车结束的消息,然后用回车返回来响应消息。

我很好奇如何才能最好地架构这种类型的通信状态机。我的问题是设计UART端口的回调函数,这样它.

  1. 不挂起等待响应的系统。(某种超时)
  2. 如果响应读取得太快,就会将响应连接在一起。
  3. 回车将表示消息的结束。

基本理论是这样的:

代码语言:javascript
复制
//send messsage to peripheral
HalUARTWriteDMA("tx\r",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));

这个想法有几个明显的缺陷。我希望有人能分享一些关于这种沟通方式的想法?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2012-10-22 08:35:25

如果您打算阻止等待消息的线程,设计中有一个直接的问题,就是使用可变大小的消息和一个CR作为分隔符。

我设想HalUARTReadDMA()的设计是为了阻止调用线程,直到接收到len字节为止,因此您显然无法可靠地使用它来阻塞可变长度的消息。

代码看起来类似于(做了一些假设):

代码语言:javascript
复制
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中使用不涉及轮询的可变大小消息的问题,没有特别好或可靠的解决方案--除非DMA控制器能够为您检测消息结束分隔符。

如果您不能更改消息格式,您最好使用中断驱动的IO来阻止单个消息字节的接收,特别是在数据速率相对较低的UART的情况下。

票数 1
EN

Stack Overflow用户

发布于 2012-10-22 23:20:57

除非DMA驱动程序具有接受缓冲区指针队列的功能,否则当接收到CR并自行移动到下一个缓冲区指针时,可以生成一个中断,您将继续迭代rx数据,寻找CR。

如果你必须迭代数据,你也可以在一个“经典的”ISR中这样做,从rx中一个接一个地从rx中获取字符,并将它们推入一个缓冲区,直到接收到CR。

然后,您可以将缓冲区指针排队到一个合适的循环队列中,为下一条消息从另一个“空”缓冲区循环池队列中获取另一个缓冲区,向一个信号量发送信号,以便运行将要处理该消息的线程,并通过操作系统从ISR退出,以便立即执行重新调度。

rx线程可以将消息排出队列,进行处理,然后将其请求到池队列中,以供ISR重用。

用strchr()继续搜索CR的完整缓冲区不太可能是特别有效或容易的-- CR可能位于DMA缓冲区的中间,而您需要参与重新挖掘部分缓冲区的数据复制。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13003971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档