作者:Adam Taylor
在上一篇博客中成功地演示了FreeRTOS并在基于Zynq的MicroZed板上运行之后,显然我们想要能够编写我们自己的应用程序。因此,我们将首先举一个简单的例子。我们将配置Zynq SoC的XADC并且在串行链路上输出结果。应用程序检查接收到的值,如果这个值超过预设值,代码就会点亮LED作为警报。在之后的博客中,这个例子会指引我们观察我们如何在任务间交流信息,发送更复杂的应用。
代码开发的第一步就是创建一个函数,在我们启动RTOS 调度程序前用来初始化XADC。这将允许我们在这个例子里运行的两个任务之一中使用XADC。这个函数会是一个标准函数,正如我们在这个系列中之前创建了许多次一样。
这个例子使用了两个任务。第一个任务是读取XADC温度,将获得的值添加到队列里。第二个任务是从队列里读取值并执行温度检验。在这个应用程序里,第二个任务也会在串行链路上输出数据,这样我们就可以看到发生的情况。这两个任务展示了我们怎样在Zynq SoC中在硬件外设之间通信,使用一个任务从硬件获得值,然后在第二个任务里使用这些获得的值。任务间通信是嵌入式系统中使用RTOS的重要方面。
带来的两个例子中非常有帮助的FreeRTOS演示代码:完整演示和更简单的闪烁演示。闪烁LED演示是通过在main.c里设置预处理器声明来控制的:
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
设置这个标志位并重建应用程序得到一个简单的例子——MicroZed板载LED闪烁。通过在两个任务之间以预定义的速率并使用队列来传递数据。这个代码正好能够达到我们需要的目的,所以这个简单的演示带给我们想要开发的应用代码的有用启示。
正如上面提到的,我们首先要创建的事情是一个配置例程,用于初始化Zynq SoC的XADC,使其可用。记住要添加需要的包含文件和访问Zynq SoC的XADC必要的声明。我们在这篇博客里做了很多次,所以这对你来说已经很习惯了。
下一步就是修改传输任务,读取XADC温度,将得到的值放在队列里,供接收进程读取。实现这个的代码如下:
static void prvQueueSendTask( void *pvParameters )
{
TickType_t xNextWakeTime;
unsigned long ulValueToSend = 100UL;
( void ) pvParameters;
xNextWakeTime = xTaskGetTickCount();
printf("task tx");
for( ;; )
{
vTaskDelayUntil( xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
ulValueToSend = XAdcPs_GetAdcData(XADCInst, XADCPS_CH_TEMP);
xQueueSend( xQueue, ulValueToSend, 0U );
}
接收进程从队列中取出这个值。然后我们将接收到的值与期望值做比较,当接收到的值大于期望值时切换LED。
static void prvQueueReceiveTask( void *pvParameters )
{
unsigned long ulReceivedValue;
unsigned long ulExpectedValue = 43000;
( void ) pvParameters;
printf("task rx");
for( ;; )
{
xQueueReceive( xQueue, ulReceivedValue, portMAX_DELAY );
printf("Raw Value = %lu", ulReceivedValue);
if( ulReceivedValue == ulExpectedValue )
{
vParTestToggleLED( mainTASK_LED );
ulReceivedValue = 0U;
}
}
}
从上面的代码可以看出,这个简单的应用就是当温度超过警戒值时,LED点亮。但是,在很多情况下会导致LED不断闪烁,因为边界温度值会快速地在高于和低于阈值之间摆动。我们通过引入滞后现象来解决这个问题,这样LED只会在温度充分下降且停止波动时才会熄灭。
原文链接:
http://forums.xilinx.com/t5/Xcell-Daily-Blog/Adam-Taylor-s-MicroZed-Chro...
© Copyright 2014 Xilinx Inc.
如需转载,请注明出处