我正在尝试使用带有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将传递为void *的结构“ Timer_t”传递给回调函数(请参见下面的代码结尾):
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结构不是公共的。我真的不明白为什么要使用此结构作为参数调用回调,而且还要将其强制转换为const void * ...
我应该怎么办?
答案 0 :(得分:2)
考虑在您的cmsis版本中调用osTimerCreate函数,实际上将参数参数存储到Timer_t结构的pvTimerID中,然后可以使用pvTimerGetTimerID来获取传递的数据:
void Callback01(void const * argument)
{
T* data = (T*)pvTimerGetTimerID((TimerHandle_t)argument);
}