2011-03-10 94 views
0

我想修改一个函数,以更明智的为我的目的;C上的ARM - 等待UART接收

int getc0 (void) 
{ 
    while ((U0LSR & 0x01) == 0); //Wait for character 
    return U0RBR; 
} 

上面的代码导致函数挂起,直到串行端口0上接收到一个字符,然后返回它。 我用这样的while循环来调用它;

while((str = getc0())!='\r'){ 
    strcat(&route_buffer,&str); 
} 

所以现在我有它等待,直到接收通过串行端口返回车厢而在此之前的每个字符复制到缓冲区中。 现在我的问题是,目前我正在阅读数据时遇到一些问题,我无法确定问题出在哪里,无论哪种方式都无法正确识别返回车厢或换行符,但它正在接收某些输出! 我知道这一点,因为我已经将所有内容保存到一个文件中,但是要做到这一点,我必须在while循环中有一个i!= 5,并且只需要读取5个字符。如果我这样做到20它再次挂起并似乎不读取任何其他东西(即使我通过uart发送数据)

有没有办法我可以修改它读取X的时间量,然后继续函数的其余部分?

编辑:

char route_data[512], route_buffer[200]; 

编辑2:

char *str; 

好吧,这里是我写在用户输入读取功能;

char* readInput(void){ 

    userinput = 0; 
    str = 0; 

    while((str=getc0())!='\r'){ 
     strcat(&userinput,&str); 

    } 
    return &userinput; 

} 

它被称为像这样;

strcat(config.nodeid,readInput()); 

它被称为很多,但这是我怎么称呼它的一个例子。然后我将它输出到一个文件,并且它可以在100%的时间内运行。

这可能有助于解释整个问题; 我有一块ARM板,连接到串口的无线模块(RX和TX)。上面的readInput函数用于读取远程登录到无线模块的用户的输入,并使ARM板读取用户的所有输入。 我现在想要实现的是在执行命令后从无线模块读取输入。使用printf语句,我可以通过将命令放入语句来执行命令。我需要做的是读取无线模块的输出,这是我遇到困难的地方。我得到了一些输出,但它非常有限,并不是预期的结果,但它显然是来自模块的。

+0

请显示route_buffer的定义。 – Throwback1986 2011-03-10 21:07:41

+0

如何定义'str'?如何定义'route_buffer'? 'str'应该是一个'int',与函数getc0()兼容,并且不能像这样将'int'传递给'strcat()'! – pmg 2011-03-10 21:09:44

+0

我已编辑上述内容以包含所需信息。给我五分钟,我会详细说明为什么我已经完成了上述以及我已经做了什么来验证它。 – Draineh 2011-03-10 21:12:49

回答

3

str不是一个nul结尾的字符串,它将地址传递给strcat()会将不确定数量的数据连接到route_buffer。

由于多种原因,在任何情况下使用strcat()都是一个坏主意,而且您的使用情况尤其不明智。对缓冲区溢出没有保护,并且strcat()每次调用时都必须不必要地重新确定route_buffer中字符串的长度。

一个稍微更好的解决办法是:

int index = strlen(route_buffer) ; 
int ch ; 
while(index < sizeof(route_buffer) - 1 && (ch = getc0()) != '\r') 
{ 
    route_buffer[index] = ch ; 
    index++ ; 
} 
route_buffer[index] = 0 ; 

我已经做了很多假设从原来的代码在这里,如route_buffer事实上是一个NUL结尾的字符串。那些是你的设计决定;他们可能会或可能不会是正确的或好的。

一个更好的解决方案是将接收到的字符放入来自UART Rx中断处理程序的环形缓冲区中,然后让读取函数从缓冲区中异步获取它们的数据。如有必要,您可以轻松实现阻塞,阻塞和超时访问。你甚至可以让ISR计算缓存的新行数,以便事先知道缓冲区中有多少行可用。缓冲也可以让你的代码不必担心及时服务UART以防止字符溢出和数据丢失。

如果您想要超时行为,则getc0()中的while循环和行输入循环都必须另外测试一些定时器源。

+0

嗨,谢谢你。自你发布这个版本以来,我做了大量修改。我甚至没有考虑缓冲区溢出的可能性......傻瓜。我想拿出一个笔记本,思考几分钟我想。感谢所有的细节 – Draineh 2011-03-10 21:24:57

+0

@Draineh,你的编辑显示'str'声明为'char *',但'getc0()'返回一个'int'。然后将'&str'(一个char **')传递给strcat()。提供的隐式转换不会神奇地使这段代码正确!你的编译器肯定不会产生警告!?它应该,如果不这样做,则将警告级别设置得更高。将警告视为错误(它们通常是错误的,并且始终表明错误或可疑代码),但不要试图通过类型转换解决所有警告;这并不能解决错误,而是告诉编译器不要告诉你这个问题。 – Clifford 2011-03-11 20:21:33

+0

关于为什么你使用strcat()的原因非常明智,请阅读[this](http://www.joelonsoftware.com) /articles/fog0000000319.html)。 – Clifford 2011-03-11 20:25:29