2016-06-19 18 views
0

Ich arbeite tatsächlich an meinem Abschlussprojekt für den Abschluss. Ich verwende FreeRTOS bei der STM32F4-Erkennung. Es funktioniert alles einwandfrei, aber die Aufgaben sind nicht so geordnet, wie ich es mag. Sie führen in diesem Zyklus: task3 zweimal, task2 einmal, dann wieder task3 zweimal und tas2 einmal und dann task1 einmal. Ich möchte sie in dieser Reihenfolge ausführen: task1 dann task2 dann task3. Vielen Dank! HierRTOS STM32F4 Entdeckung

ist ein Teil meines Codes:

/* Die Periode des Beispiel Software-Timer in Millisekunden angegeben und umgewandelt Zecken des portTICK_RATE_MS Konstante verwendet. */

#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

Wenn alles richtig funktioniert, warum ist es dann wichtig, in welcher Reihenfolge die Aufgaben ausgeführt werden? – kkrambo

+0

die Wiederholung von einigen Aufgaben mehr als andere mich geärgert :) –

+0

Der ganze Sinn eines RTOS ist, dass die Planung ist völlig deterministisch. Wenn sie Aufgaben in einer Weise planen, die nicht erwartet wird, dann ist es eindeutig nicht "alles funktioniert ordnungsgemäß". Sie führen in der Weise aus, wie Sie sie codiert haben; Wenn es dich "ärgert", ist das eine gute Sache - du solltest dich über falschen Code ärgern. Etwas wie herkömmliche Codeformatierung und Einrückung könnte dazu beitragen, mehr Blick auf Ihren Code zu werfen - da werden Sie nur diejenigen ärgern, die anderenfalls helfen könnten. – Clifford

Antwort

2

Blick auf den Aufruf von vTaskDelay() in jeder Aufgabe Funktion. Eine Task verzögert sich um PERIOD, die nächste um PERIOD/2 und die dritte um PERIOD/4. Die Task, die sich um PERIOD/4 verzögert, kann vier Mal ausgeführt werden, wenn die Task, die für PERIOD verzögert wird, für die Ausführung bereit ist. Aus diesem Grund sehen Sie eine Aufgabe vier Mal, die nächsten zwei Mal und die dritte einmal. Warum haben Sie unterschiedliche Verzögerungszeiten verwendet, wenn Sie möchten, dass die Aufgaben mit derselben Geschwindigkeit ausgeführt werden?

Welche Aufgabe zuerst ausgeführt wird, hängt davon ab, wie der FreeRTOS-Scheduler implementiert ist. Sie haben jeder Task in den Aufrufen zu xTaskCreate() die gleiche Priorität (configMAX_PRIORITIES - 1) zugewiesen. Der FreeRTOS-Scheduler verwendet wahrscheinlich seinen Round-Robin-Scheduling-Algorithmus für Tasks mit derselben Priorität. Und ich schätze, dass der Scheduler die Aufgaben in der Reihenfolge vorbereitet, in der sie erstellt wurden (oder umgekehrt). Sie können also möglicherweise die Bereitschaftsreihenfolge beeinflussen, indem Sie die Erstellungsreihenfolge ändern. Aber ich rate nur und Sie sollten sich den Quellcode für den FreeRTOS-Scheduler ansehen, um zu erfahren, was er tut. Oder vielleicht sollten Sie den Aufgaben verschiedene Prioritäten geben. Dann sollte der FreeRTOS-Scheduler die Aufgabe mit der höchsten Priorität zuerst ausführen.

+0

Danke für deine Hilfe, es funktioniert jetzt perfekt :) –