RTOS STM32F4发现

时间:2016-06-19 16:09:54

标签: rtos freertos stm32f4discovery

我实际上正在为我的毕业项目而努力。我正在使用FreeRTOS进行STM32F4发现。一切正常,但任务没有按我喜欢的顺序排列。他们在这个循环中执行:task3两次,task2一次,然后再次task3两次,tas2一次,然后task1一次。 我希望他们按此顺序执行:task1然后task2然后task3。谢谢!

以下是我的代码的一部分:

/ *示例软件计时器的周期,以毫秒为单位,和 使用portTICK_RATE_MS常量转换为ticks。 * /

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

1 个答案:

答案 0 :(得分:2)

查看每个任务函数中对vTaskDelay()的调用。一项任务延迟PERIOD,下一项PERIOD/2,第三项PERIOD/4。每次延迟PERIOD/4的任务准备好运行时,PERIOD的延迟任务就可以运行四次。这就是为什么你看到一个任务运行四次,接下来的两次,第三次运行一次。如果您希望任务以相同的速率运行,为什么使用不同的延迟时间?

至于哪个任务在开始时首先运行,这取决于FreeRTOS调度程序的实现方式。您为configMAX_PRIORITIES - 1的调用中的每项任务分配了相同的优先级(xTaskCreate())。 FreeRTOS调度程序可能正在使用其循环调度算法来处理具有相同优先级的任务。而且我猜测调度程序按照创建顺序(或者可能是反向顺序)准备好任务。因此,您可以通过更改创建顺序来影响就绪订单。但我只是在猜测,您应该查看FreeRTOS调度程序的源代码,以了解它的作用。或许你应该给任务不同的优先级。然后,FreeRTOS调度程序应该使具有最高优先级的任务准备好先运行。