2011-03-10 90 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