2016-06-19 318 views
0

我實際上正在研究畢業的最終項目。我在STM32F4發現上使用FreeRTOS。這一切正常工作,但任務不按我喜歡的順序。他們在這個循環中執行:task3兩次,task2一次,然後再task3兩次,tas2一次,然後task1一次。 我希望他們執行iin這個命令:task1然後task2然後task3。謝謝!實時操作系統STM32F4發現

這裏是我的代碼的一部分:

/*該示例中軟件定時器的週期,以毫秒爲單位指定,並且 轉化成蜱使用portTICK_RATE_MS恆定。 */

的#define mainSOFTWARE_TIMER_PERIOD_MS(1000/portTICK_RATE_MS)

int main(void) 
{ 


/* Configure the system ready to run the demo. The clock configuration 
can be done here if it was not done before main() was called. */ 
prvSetupHardware(); 

/* Create the queue used by the queue send and queue receive tasks. 
http://www.freertos.org/a00116.html */ 
xQueue = xQueueCreate( mainQUEUE_LENGTH,  /* The number of items the queue can hold. */ 
         sizeof(uint32_t)); /* The size of each item the queue holds. */ 
/* Add to the registry, for the benefit of kernel aware debugging. */ 
vQueueAddToRegistry(xQueue, (signed char *) "MainQueue"); 


/* Create the semaphore used by the FreeRTOS tick hook function and the 
event semaphore task. */ 
vSemaphoreCreateBinary(xEventSemaphore); 
/* Add to the registry, for the benefit of kernel aware debugging. */ 
vQueueAddToRegistry(xEventSemaphore, (signed char *) "xEventSemaphore"); 


/* Create the MPXV7002DP task */ 
xTaskCreate( vMPXV7002DPTask,    /* The function that implements the task. */ 
       (signed char *) "MPXV7002DP",   /* Text name for the task, just to help debugging. */ 
       configMINIMAL_STACK_SIZE,  /* The size (in words) of the stack that should be created for the task. */ 
       NULL,       /* A parameter that can be passed into the task. Not used in this simple demo. */ 
       configMAX_PRIORITIES - 1,  /* The priority to assign to the task. tskIDLE_PRIORITY (which is 0) is the lowest priority. configMAX_PRIORITIES - 1 is the highest priority. */ 
       NULL);       /* Used to obtain a handle to the created task. Not used in this simple demo, so set to NULL. */ 


/* Create the MPU9250 task */ 
xTaskCreate( vMPU9250Task, 
       (signed char *) "MPU9250", 
       configMINIMAL_STACK_SIZE, 
       NULL, 
       configMAX_PRIORITIES - 1, 
       NULL); 


/* Create the MPL3115A2 task */ 
xTaskCreate( vMPL3115A2Task, 
       (signed char *) "MPL3115A2", 
       configMINIMAL_STACK_SIZE, 
       NULL, 
       configMAX_PRIORITIES - 1, 
       NULL); 


/* Create the TOPC task */ 
    //xTaskCreate( vToPcTask, 
     //   (signed char *) "ToPc", 
      //  configMINIMAL_STACK_SIZE, 
       // NULL, 
        //configMAX_PRIORITIES - 4, 
        //NULL); 


/* Start the tasks and timer running. */ 
vTaskStartScheduler(); 
} 

static void vMPXV7002DPTask(void *pvParameters) 
{ 
    int convertedValue,pressure,v; 

for(;;) 
{ 
    if(xSemaphoreTake(xEventSemaphore, mainSOFTWARE_TIMER_PERIOD_MS)) 
    {USART_puts(USART1, "mpxv begin\n\r"); 
     ADC_SoftwareStartConv(ADC1);//Start the conversion 
     while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion 

     convertedValue = ADC_GetConversionValue(ADC1); //Return the converted dat 

     convertedValue=(5*convertedValue)/255; 
     pressure=(convertedValue+0.0625*4)-0.5; 
     v=sqrt((2*pressure)/1.293); 
     USART_puts(USART1, "mpxv end\n\r"); 
     xSemaphoreGive(xEventSemaphore); 
    } 
    vTaskDelay(mainSOFTWARE_TIMER_PERIOD_MS); 
} 
} 

static void vMPU9250Task(void *pvParameters) 
{ 
int16_t xa,ya,za,xg,yg,zg,xm,ym,zm; 
uint8_t res[22]; 

for(;;) 
{ 
    if(xSemaphoreTake(xEventSemaphore, mainSOFTWARE_TIMER_PERIOD_MS)) 
    {USART_puts(USART1, "mpu begin\n\r"); 
     SPI_Tx(0x25,0x0C|0x80);//read from slv0 
     SPI_Tx(0x26,0x03);//reg from which start reading 
     SPI_Tx(0x27,0x87);//read 7 bytes 

     SPI_Rx_seq(0x3A,res,22); 

     xa=((int16_t)res[1]<<8)|res[2]; 
     xa/=8192; 
     ya=((int16_t)res[3]<<8)|res[4]; 
     ya/=8192; 
     za=((int16_t)res[5]<<8)|res[6]; 
     za/=8192; 

     xg=((int16_t)res[9]<<8)|res[10]; 
     xg/=131; 
     yg=((int16_t)res[11]<<8)|res[12]; 
     yg/=131; 
     zg=((int16_t)res[13]<<8)|res[14]; 
     zg/=131; 

     //AK8963_Rx_seq(0x03, mag_asax, 7); 
     //SPI_Rx_seq(0x49,mag_asax,7); 

     xm=((int16_t)res[16]<<8)|res[15]; 
     ym=((int16_t)res[18]<<8)|res[17]; 
     zm=((int16_t)res[20]<<8)|res[19]; 

     USART_puts(USART1, "mpu end\n\r"); 

     xSemaphoreGive(xEventSemaphore); 
    } 
    vTaskDelay(mainSOFTWARE_TIMER_PERIOD_MS/2); 
} 
} 

static void vMPL3115A2Task(void *pvParameters) 
{ 
uint8_t altitude[3]; 
uint32_t x; 
char alt[1]; 

for(;;) 
{ 
    if(xSemaphoreTake(xEventSemaphore, mainSOFTWARE_TIMER_PERIOD_MS)) 
    {USART_puts(USART1, "mpl begin\n\r"); 
     Read_IIC1_seq(0x60<<1, 0x01, altitude, 3); 

     x=altitude[0];x<<=8; 
     x|=altitude[1];x<<=8; 
     x|=altitude[2];x>>=4; 

     x/=49920; 
     USART_puts(USART1, "mpl end\n\r"); 
     xSemaphoreGive(xEventSemaphore); 
    } 
    vTaskDelay(mainSOFTWARE_TIMER_PERIOD_MS/4); 
} 
} 
+0

如果一切正常,爲什麼它關係到任務運行的順序? – kkrambo

+0

某些任務的重複比其他人更讓我煩惱:) –

+0

RTOS的全部內容是調度完全是確定性的。如果他們的任務按照預料不到的方式進行調度,那麼顯然不是「所有工作都正常」。他們以你編碼的方式執行;如果它「惹惱了你」,那是件好事 - 你應該被不正確的代碼激怒。類似於傳統的代碼格式和縮進可能有助於更多地關注代碼 - 因爲它只是會讓那些本來可以提供幫助的人惱火。 – Clifford

回答

2

看在每一個任務函數調用vTaskDelay()。一項任務推遲PERIOD,下一項爲PERIOD/2,第三項爲PERIOD/4。延遲PERIOD/4的任務將準備好每次運行四次,延遲執行PERIOD的任務將準備運行。這就是爲什麼你看到一個任務運行四次,接下來兩次,第三次運行。如果您希望任務以相同的速率運行,爲什麼使用不同的延遲時間?

至於哪個任務在開始時首先運行,這取決於FreeRTOS調度程序的實現方式。您在xTaskCreate()的調用中爲每個任務分配了相同的優先級(configMAX_PRIORITIES - 1)。 FreeRTOS調度程序可能使用其循環調度算法來處理具有相同優先級的任務。我猜測調度器按照它們創建的順序來準備任務(或者可能是逆序)。因此,您可以通過更改創建順序來影響就緒順序。但我只是猜測,你應該看看FreeRTOS調度程序的源代碼,以瞭解它的功能。或者,也許你應該給任務不同的優先級。然後,FreeRTOS調度程序應該使具有最高優先級的任務準備好首先運行。

+0

謝謝你的幫助,它現在完美:) –