因此,一开始我很抱歉成为新手。我尝试自己解决这个问题并搜索其他答案,但我什至不确定自己到底要搜索什么。我发现this是一个有用的答案,但只是希望进一步澄清。
我正在与几个开发委员会合作,努力使他们互相交谈。我需要与之讨论的一个板提供了一些我一直在尝试的示例代码。 TX函数工作正常,只是我对C不够熟悉,无法完全了解我在做什么。
他们提供的RX功能是:
int recv_packet(char *p, int len){
char c;
int received = 0;
/* sit in a loop reading bytes until we put together
* a whole packet.
* Make sure not to copy them into the packet if we
* run out of room.
*/
while(1) {
/* get a character to process
*/
c = UART_GetChar();
/* handle bytestuffing if necessary
*/
switch(c) {
/* if it's an END character then we're done with
* the packet
*/
case END:
/* a minor optimization: if there is no
* data in the packet, ignore it. This is
* meant to avoid bothering IP with all
* the empty packets generated by the
* duplicate END characters which are in
* turn sent to try to detect line noise.
*/
if(received)
return received;
else
break;
/* if it's the same code as an ESC character, wait
* and get another character and then figure out
* what to store in the packet based on that.
*/
case ESC:
c = UART_GetChar();
/* if "c" is not one of these two, then we
* have a protocol violation. The best bet
* seems to be to leave the byte alone and
* just stuff it into the packet
*/
switch(c) {
case ESC_END:
c = END;
break;
case ESC_ESC:
c = ESC;
break;
}
/* here we fall into the default handler and let
* it store the character for us
*/
default:
if(received < len)
p[received++] = c;
}
}
}
然后根据我发现的答案,我可以使用类似的功能来调用它
int main() {
char arr[10] = {0};
recv_packet(arr, 10);
/*then parse it somehow--
* I'll figure this out on my own,
* but for now I just want to read it all
* into an array.
*/
parse_function(arr);
}
因此,如果您完成了所有工作...。我的主要问题是,如果我使长度小于需要接收的消息,如何防止阵列填满?我正在使用C与之交谈的设备将发回一系列以0xC0开头和结尾的十六进制字符(否则在其他代码中定义为“ END”),但是中间是一堆乱七八糟的东西,是从设备取决于我在send_packet中发送的内容。我想我可以将arr
设置得很大,以防万一,但是我想知道在这种情况下适当的编码将决定什么。
答案 0 :(得分:0)
我说您需要更多分析-2个步骤。 第一步:定义(或尊重)您打算使用的协议。协议必须定义最大包长度,没有更大的包是合法的。 您发布的例程已经受到保护,可以防止太大的数据包,但是无法检查其有效性。该协议可以为数据包定义一个固定的长度,或者为不同类型的数据包定义不同的长度,等等,您必须检查它们。
第二步:一次获取一个数据包,对其进行管理,然后重新开始。
有两种技术可以在上述简单情况下提供帮助。如果您需要传输大量数据,请为一个(大)逻辑数据块使用多个数据包。例如,如果您接收数据并将其存储在其他地方(例如闪存),则接收 all 数据然后存储 all 并不好。一次做一次,也许还要进行一致性检查。
第二个建议:如果您担心在管理另一个数据包时可能会丢失一个数据包,则必须使用中断(也许您已经在这样做了)。因此,您可以在处理数据的同时接收 。有时,双缓冲区可以提供帮助。接收数据包,将其放入辅助(双)缓冲区,然后在分析辅助缓冲区时再次开始接收。甚至可以直接在中断例程中进行此操作(切换缓冲区而不是在缓冲区之间进行复制),但这可能不在主题之列。
-注释后更新-
实际上,当涉及数据传输时,在接收到数据的同时处理输入数据 是最有效(并且可能是安全的)方法。无论如何,您都必须接收和解析(两件事要做),因此代码不会变得更大。您不会在等待数据时浪费时间,也不会在浪费不必要的内存。至少,协议的某些低级部分应在接收时完成(您发布的例程使用转义符执行某些操作)。正如您提到的,接收时,有时您会知道会收到多少数据。
答案 1 :(得分:-1)
我想我可以将arr设置得非常大,以防万一,但是我想知道在这种情况下适当的编码会决定什么。
这是正确的-从I / O读取数据时,无论是网络,文件系统等,通常都使用缓冲区,并使其大于预期的传入消息大小。
因此,您可以代替char arr[10] = {0};
char arr[10000];
只需重复使用它,而不必担心空间不足。