/* index 0x1017 : Producer Heartbeat Time */
UNS16 masterObjdict_obj1017 = 0; /* 0 */
subindex masterObjdict_Index1017[] =
{
{ RW, uint16, sizeof (UNS16), (void*)&masterObjdict_obj1017, NULL }
};
masterObjdict_obj1017用来设置时间
#define MS_TO_TIMEVAL(ms) ((ms) * 125):把源代码根据自己的时间需求更改
void heartbeatInit(CO_Data* d)
{
UNS8 index; /* Index to scan the table of heartbeat consumers */
RegisterSetODentryCallBack(d, 0x1017, 0x00, &OnHeartbeatProducerUpdate);
d->toggle = 0;
for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ )
{
TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ;
if ( time )
{
d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHeartbeatAlarm, MS_TO_TIMEVAL(time), 0);
}
}
if ( *d->ProducerHeartBeatTime )
{
TIMEVAL time = *d->ProducerHeartBeatTime;
d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHeartbeatAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time));
}
}
setalarm()的功能:添加一个定时
d:指向结构体的指针
callback:回调函数
value:定时时间
period:为0表示单次触发,不为0表示循环触发
for(){}:遍历所有定时事件入口
if(callback&&row->state==TIMER_FREE):回调函数存在,并且入口状态时空闲则进入
getElapsedTime():获取已经流失的时间
setTimer(real_timer_value):设定定时器重装载值
接下来就是初始化回调函数、节点指针、ID、触发时间、周期、入口状态
TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period)
{
TIMER_HANDLE row_number;
s_timer_entry *row;
/* in order to decide new timer setting we have to run over all timer rows */
for(row_number=0, row=timers; row_number <= last_timer_raw + 1 && row_number < MAX_NB_TIMER; row_number++, row++)
{
if (callback && /* if something to store */
row->state == TIMER_FREE) /* and empty row */
{ /* just store */
TIMEVAL real_timer_value;
TIMEVAL elapsed_time;
if (row_number == last_timer_raw + 1) last_timer_raw++;
elapsed_time = getElapsedTime();
/* set next wakeup alarm if new entry is sooner than others, or if it is alone */
real_timer_value = value;
real_timer_value = min_val(real_timer_value, TIMEVAL_MAX);
if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value)
{
total_sleep_time = elapsed_time + real_timer_value;
setTimer(real_timer_value);
}
row->callback = callback;
row->d = d;
row->id = id;
row->val = value + elapsed_time;
row->interval = period;
row->state = TIMER_ARMED;
return row_number;
}
}
return TIMER_NONE;
}
TimeDispatch:放入定时器的中断中,时间到达,则使用一次该函数
real_total_sleep_time = total_sleep_time + overrun:total_sleep_time来自setalarm
for():遍历定时事件入口
if (row->state & TIMER_ARMED) /* if row is active */:如果被占用
if (row->val <= real_total_sleep_time) /* to be trigged */:超时需要触发
if (!row->interval):不是周期触发
void TimeDispatch(void)
{
TIMER_HANDLE i;
TIMEVAL next_wakeup = TIMEVAL_MAX; /* used to compute when should normaly occur next wakeup */
/* First run : change timer state depending on time */
/* Get time since timer signal */
UNS32 overrun = (UNS32)getElapsedTime();
TIMEVAL real_total_sleep_time = total_sleep_time + overrun;
s_timer_entry *row;
for(i=0, row = timers; i <= last_timer_raw; i++, row++)
{
if (row->state & TIMER_ARMED) /* if row is active */
{
if (row->val <= real_total_sleep_time) /* to be trigged */
{
if (!row->interval) /* if simply outdated */
{
row->state = TIMER_TRIG; /* ask for trig */
}
else /* or period have expired */
{
/* set val as interval, with 32 bit overrun correction, */
/* modulo for 64 bit not available on all platforms */
row->val = row->interval - (overrun % (UNS32)row->interval);
row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */
/* Check if this new timer value is the soonest */
if(row->val < next_wakeup)
next_wakeup = row->val;
}
}
else
{
/* Each armed timer value in decremented. */
row->val -= real_total_sleep_time;
/* Check if this new timer value is the soonest */
if(row->val < next_wakeup)
next_wakeup = row->val;
}
}
}
/* Remember how much time we should sleep. */
total_sleep_time = next_wakeup;
/* Set timer to soonest occurence */
setTimer(next_wakeup);
/* Then trig them or not. */
for(i=0, row = timers; i<=last_timer_raw; i++, row++)
{
if (row->state & TIMER_TRIG)
{
row->state &= ~TIMER_TRIG; /* reset trig state (will be free if not periodic) */
if(row->callback)
(*row->callback)(row->d, row->id); /* trig ! */
}
}
}
初始化节点状态后,进入运行状态
从机的节点:0x00
运行状态:0x05