Call to _timer_start_periodic_at corrupts task descriptor list in kernel data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Call to _timer_start_periodic_at corrupts task descriptor list in kernel data

477 Views
hbouch
Contributor III

Hello all,

First, I'm using MQX 4.1 and CW 10.5.

I did a little application which has 3 tasks. One init task and two other tasks that I want to make cyclic. To do so, I create a periodic timer for each of my cyclic tasks and I pass the corresponding task descriptor pointer as timer callback function parameter. I did a test with one init and one cyclic task and it worked fine. Now with two tasks, it doesn't work at all, the task are not made ready by the timer callback function.

I tracked down the problem and I found out that when I call _timer_start_periodic_at() it create a timer task. In this creation of the task the function _task_alloc_td_internal() is called in file task.c. At line 3585 INSERT_TD_PTR pointer is copied into a local pointer (insert_td_ptr = kernel_data->INSERT_TD_PTR;). This line corrupts the TD_LIST in kernel data:

Before execution of line 3585 (TD_LIST is OK):

before.jpg

Before execution of line 3585 (TD_LIST is not OK):

after.jpg

I don't understand why this line does that because it should only modify a local variable. This variable is a pointer but the pointed value shouldn't be modified...

Here is a copy of my code in case you see something wrong:

TASK_TEMPLATE_STRUCT MQX_template_list[] =

{

/*  Task number,                        Entry point,       Stack,  Pri, String,          attr,                                       param,  time slice */

   {TASK_KU32_STARTUP,       TaskStartup,      100,    0,    "startup",      MQX_AUTO_START_TASK, 0,          0},

   {TASK_KU32_1MS_CYCLE,  Task1msCycle,  2000,  2,    "1 ms task",  0,                                          0,          0},

   {TASK_KU32_5MS_CYCLE,  Task5msCycle,  2000,  4,    "5 ms task",  0,                                          0,          0},

   {0,                                          0,                      0,        0,    0,                  0,                                          0,          0}

};

void TaskStartup(uint32_t u32Parameter)

{

    _task_id u32Task1msId;

    _task_id u32Task5msId;

    TIME_STRUCT stTimePtr;

    void * pvTaskDescriptor;

    /* To avoid unused parameter warning */

    u32Parameter = u32Parameter;

    /* Create tasks */

    u32Task1msId = _task_create_blocked(0U, TASK_KU32_1MS_CYCLE, 0U);

    u32Task5msId = _task_create_blocked(0U, TASK_KU32_5MS_CYCLE, 0U);

    /* If all tasks could be created */

    if(    (MQX_NULL_TASK_ID != u32Task1msId)

        && (MQX_NULL_TASK_ID != u32Task5msId) )

    {

        _time_get(&stTimePtr);              /* Get actual time */

        /**** Initialize periodic timers to make cyclic tasks ****/

        /*** 1 ms Task ***/

        pvTaskDescriptor = _task_get_td(u32Task1msId);

        (void)_timer_start_periodic_at(CallbackFct1msTimer, pvTaskDescriptor, TIMER_ELAPSED_TIME_MODE, &stTimePtr, (uint32_t)1);

        /*** 5 ms Task ***/

        pvTaskDescriptor = _task_get_td(u32Task5msId);

        (void)_timer_start_periodic_at(CallbackFct5msTimer, pvTaskDescriptor, TIMER_ELAPSED_TIME_MODE, &stTimePtr, (uint32_t)5);

    }

    /* Destroy task to avoid further call */

    _task_destroy(_task_get_id());

}

void Task1msCycle(uint32_t u32Parameter)

{

    /* To avoid unused parameter warning */

    u32Parameter = u32Parameter;

    while(1)

    {

        /* Do something */

        _task_block();

    }

}

void Task5msCycle(uint32_t u32Parameter)

{

    /* To avoid unused parameter warning */

    u32Parameter = u32Parameter;

    while(1)

    {

        /* Do something */

        _task_block();

    }

}

void CallbackFct1msTimer(_timer_id u32TimerId, void * pvTaskDescriptor, uint32_t u32Seconds, uint32_t u32MilliSeconds)

{

    /* To avoid unused parameter warnings */

    u32TimerId = u32TimerId;

    u32Seconds = u32Seconds;

    u32MilliSeconds = u32MilliSeconds;

    /* Set task ready cyclically when timer expires to make a cyclic task */

    _task_ready(pvTaskDescriptor);

}

void CallbackFct5msTimer(_timer_id u32TimerId, void * pvTaskDescriptor, uint32_t u32Seconds, uint32_t u32MilliSeconds)

{

    /* To avoid unused parameter warnings */

    u32TimerId = u32TimerId;

    u32Seconds = u32Seconds;

    u32MilliSeconds = u32MilliSeconds;

    /* Set task ready cyclically when timer expires to make a cyclic task */

    _task_ready(pvTaskDescriptor);

}

Does anyone have an idea of where the problem could come from?

Thanks

Hugo

0 Kudos
3 Replies

307 Views
hbouch
Contributor III

Seems that the small stack size of startup task is the problem. Works better with 1000 instead of 100.

Hugo

0 Kudos

307 Views
DavidS
NXP Employee
NXP Employee

Hi Hugo,

Try setting your task priorities to 8 and above.  MQX RTOS and Components use lower priority levels so your tasks might be affecting the RTOS operation.

Hope this helps.

Regards,

David

0 Kudos

307 Views
hbouch
Contributor III

Hi David,

I tried to change the task priorities but I still have the same problem...

Do you have another idea?

Thanks

Hugo

0 Kudos