stm32 freeRTOS软件定时器中的回调参数

Callback parameter in stm32 freeRTOS software timer

我正在尝试将软件计时器与 freeRTOS 的 cubeMx 集成一起使用(基本上,它是 freeRTOS,上面有一个几乎透明的层)。 我想我可以将一个指向结构的指针作为计时器参数传递,并将其作为回调函数中的参数获取。像这样:

typedef struct{
    uint8_t a;
    uint8_t b;
    uint8_t c;
}T;

T t = {1, 2, 3};

osTimerDef(myTimer01, Callback01);
myTimer01Handle = osTimerCreate(osTimer(myTimer01), osTimerPeriodic, (void*) &t);
osTimerStart(myTimer01Handle, 5000);

回调:

void Callback01(void const * argument)
{
    T* a = argument;
}

不幸的是,参数未指向与 &t 相同的地址。当我查看 freeRTOS 代码时,似乎 lib 将结构 "Timer_t" 转换为 void* 传递给回调函数(请参阅下面代码的结尾):

static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )
{
BaseType_t xResult;
Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );

    /* Remove the timer from the list of active timers.  A check has already
    been performed to ensure the list is not empty. */
    ( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
    traceTIMER_EXPIRED( pxTimer );

    /* If the timer is an auto reload timer then calculate the next
    expiry time and re-insert the timer in the list of active timers. */
    if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )
    {
        /* The timer is inserted into a list using a time relative to anything
        other than the current time.  It will therefore be inserted into the
        correct list relative to the time this task thinks it is now. */
        if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )
        {
            /* The timer expired before it was added to the active timer
            list.  Reload it now.  */
            xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );
            configASSERT( xResult );
            ( void ) xResult;
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }
    }
    else
    {
        mtCOVERAGE_TEST_MARKER();
    }

    /* Call the timer callback. */
    pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );
}

结构是:

typedef struct tmrTimerControl
{
    const char              *pcTimerName;       /*<< Text name.  This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
    ListItem_t              xTimerListItem;     /*<< Standard linked list item as used by all kernel features for event management. */
    TickType_t              xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
    UBaseType_t             uxAutoReload;       /*<< Set to pdTRUE if the timer should be automatically restarted once expired.  Set to pdFALSE if the timer is, in effect, a one-shot timer. */
    void                    *pvTimerID;         /*<< An ID to identify the timer.  This allows the timer to be identified when the same callback is used for multiple timers. */
    TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
} xTIMER;

typedef xTIMER Timer_t;

这个结构包含我在创建定时器时传递的数据指针。它存储在 pvTimerId.

这意味着我应该将回调参数转换为 Timer_t 以便访问 pvTimerId。像这样:

void Callback01(void const * argument)
{
    T* a =((Timer_t*)argument)->pvTimerID;
}

但是这个 Timer_t 结构不是 public。我真的不明白为什么用这个结构作为参数调用回调,而且还强制转换为 const void*...

我该怎么办?

考虑调用 osTimerCreate function in your version of cmsis stores realy the argument parameter to the pvTimerID of the Timer_t structure then you could use pvTimerGetTimerID 以取回您传递的数据:

void Callback01(void const * argument)
{
    T* data = (T*)pvTimerGetTimerID((TimerHandle_t)argument);
}