1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
22 #define COUNTER_STD_END \
\r
30 /* Accessor functions */
31 #if ( OS_SC2 == STD_ON ) || ( OS_SC4 == STD_ON )
\r
32 static inline OsSchTblAdjExpPointType *getAdjExpPoint( OsSchTblType *stblPtr ) {
\r
33 return &stblPtr->adjExpPoint;
\r
38 static inline struct OsSchTblAutostart *getAutoStart( OsSchTblType *stblPtr ) {
\r
39 return &stblPtr->autostart;
\r
42 #if ( OS_SC2 == STD_ON ) || ( OS_SC4 == STD_ON )
\r
43 static inline struct OsScheduleTableSync *getSync( OsSchTblType *stblPtr ) {
\r
44 return &stblPtr->sync;
\r
53 static void AlarmProcess( OsAlarmType *a_obj ) {
\r
54 if( a_obj->cycletime == 0 ) {
\r
57 // Calc new expire value..
\r
58 a_obj->expire_val = Os_CounterCalcModulo( a_obj->expire_val,
\r
59 Os_CounterGetMaxValue(a_obj->counter),
\r
64 static void check_alarms( OsCounterType *c_p ) {
\r
67 SLIST_FOREACH(a_obj,&c_p->alarm_head,alarm_list) {
\r
68 if( a_obj->active && (c_p->val == a_obj->expire_val) ) {
\r
69 /* Check if the alarms have expired */
\r
70 os_isr_printf(D_ALARM,"expired %s id:%d val:%d\n",
\r
75 switch( a_obj->action.type ) {
\r
76 case ALARM_ACTION_ACTIVATETASK:
\r
77 if( ActivateTask(a_obj->action.task_id) != E_OK ) {
78 /* We actually do thing here, See 0S321 */
\r
80 AlarmProcess(a_obj);
\r
82 case ALARM_ACTION_SETEVENT:
\r
83 if( SetEvent(a_obj->action.task_id,a_obj->action.event_id) != E_OK ) {
\r
84 // TODO: Check what to do here..
\r
87 AlarmProcess(a_obj);
\r
89 case ALARM_ACTION_ALARMCALLBACK:
\r
90 /* TODO: not done */
\r
93 case ALARM_ACTION_INCREMENTCOUNTER:
95 /* Huh,, recursive....*/
\r
96 IncrementCounter(a_obj->action.counter_id);
\r
106 * Go through the schedule tables connected to this counter
\r
108 * @param c_p Pointer to counter object
113 static void check_stbl(OsCounterType *c_p) {
114 OsSchTblType *sched_obj;
\r
116 /* Iterate through the schedule tables */
\r
117 SLIST_FOREACH(sched_obj,&c_p->sched_head,sched_list) {
\r
119 if( sched_obj->state == SCHEDULETABLE_STOPPED ) {
\r
123 #if ( OS_SC2 == STD_ON ) || ( OS_SC4 == STD_ON )
\r
124 if( sched_obj->sync.syncStrategy == IMPLICIT ) {
\r
130 if( sched_obj->sync.deviation > 0 ) {
\r
131 // The sync counter was set back ==
\r
132 // we have more time to complete the table
\r
133 adj = MIN(sched_obj->sync.deviation, getAdjExpPoint(sched_obj)->maxAdvance );
\r
134 sched_obj->sync.deviation -= adj;
\r
136 } else if( sched_obj->sync.deviation < 0 ) {
\r
137 // The sync counter was set forward ==
\r
138 // we have less time to complete the table
\r
139 adj = MIN((-sched_obj->sync.deviation), getAdjExpPoint(sched_obj)->maxRetard);
\r
140 sched_obj->sync.deviation -= adj;
\r
144 sched_obj->state = SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS;
\r
149 /* Check if the expire point have been hit */
\r
150 if( (sched_obj->state == SCHEDULETABLE_RUNNING ||
\r
151 SCHEDULETABLE_RUNNING_AND_SYNCHRONOUS ) &&
\r
152 (c_p->val >= sched_obj->expire_val) )
154 OsScheduleTableActionType * action;
\r
156 action = SA_LIST_GET(&sched_obj->action_list,sched_obj->expire_curr_index);
\r
158 switch( action->type ) {
159 case SCHEDULE_ACTION_ACTIVATETASK:
160 ActivateTask(action->task_id);
163 case SCHEDULE_ACTION_SETEVENT:
164 SetEvent( action->task_id, action->event_id);
171 // Calc new expire val
\r
172 Os_SchTblCalcExpire(sched_obj);
\r
180 * Increment a counter. Checks for wraps.
\r
182 * @param counter Ptr to a counter object
184 static void IncCounter( OsCounterType *counter ) {
\r
185 // Check for wrap of type
\r
186 if( (counter->val+1) < (counter->val) ) {
\r
187 counter->val = 0; // This wraps
\r
189 if( counter->val > counter->alarm_base.maxallowedvalue ) {
\r
198 #define IsCounterValid(_counterId) ((_counterId) <= Oil_GetCounterCnt())
207 StatusType IncrementCounter( CounterType counter_id ) {
\r
208 StatusType rv = E_OK;
\r
209 OsCounterType *counter;
\r
210 counter = Oil_GetCounter(counter_id);
213 if( !IsCounterValid(counter_id) ) {
220 if( ( counter->type != COUNTER_TYPE_SOFT ) ||
\r
221 ( counter_id >= Oil_GetCounterCnt() ) ) {
\r
227 IncCounter(counter);
\r
229 check_alarms(counter);
\r
230 check_stbl(counter);
\r
237 StatusType GetCounterValue( CounterType counter_id , TickRefType tick_ref)
\r
239 StatusType rv = E_OK;
\r
240 OsCounterType *cPtr;
\r
241 cPtr = Oil_GetCounter(counter_id);
244 if( !IsCounterValid(counter_id) ) {
250 if( cPtr->type == COUNTER_TYPE_HARD ) {
251 if( cPtr->driver == NULL ) {
252 /* It's OSINTERNAL */
253 *tick_ref = os_sys.tick;
256 /* We support only GPT for now */
257 *tick_ref = (TickType)Gpt_GetTimeElapsed(cPtr->driver.OsGptChannelRef);
262 *tick_ref = cPtr->val;
268 StatusType GetElapsedCounterValue( CounterType counter_id, TickRefType val, TickRefType elapsed_val)
\r
270 StatusType rv = E_OK;
\r
274 cPtr = Oil_GetCounter(counter_id);
277 if( !IsCounterValid(counter_id) ) {
283 if( *val > Os_CounterGetMaxValue(cPtr) ) {
288 GetCounterValue(counter_id,&tick);
290 #warning missing....OS382
297 * 1. The Decrementer is setup by Frt_Start(period_ticks)
\r
298 * 2. Frt_Init() setup INTC[7] to trigger OsTick
\r
299 * 3. OsTick() then increment counter os_tick_counter if used
303 * Non-Autosar stuff
\r
306 /* The id of the counter driven by the os tick, or -1 if not used.
307 * Using weak linking to set default value -1 if not set by config.
309 CounterType Os_Arc_OsTickCounter __attribute__((weak)) = -1;
311 void OsTick( void ) {
312 // if not used, os_tick_counter < 0
313 if (Os_Arc_OsTickCounter >= 0) {
315 OsCounterType *c_p = Oil_GetCounter(Os_Arc_OsTickCounter);
321 // os_sys.tick = c_p->val;
328 TickType GetOsTick( void ) {
\r
329 return get_os_tick();
\r