實時控制軟件第二次作業
阿新 • • 發佈:2017-09-30
creat chmod continue tgz clip ask path 文件 literal
0. Fork例程到自己的GitHub賬號:
開發環境搭建
1. QEMU安裝
建議使用qemu-system-gnuarmeclipse,該qemu分支對stm32f4有更好的支持,主要面向Eclipse開發環境。
-
到網頁 https://github.com/gnu-mcu-eclipse/qemu/releases/tag/gae-2.8.0-20161227 下載二進制文件 gnuarmeclipse-qemu-debian64-2.8.0-201612271623-dev.tgz到~/work目錄
-
在工作目錄解壓縮文件,並把路徑添加到$PATH變量中
#cd ~/work #tar xvf gnuarmeclipse-qemu-debian64-2.8.0-201612271623-dev.tgz #chmod -R -w ./qemu export PATH=~/work/qemu/2.8.0-201612271623-dev/bin/:$PATH
- 測試qemu能否正常運行
#qemu-system-gnuarmeclipse --version
顯示版本信息為2.8.0,正常。
2. 編譯例程
- 在/Projects/Demo1目錄下運行make,生成hello_rtos.elf文件
說明:qemu-system-gnuarmeclipse當前版本不支持STM32F4的浮點,相應的,FreeRTOS使用的portable目錄沒有使用ARM_CM4F而是使用ARM_CM3。
3. QEMU仿真
在Demo1目錄下運行腳本文件:
#./qemu.sh
4. GDB調試
在/Projects/Demo1目錄下運行qemu_gdb腳本文件,該文件中添加了--gdb tcp::1234 -S
qemu啟動後等待來自gdb的調試指令,打開另外一個終端窗口,運行
#arm-none-eabi-gdb
在gdb界面內運行:
(gdb)target remote localhost:1234
(gdb)continue
5. 編程作業具體要求:
- 創建三個任務:Sender_Task,Receiver_Task, Monitor_Task
- Sender_Task的任務執行周期為2ms,Receiver_Task的任務執行周期為1000ms, Monitor_Task的任務執行周期為10000ms。
- Sender_Task在每個執行周期向Receiver_Task發送一個32位無符號整數,第一次發送1,然後依次發送2,3,4......,發送完10000後再從1開始發送。同時對發送的數據進行計算累加計算並保存當前累加結果。
- Receiver_Task對接收到的數據進行和Sender_Task同樣的累加計算並保存當前累加結果。
- Monitor_Task在每個執行周期檢查Sender_Task發送的每個數據是否都被Receiver_Task正確的接收和處理,請自行設計一種檢查機制並實現。
- 可利用STM32F429I Discovery開發板的相關硬件(LED/LCD/串口)來輸出相關狀態信息。
- 使用FreeRTOS的任務間通信和同步API完成上述功能。
1.main函數
int main(void)
{
MsgQueue=xQueueCreate(30000,sizeof(uint32_t));
xTaskCreate(
Sender_Task,
"Sender_Task",
configMINIMAL_STACK_SIZE,
(void*) NULL,
tskIDLE_PRIORITY+4UL,
NULL
);
xTaskCreate(
Receiver_Task,
"Receiver_Task",
configMINIMAL_STACK_SIZE,
(void*) NULL,
tskIDLE_PRIORITY+3UL,
NULL
);
xTaskCreate(
Monitor_Task,
"Monitor_Task",
configMINIMAL_STACK_SIZE,
(void*) NULL,
tskIDLE_PRIORITY+2UL,
NULL
);
vTaskStartScheduler();
for( ;; );
2.Sender_Task
void Sender_Task(void *pvParameters)
{
uint32_t Sendnum=1;
while(1)
{
xQueueSend(MsgQueue,(void* )&Sendnum,0);
Sendsum=Sendsum+Sendnum;
Sendnum++;
if(Sendnum==10000)
{
uint32_t Sendnum=1;
}
vTaskDelay(2);
}
}
3.Receiver_Task
void Receiver_Task(void *pvParameters)
{
uint32_t Receivernum=0;
while(1)
{
while(xQueueReceive(MsgQueue,&Receivernum,
0/portTICK_RATE_MS) == pdTRUE)
{
Receiversum=Receiversum+Receivernum;
}
vTaskDelay(1000);
}
}
4.Monitor_Task
void Monitor_Task(void)
{
while(1)
{
if(Receiversum == Sendsum)
{
Green_LED_On();
vTaskDelay(1000/ portTICK_RATE_MS);
Green_LED_Off();
}
else
{
Red_LED_On();
vTaskDelay(1000/ portTICK_RATE_MS);
Red_LED_Off();
}
vTaskDelay(10000);
}
}
實時控制軟件第二次作業