]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/counter.c
16ba4191a26bdbd1b96568b1945385dd27de5daf
[arc.git] / system / kernel / counter.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 #include <assert.h>\r
17 #include <stdlib.h>\r
18 #include "Os.h"\r
19 #include "internal.h"\r
20 #include "arc.h"\r
21 \r
22 #define COUNTER_STD_END         \\r
23                 goto ok;                \\r
24         err:                            \\r
25                 ERRORHOOK(rv);  \\r
26         ok:                                     \\r
27                 return rv;\r
28 \r
29 \r
30 /* Accessor functions */\r
31 #if ( OS_SC2 == STD_ON ) || ( OS_SC4 == STD_ON )\r
32 static inline OsSchTblAdjExpPointType *getAdjExpPoint( OsSchTblType *stblPtr ) {\r
33         return &stblPtr->adjExpPoint;\r
34 }\r
35 #endif\r
36 \r
37 \r
38 static inline const struct OsSchTblAutostart *getAutoStart( OsSchTblType *stblPtr ) {\r
39         return stblPtr->autostartPtr;\r
40 }\r
41 \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
45 }\r
46 #endif\r
47 \r
48 \r
49 #define IsCounterValid(_counterId)   ((_counterId) <= OS_COUNTER_CNT)\r
50 \r
51 /**\r
52  *\r
53  * @param counter_id\r
54  * @return\r
55  */\r
56 \r
57 /** @req OS399 */\r
58 StatusType IncrementCounter( CounterType counter_id ) {\r
59         StatusType rv = E_OK;\r
60         OsCounterType *cPtr;\r
61         uint32_t flags;\r
62         cPtr = Os_CfgGetCounter(counter_id);\r
63 \r
64         Irq_Save(flags);\r
65         /** @req OS376 */\r
66         if( !IsCounterValid(counter_id) ) {\r
67                 rv = E_OS_ID;\r
68                 Irq_Restore(flags);\r
69                 goto err;\r
70         }\r
71 \r
72         /* Check param */\r
73         /** @req OS285 */\r
74         if( ( cPtr->type != COUNTER_TYPE_SOFT ) ||\r
75                 ( counter_id >= OS_COUNTER_CNT ) ) {\r
76                 rv =  E_OS_ID;\r
77                 Irq_Restore(flags);\r
78                 goto err;\r
79         }\r
80 \r
81         /** @req OS286 */\r
82         cPtr->val = Os_CounterAdd( cPtr->val, Os_CounterGetMaxValue(cPtr), 1 );\r
83 \r
84 #if OS_ALARM_CNT!=0\r
85         Os_AlarmCheck(cPtr);\r
86 #endif\r
87 #if OS_SCHTBL_CNT!=0\r
88         Os_SchTblCheck(cPtr);\r
89 #endif\r
90 \r
91         Irq_Restore(flags);\r
92 \r
93         /** @req OS321 */\r
94         COUNTER_STD_END;\r
95 }\r
96 \r
97 \r
98 /** @req OS383 */\r
99 StatusType GetCounterValue( CounterType counter_id , TickRefType tick_ref)\r
100 {\r
101         StatusType rv = E_OK;\r
102         OsCounterType *cPtr;\r
103         cPtr = Os_CfgGetCounter(counter_id);\r
104 \r
105         /** @req OS376 */\r
106         if( !IsCounterValid(counter_id) ) {\r
107                 rv = E_OS_ID;\r
108                 goto err;\r
109         }\r
110 \r
111         /** @req OS377 */\r
112         if( cPtr->type == COUNTER_TYPE_HARD ) {\r
113                 if( cPtr->driver == NULL ) {\r
114                         /* It's OSINTERNAL */\r
115                         *tick_ref = os_sys.tick;\r
116                 } else {\r
117 #if 0\r
118                 /* We support only GPT for now */\r
119                 *tick_ref  = (TickType)Gpt_GetTimeElapsed(cPtr->driver.OsGptChannelRef);\r
120 #endif\r
121 \r
122                 }\r
123         } else {\r
124                 *tick_ref = cPtr->val;\r
125         }\r
126 \r
127         COUNTER_STD_END;\r
128 }\r
129 \r
130 /**\r
131  *\r
132  * @param counter_id            The counter to be read\r
133  * @param val[in,out]           in,  The previously read tick value of the counter\r
134  *                                                      out, Contains the current tick value of the counter.\r
135  * @param elapsed_val[out]  The difference\r
136  * @return\r
137  */\r
138 \r
139 /** @req OS392 */\r
140 StatusType GetElapsedCounterValue( CounterType counter_id, TickRefType val, TickRefType elapsed_val)\r
141 {\r
142         StatusType rv = E_OK;\r
143         OsCounterType *cPtr;\r
144         TickType currTick = 0;\r
145         TickType max;\r
146 \r
147         cPtr = Os_CfgGetCounter(counter_id);\r
148 \r
149         /** @req OS381 */\r
150         if( !IsCounterValid(counter_id) ) {\r
151                 rv = E_OS_ID;\r
152                 goto err;\r
153         }\r
154 \r
155         max = Os_CounterGetMaxValue(cPtr);\r
156         /** @req OS391 */\r
157         if( *val > max ) {\r
158                 rv = E_OS_VALUE;\r
159                 goto err;\r
160         }\r
161 \r
162         GetCounterValue(counter_id,&currTick);\r
163 \r
164         /** @req OS382 */\r
165         *elapsed_val = Os_CounterDiff(currTick,*val,max);\r
166 \r
167         /** @req OS460 */\r
168         *val = currTick;\r
169 \r
170         COUNTER_STD_END;\r
171 }\r
172 \r
173 /*\r
174  * The OsTick():\r
175  * 1. The Decrementer is setup by Os_SysTickStart(period_ticks)\r
176  * 2. Os_SysTickInit() setup INTC[7] to trigger OsTick\r
177  * 3. OsTick() then increment counter os_tick_counter if used\r
178  */\r
179 \r
180 /*\r
181  * Non-Autosar stuff\r
182  */\r
183 \r
184 /* The id of the counter driven by the os tick, or -1 if not used.\r
185  * Using weak linking to set default value -1 if not set by config.\r
186  */\r
187 CounterType Os_Arc_OsTickCounter __attribute__((weak)) = -1;\r
188 \r
189 void OsTick( void ) {\r
190         // if not used, os_tick_counter < 0\r
191         if (Os_Arc_OsTickCounter >= 0) {\r
192 \r
193                 OsCounterType *cPtr = Os_CfgGetCounter(Os_Arc_OsTickCounter);\r
194 \r
195                 os_sys.tick++;\r
196 \r
197                 cPtr->val = Os_CounterAdd( cPtr->val, Os_CounterGetMaxValue(cPtr), 1 );\r
198 \r
199         //      os_sys.tick = cPtr->val;\r
200 #if OS_ALARM_CNT!=0\r
201                 Os_AlarmCheck(cPtr);\r
202 #endif\r
203 #if OS_SCHTBL_CNT!=0\r
204                 Os_SchTblCheck(cPtr);\r
205 #endif\r
206         }\r
207 }\r
208 \r
209 TickType GetOsTick( void ) {\r
210         return get_os_tick();\r
211 }\r
212 \r
213 \r
214 /**\r
215  * Initialize alarms and schedule-tables for the counters\r
216  */\r
217 void Os_CounterInit( void ) {\r
218 #if OS_ALARM_CNT!=0\r
219         {\r
220                 OsCounterType *cPtr;\r
221                 OsAlarmType *aPtr;\r
222 \r
223                 /* Add the alarms to counters */\r
224                 for (int i = 0; i < OS_ALARM_CNT; i++) {\r
225                         aPtr = Os_CfgGetAlarmObj(i);\r
226                         cPtr = aPtr->counter;\r
227                         SLIST_INSERT_HEAD(&cPtr->alarm_head, aPtr, alarm_list);\r
228                 }\r
229         }\r
230 #endif\r
231 \r
232 #if OS_SCHTBL_CNT!=0\r
233         {\r
234                 OsCounterType *cPtr;\r
235                 OsSchTblType *sPtr;\r
236 \r
237                 /* Add the schedule tables to counters */\r
238                 for(int i=0; i < OS_SCHTBL_CNT; i++ ) {\r
239 \r
240                         sPtr = Os_CfgGetSched(i);\r
241                         cPtr = sPtr->counter;\r
242                         SLIST_INSERT_HEAD(&cPtr->sched_head, sPtr, sched_list);\r
243                 }\r
244         }\r
245 #endif\r
246 }\r
247 \r