24小(xiǎo)时联系電(diàn)话:18217114652、13661815404
中文(wén)
- 您当前的位置:
- 首页>
- 電(diàn)子资讯>
- 行业资讯>
- 带外部RAM的AVR上的Fr...
行业资讯
带外部RAM的AVR上的FreeRTOS
由于片内RAM较低,因此AVR微控制器不是运行FreeRTOS调度程序的最佳选择。Atmega128仅具有(yǒu)4K RAM,因此这将FreeRTOS功能(néng)限制為(wèi)非常基本的功能(néng)。无论如何,可(kě)以通过添加可(kě)能(néng)连接到外部存储器接口的额外RAM来解决此问题。以前我们已经构建了8K的外部存储块,所以现在我们可(kě)以使用(yòng)FreeRTOS应用(yòng)程序对其进行测试。
让我们继续前面的代码,该代码运行一些简单的任務(wù)(按钮状态读取,LCD输出和LED闪光灯),并且我们可(kě)以添加更多(duō)内容。我们将建立一个用(yòng)于存储堆的外部RAM。这将允许存储大型数据缓冲區(qū),而不必过多(duō)担心堆和栈的重叠。
首先,我们需要注意链接器选项。在AVRStudio5项目属性中,AVR / GNU C链接器->其他(tā)输入链接器选项:
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;">-Wl,-defsym = __ heap_start = 0x801100,-defsym = __ heap_end = 0x8030ff</font></font>
这将指示链接器仅将0x801100到0x8030ff(整个外部RAM)的内存區(qū)域用(yòng)于堆。
第二步是设置微控制器以使用(yòng)外部存储器。為(wèi)了使内容整洁和模块化,我们将创建单独的驱动程序源文(wén)件xmem.c和xmem.h。并编写简单的XMEM_init()函数:
<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>
}
在主例程的开头,我们简单地调用(yòng)此函数以在使用(yòng)外部RAM之前对其进行初始化。
编写USART驱动程序
我们将需要USART功能(néng),以方便的方式调试和显示信息。因此,首先,我们需要可(kě)以在任務(wù)中使用(yòng)的驱动程序。使用(yòng)USART的最方便的方法可(kě)能(néng)是通过队列发送消息。这样,任何任務(wù)都可(kě)以通过使用(yòng)消息传递服務(wù)而不是直接访问外围设备来与USART通信。因此,我们将实现两个队列–一个用(yòng)于TX,另一个用(yòng)于RX通道。
//receive and transmit queues<font></font>
<font></font>
xQueueHandlexRxedChars=NULL;<font></font>
<font></font>
xQueueHandlexCharsForTx=NULL;
然后在USART初始化期间,我们创建队列。
xRxedChars=xQueueCreate(uxQueueLength,(signedchar)sizeof(signedchar));<font></font>
<font></font>
xCharsForTx=xQueueCreate(uxQueueLength,(signedchar)sizeof(signedchar));
队列長(cháng)度是在初始化USART时给出的(在我们的示例中為(wèi)30)。现在,当队列准备就绪时,就可(kě)以使用(yòng)它们与USART通信。通过两个自定义函数放置和读取发送到队列的消息,这使生活更轻松:
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>
}
当接收器队列中没有(yǒu)字符且发送队列已满时,这些功能(néng)可(kě)提供额外的安全性。您可(kě)能(néng)会注意到,在xUSART0PutChar()中调用(yòng)了一个私有(yǒu)函数prvUDRIE0InterruptOn()。一旦发送队列中至少有(yǒu)一个字符,这将启用(yòng)USART数据就绪中断。
通过中断例程执行USART发送和接收。