24小時聯(lián)系電話:18217114652、13661815404
中文
行業(yè)資訊
帶外部RAM的AVR上的FreeRTOS
由于片內(nèi)RAM較低,因此AVR微控制器不是運行FreeRTOS調(diào)度程序的最佳選擇。Atmega128僅具有4K RAM,因此這將FreeRTOS功能限制為非常基本的功能。無論如何,可以通過添加可能連接到外部存儲器接口的額外RAM來解決此問題。以前我們已經(jīng)構(gòu)建了8K的外部存儲塊,所以現(xiàn)在我們可以使用FreeRTOS應用程序?qū)ζ溥M行測試。
讓我們繼續(xù)前面的代碼,該代碼運行一些簡單的任務(按鈕狀態(tài)讀取,LCD輸出和LED閃光燈),并且我們可以添加更多內(nèi)容。我們將建立一個用于存儲堆的外部RAM。這將允許存儲大型數(shù)據(jù)緩沖區(qū),而不必過多擔心堆和棧的重疊。
首先,我們需要注意鏈接器選項。在AVRStudio5項目屬性中,AVR / GNU C鏈接器->其他輸入鏈接器選項:
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">-Wl,-defsym = __ heap_start = 0x801100,-defsym = __ heap_end = 0x8030ff</font></font>
這將指示鏈接器僅將0x801100到0x8030ff(整個外部RAM)的內(nèi)存區(qū)域用于堆。
第二步是設置微控制器以使用外部存儲器。為了使內(nèi)容整潔和模塊化,我們將創(chuàng)建單獨的驅(qū)動程序源文件xmem.c和xmem.h。并編寫簡單的XMEM_init()函數(shù):
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">無效vXMEMInit(void)</font></font><font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
{</font></font><font></font>
MCUCR |= (1<<SRE); /* External memory interface enable */<font></font>
XMCRA = 0;<font></font>
XMCRB |= (1<<XMM1)|(1<<XMM0);//PC7..PC5 released pins<font></font>
}
在主例程的開頭,我們簡單地調(diào)用此函數(shù)以在使用外部RAM之前對其進行初始化。
編寫USART驅(qū)動程序
我們將需要USART功能,以方便的方式調(diào)試和顯示信息。因此,首先,我們需要可以在任務中使用的驅(qū)動程序。使用USART的最方便的方法可能是通過隊列發(fā)送消息。這樣,任何任務都可以通過使用消息傳遞服務而不是直接訪問外圍設備來與USART通信。因此,我們將實現(xiàn)兩個隊列–一個用于TX,另一個用于RX通道。
//receive and transmit queues<font></font>
<font></font>
xQueueHandlexRxedChars=NULL;<font></font>
<font></font>
xQueueHandlexCharsForTx=NULL;
然后在USART初始化期間,我們創(chuàng)建隊列。
xRxedChars=xQueueCreate(uxQueueLength,(signedchar)sizeof(signedchar));<font></font>
<font></font>
xCharsForTx=xQueueCreate(uxQueueLength,(signedchar)sizeof(signedchar));
隊列長度是在初始化USART時給出的(在我們的示例中為30)。現(xiàn)在,當隊列準備就緒時,就可以使用它們與USART通信。通過兩個自定義函數(shù)放置和讀取發(fā)送到隊列的消息,這使生活更輕松:
portBASE_TYPE xUSART0PutChar(unsigned char cOutChar)<font></font>
{<font></font>
//Return false if after the block time there is no room on the Tx queue.<font></font>
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )<font></font>
{<font></font>
return pdFAIL;<font></font>
}<font></font>
//enable usart UDRE interrupt to transmit<font></font>
prvUDRIE0InterruptOn();<font></font>
return pdPASS;<font></font>
}<font></font>
portBASE_TYPE xUSART0GetChar(unsigned char *pcRxedChar)<font></font>
{<font></font>
/* Get the next character from the buffer. Return false if no characters<font></font>
are available, or arrive before xBlockTime expires. */<font></font>
if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )<font></font>
{<font></font>
return pdTRUE;<font></font>
}<font></font>
else<font></font>
{<font></font>
return pdFALSE;<font></font>
}<font></font>
}
當接收器隊列中沒有字符且發(fā)送隊列已滿時,這些功能可提供額外的安全性。您可能會注意到,在xUSART0PutChar()中調(diào)用了一個私有函數(shù)prvUDRIE0InterruptOn()。一旦發(fā)送隊列中至少有一個字符,這將啟用USART數(shù)據(jù)就緒中斷。
通過中斷例程執(zhí)行USART發(fā)送和接收。