How to "simulate" processing time consuming tasks for FreeRTOS aimed to discuss real-time system topics using Linux simulator

Viewed 97

I'm trying to use FreeRTOS to discuss real time concepts with students, using the POSIX-Linux simulator framework. To accomplish this, I have to find a way of wasting processing time in a controlled way (simulating task in "Running" status by a predetermined period of processing time).

Delays are not good because they change the task status to "Block" and, with a preemptive scheduler, it means the scheduler can give the processor to other tasks. Using Linux native time control approaches (e.g. using clock_gettime() to build the logic) are not good because I don't have the control of the exact running time of a single task, specially with preemptiveness. Regular iterations (for, while) don't have the control I need for processing time (my computer and students computers will have different processing times depending on their architectures).

During my researches on FreeRTOS documentation, I found both the TaskStatus_t struct and the vTaskGetInfo() function which were supposed to help me out. And my problem is when I implement something like:

// Creating the task
if (xTaskCreate( 
    app_task,   
    task1_info.name,                            
    configMINIMAL_STACK_SIZE,       
    (void *) &task1_info,                           
    task1_info.priority,
    NULL 
) != pdPASS) printf("Task create error %s\n", task1_info.name);
// ...
starting_time_ticks = xTaskGetTickCount(); // starting time in ticks
vTaskStartScheduler();
// ...

static void app_task( void *pvParameters )
// The task itself
{ // ...
    for( ;; )
    { // ...
        app_proc_ticks( 
            pdMS_TO_TICKS( task_info.proc_time_ms ), 
            task_info.name
        ); // consuming processing time...
    // ... }
// ... }

static void app_proc_ticks( TickType_t proc_time_ticks,  uint8_t name[APP_MAX_MSG_SIZE])
// Consuming the number of ticks in order to attain a certain processing time
{
    TaskHandle_t xHandle;
    TaskStatus_t xTaskDetails;
    xHandle = xTaskGetHandle( name );
    configASSERT( xHandle );
    vTaskGetInfo( xHandle, &xTaskDetails, pdTRUE, eInvalid );
    TickType_t begin = xTaskDetails.ulRunTimeCounter;
    while((xTaskDetails.ulRunTimeCounter - begin) < proc_time_ticks)
    {
        vTaskGetInfo( xHandle, &xTaskDetails, pdTRUE, eInvalid );
    }
}

For a task_info.proc_time_ms equal to 25 ms, my code shows up as the task is consuming around 250 ms worth of ticks, a error factor of 10x. The way I count this is with the following "timestamp" strategy:

static TickType_t get_timestamp_ticks() {
    return xTaskGetTickCount() - starting_time_ticks;
}

As far as I can see, I'm having problems to understand and properly convert xTaskDetails.ulRunTimeCounter time unit (ticks, ms, or probably something else). Also probably some tick to ms constant I'm not aware of. Right now, to convert from "ms" to "ticks" I'm using pdMS_TO_TICKS() macro and to convert from "ticks" to "ms" I'm multiplying the number of ticks by portTICK_RATE_MS.

Also, after make, I'm using taskset -c 0 ./build/posix_demo to run and ensure the use of a single processor by my executable.

I'm not trying to hold on to this solution, though. If anyone could share how to do a time controlled delay with "real consumption of processing time" for tasks in FreeRTOS, I would appreciate it as well.

0 Answers
Related