2008-12-11 44 views
6

我有一個微控制器必須從PC串行端口(115200波特)下載一個大文件,並通過SPI(〜2 MHz)將其寫入串行閃存。閃存寫入必須在256字節塊之後,寫入命令和頁面地址。系統上可用的RAM總量爲1 kB,堆棧大小爲80字節。如何在內存受限的嵌入式系統上處理大數據傳輸?

目前,這是通過從UART填充256字節的緩衝區,然後ping到另一個256字節的緩衝區,通過接收緩衝區就緒信號上的中斷來填充,同時在寫入忙時寫入閃存。重複緩衝區交換直到操作完成。

我寧願設置TX/RX中斷兩種,關於單獨的循環緩衝區操作SPI和UART接口處理器。因此,不用輪詢新字節並等待操作完成,我可以簡單地填充TX緩衝區並啓用中斷或檢查緩衝區中的傳入數據。這會給實際工作帶來更多的時鐘週期,而不是等待外設。

實施IRQ與128字節循環緩衝區後,我輪詢數據的UART接收緩衝區,並立即將其置於SPI TX緩衝區做文件傳輸。我用這種方法遇到的問題是,我沒有足夠的RAM用於緩衝區,並且PC接收緩衝區的填充速度比我將數據傳送到閃存發送緩衝區的速度要快。很顯然,傳輸速度不是問題(115.2 kHz輸入和2 MHz輸出),但是在每個256字節頁面發送後都有一個寫週期等待。


看來頻繁的SPI中斷阻塞了一些UART中斷並導致字節被漏掉。我選擇的解決方案是爲UART接收中斷使用環形緩衝區,並將數據送入256字節的頁面緩衝區,通過輪詢字節傳輸和寫入完成,發送到串行閃存。 128個環形緩衝區足夠大以防止SPI寫入期間發生溢出。

回答

3

我會在PC上做一些分散收集。創建一個結構的鏈表是這樣的:

typedef struct data_buffer { 
    char flags; 
    char[128] data; 
} 

已在標誌中的一個比特表示「ReadyToFlash」和一個「閃爍」。您應該能夠調整鏈接列表中的緩衝區數量,以防止Flash在寫入時捕捉UART,反之亦然。

如果閃存進入不是「ReadyToFlash」的緩衝塊,它會停頓,你需要讓你的UART IRQ啓動備份。如果UART進入「ReadyToFlash」或「閃爍」模塊,則其填充速度過快,並且您可能需要另一個緩衝區,如果您有動態內存,則可以在運行時進行此調整,並在列表中隨時添加緩衝區,否則你只需要做一些實證測試。

4

是否UART和應用支持RS-232握手(流量控制)的PC側?如果是這樣,當你的接收緩衝器接近滿時,讓ISR丟棄CTS線 - 如果PC端配置爲遵守硬件流量控制,它應該在發現這種情況時停止發送。一旦你的接收緩衝器已經耗盡(或接近耗盡),再次斷言CTS並且PC應該再次開始發送。

注意,這使得嵌入式設備上的軟件複雜得多 - 這是否是一個折衷你願意做就必須通過分析你和你的經理&團隊來完成。

+0

這實際上是通過USB接口發生的,這些信號不可用。不過這是個好建議。 – 2008-12-11 15:57:36

4

這正是流量控制是爲,我知道它的一個巨大的痛苦成立創建的,但如果你的串行線路配置流量控制你的問題將成爲歷史。

我假設你正在傳輸二進制文件,以便XON-XOFF是不是最好的解決方案,這讓硬件流控制。

另一種選擇是使用一個協議與內置的流量控制如XModem協議。我有一個類似的嵌入式項目,其中閃存是用128字節的頁面編寫的。 XModem以128byte的塊發送數據是一個巧合,然後在發送下一個ACK之前等待ACK。

+0

我在過去使用過XModem,並有代碼爲它鋪設。但是,我正在簽訂合同,無法更改PC客戶端(它只是一次發送整個文件)。 – 2008-12-11 15:56:57

1

不知道我在這裏錯過了什麼,但如果事實是來自PC的平均數據速率高於平均速率,您可以將其寫入閃存,那麼您要麼需要很多內存,或者你將需要流量控制。

但是你是否說它在你有塊緩衝區的情況下工作,但是現在你有字節緩衝區了嗎?

您是否可以堅持由UART RX中斷填充的塊緩衝區,並且當每個緩衝區滿時,將其交給SPI/Flash代碼以使用SPI中斷清空該緩衝區?這將節省您複製每個字節,而不必爲每個字節執行兩次循環緩衝區邏輯,您只需爲每個塊執行一次。

+0

傳輸後寫頁面的等待週期是瓶頸。我在這個問題上添加了這些信息。 – 2008-12-11 16:12:21

+0

我可以讓它與UART上的128字節循環緩衝區和256字節中間緩衝區一起工作,並且忙於向SPI寫/輪詢。沒有256中介的128字節緩衝區不起作用。 – 2008-12-11 16:13:54

相關問題