1. 程式人生 > >實時控制軟件第二次作業

實時控制軟件第二次作業

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);
           }
    }

實時控制軟件第二次作業