一、开发环境搭建:
1、Fork例程项目
在github上,Fork例程项目(https://github.com/cbhust/STM32F429_Discovery_FreeRTOS_9.git) 到自己的个人账号。
2、Qemu安装
到网页 https://github.com/gnu-mcu-eclipse/qemu/releases/tag/gae-2.8.0-20161227 下载二进制文件 gnuarmeclipse-qemu-debian64-2.8.0-201612271623-dev.tgz到~/work目录
3、在工作目录解压缩文件,并把路径添加到$PATH变量中
#tar xvf gnuarmeclipse-qemu-debian64-2.8.0-201612271623-dev.tgz
#chmod -R -w ./qemu
4、测试qemu能否正常运行
#qemu-system-gnuarmeclipse --version
显示版本为2.8.0 故可以正常运行
5、编译例程:在/Projects/Demo1目录下运行make,生成hello_rtos.elf文件
6、QEMU仿真
在/Projects/Demo1目录下提供了一个qemu.sh脚本文件,内容如下
#!/bin/bash
qemu-system-gnuarmeclipse --verbose --verbose --board STM32F429I-Discovery --mcu STM32F429ZI -d unimp,guest_errors --image hello_rtos.elf --semihosting-config enable
在Demo1目录下运行脚本文件:
#./qemu.sh
7.GDB调试
在/Projects/Demo1目录下运行qemu_gdb脚本文件,该文件中添加了--gdb tcp::1234 -S
qemu启动后等待来自gdb的调试指令,打开另外一个终端窗口,运行
#arm-none-eabi-gdb
在gdb界面内运行:
(gdb)target remote localhost:1234
(gdb)continue
有红绿灯闪烁的现象(由于无法截动图所以简单表示了)
二、编程部分
(git clone https://github.com/zss1995/STM32F429_Discovery_FreeRTOS_9)
1、首先,要在一开始添加上 "queue.h"头文件,然后创建队列句柄,创建全局变量。
xQueueHandle MsgQueue;
unsigned long SendNum;
unsigned long SendSum = 0;
unsigned long ReceiveSum = 0;
2、创建三个任务:Sender_Task,Receiver_Task, Monitor_Task
Send _Task
/**
* Sender_Task: Send a number every 2 ms.
*/
void Sender_Task(void *pvParameters)
{
SendNum=0;
while (1)
{
SendNum++;
if(SendNum > 10000)
{
SendNum=1;
}
xQueueSend(MsgQueue,(void*)&SendNum,0);
SendSum = SendNum + SendSum;
vTaskDelay(2);
}
}
Reciever_Task
/**
* Receive_Task: Receive numbers every 1000 ms.
*/
void Receiver_Task(void *pvParameters)
{
unsigned long ReceiveNum;
while(1)
{
while(xQueueReceive(MsgQueue,&ReceiveNum,0/portTICK_RATE_MS ) == pdTRUE )
{
ReceiveSum = ReceiveNum + ReceiveSum;
}
vTaskDelay(1000);
}
}
Monitor_Task
/**
* Monitor_Task:
*/
void Monitor_Task(void *pvParameters)
{
while(1)
{
if(ReceiveSum==SendSum)
{ Green_LED_On();
Red_LED_Off();}
else
{Green_LED_Off();
Red_LED_On();}
vTaskDelay(1000);
}
}
3、主函数 (使Sender的优先级最高,Receiver其次,Monitor最低)
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
Hardware_Init();
/* Init and start tracing*/
vTraceEnable(TRC_INIT);
vTraceEnable(TRC_START);
MsgQueue=xQueueCreate(10000,sizeof(unsigned long)); /*The depth of Queue=10000*/
/* Create tasks */
xTaskCreate(
Sender_Task, /* Function pointer */
"Task_Sender", /* Task name - for debugging only*/
configMINIMAL_STACK_SIZE, /* Stack depth in words */
(void*) NULL, /* Pointer to tasks arguments (parameter) */
tskIDLE_PRIORITY+4UL, /* Task priority zuigaoyouxianji*/
NULL /* Task handle */
);
xTaskCreate(
Receiver_Task, /* Function pointer */
"Task_Receiver", /* Task name - for debugging only*/
configMINIMAL_STACK_SIZE, /* Stack depth in words */
(void*) NULL, /* Pointer to tasks arguments (parameter) */
tskIDLE_PRIORITY + 3UL, /* Task priority*/
NULL /* Task handle */
);
xTaskCreate(
Monitor_Task, /* Function pointer */
"Task_Monitor", /* Task name - for debugging only*/
configMINIMAL_STACK_SIZE, /* Stack depth in words */
(void*) NULL, /* Pointer to tasks arguments (parameter) */
tskIDLE_PRIORITY + 2UL, /* Task priority*/
NULL /* Task handle */
);
/* Start the scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following line
will never be reached. If the following line does execute, then there was
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
to be created. See the memory management section on the FreeRTOS web site
for more details. */
for( ;; );
}
4、运行结果
一直亮绿灯,表示正确