【发布时间】:2012-11-11 07:09:55
【问题描述】:
我是不是把事情复杂化了?
我正在构建我的代码以通过 UART 从 8051 微型设备与外围设备通信。外设响应来自主机的命令,并且一次只能响应一个命令。这是一个简单的发送和接收协议。 (tx1, rx1, tx2, rx2, tx3, rx3) 每个 TX 消息以 CR 结束,每个响应以 > 结束。在收到对最后一条消息的回复之前,我无法发送新消息。如果我启用该选项,响应也可以在开头回显原始 TX 消息(但这会导致更多流量)
一个示例消息是:
- TX:你好
- RX:世界!>
或者使用回显选项...
- TX:你好
- RX:你好\rWorld!>
选项 A 像 getHello 这样的函数将包含发送和接收。并行 ISR 例程将收集传入字节并在接收到“>”字符时抛出一个标志。
char* getHello(char * buf){
sendMsg("Hello\r");
delay(10ms); //wait a little bit
//wait for receive to come in or timeout to occur
while(!receiveFlag || !timeoutFlag); //thrown by ISR
receiveMsg(buf);
//parse the message and do some other stuff
return buf;
}
优点:
- 一切都包含在一个函数中。
- 更容易调试
缺点:
- 此函数处于阻塞状态,如果外围设备从不响应,则可能会挂起,因此必须实现超时。
- 消息不能乱序接收,必须串联(即tx1、rx1、tx2、rx2、tx3、rx3)
选项 B 采取平行的方法。将创建两个单独的函数。一种用于发送消息,另一种用于在收到 ISR 的响应时进行顶点处理。
void sendHello(){
sendMsg("Hello\r");
//do some other stuff if needed
}
char* receiveMsg(char * buf){
//figure out from echo print what the tx message was
//use a switch statement to decide which response parser to call
switch(txMessage){ //pseudo code
case "Hello":
receiveMsg(buf);
//parse the message and do some other stuff
break;
}
return buf;
}
优点:
- 可以处理乱序返回的并行消息,因为它依赖于 tx 消息的回显打印来确定如何解析它。 (即 tx1、tx2、tx3、rx1、rx2、rx3)
缺点:
- 很难调试
- 产生多个线程
- 很多额外的代码
- 不值得,因为消息肯定会按顺序返回
现在,我正在做选项 B,但随着我继续这个项目,我开始觉得这变得过于复杂。我很好奇你们是怎么想的。
谢谢!
【问题讨论】:
-
case "Hello":你是在比较指针,而不是字符串。 -
一般来说我会:清空接收缓冲区并等待一段时间以验证没有任何内容进入。然后发送提示并启动计时器。然后在每个进入缓冲区的字节中断时,缓冲它直到你得到 end > 字符,或者发生超时。然后,中断可以触发一个标志,向主指示返回超时或收到有效数据包。
-
Ouah- 是的,我知道,我对伪代码很懒惰。
-
Myforwik - 您的建议似乎与选项 b 非常相似。有什么不同吗?
标签: c architecture serial-port serial-communication uart