• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2 
3   (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4       www.systec-electronic.com
5 
6   Project:      openPOWERLINK
7 
8   Description:  source file for EPL User Timermodule for Linux kernel module
9 
10   License:
11 
12     Redistribution and use in source and binary forms, with or without
13     modification, are permitted provided that the following conditions
14     are met:
15 
16     1. Redistributions of source code must retain the above copyright
17        notice, this list of conditions and the following disclaimer.
18 
19     2. Redistributions in binary form must reproduce the above copyright
20        notice, this list of conditions and the following disclaimer in the
21        documentation and/or other materials provided with the distribution.
22 
23     3. Neither the name of SYSTEC electronic GmbH nor the names of its
24        contributors may be used to endorse or promote products derived
25        from this software without prior written permission. For written
26        permission, please contact info@systec-electronic.com.
27 
28     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32     COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39     POSSIBILITY OF SUCH DAMAGE.
40 
41     Severability Clause:
42 
43         If a provision of this License is or becomes illegal, invalid or
44         unenforceable in any jurisdiction, that shall not affect:
45         1. the validity or enforceability in that jurisdiction of any other
46            provision of this License; or
47         2. the validity or enforceability in other jurisdictions of that or
48            any other provision of this License.
49 
50   -------------------------------------------------------------------------
51 
52                 $RCSfile: EplTimeruLinuxKernel.c,v $
53 
54                 $Author: D.Krueger $
55 
56                 $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
57 
58                 $State: Exp $
59 
60                 Build Environment:
61                 KEIL uVision 2
62 
63   -------------------------------------------------------------------------
64 
65   Revision History:
66 
67   2006/09/12 d.k.:   start of the implementation
68 
69 ****************************************************************************/
70 
71 #include "user/EplTimeru.h"
72 #include <linux/timer.h>
73 
74 /***************************************************************************/
75 /*                                                                         */
76 /*                                                                         */
77 /*          G L O B A L   D E F I N I T I O N S                            */
78 /*                                                                         */
79 /*                                                                         */
80 /***************************************************************************/
81 
82 //---------------------------------------------------------------------------
83 // const defines
84 //---------------------------------------------------------------------------
85 
86 //---------------------------------------------------------------------------
87 // local types
88 //---------------------------------------------------------------------------
89 typedef struct {
90 	struct timer_list m_Timer;
91 	tEplTimerArg TimerArgument;
92 
93 } tEplTimeruData;
94 
95 //---------------------------------------------------------------------------
96 // modul globale vars
97 //---------------------------------------------------------------------------
98 
99 //---------------------------------------------------------------------------
100 // local function prototypes
101 //---------------------------------------------------------------------------
102 static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
103 
104 /***************************************************************************/
105 /*                                                                         */
106 /*                                                                         */
107 /*          C L A S S  <Epl Userspace-Timermodule for Linux Kernel>              */
108 /*                                                                         */
109 /*                                                                         */
110 /***************************************************************************/
111 //
112 // Description: Epl Userspace-Timermodule for Linux Kernel
113 //
114 //
115 /***************************************************************************/
116 
117 //=========================================================================//
118 //                                                                         //
119 //          P U B L I C   F U N C T I O N S                                //
120 //                                                                         //
121 //=========================================================================//
122 
123 //---------------------------------------------------------------------------
124 //
125 // Function:    EplTimeruInit
126 //
127 // Description: function inits first instance
128 //
129 // Parameters:  void
130 //
131 // Returns:     tEplKernel  = errorcode
132 //
133 // State:
134 //
135 //---------------------------------------------------------------------------
136 
EplTimeruInit()137 tEplKernel PUBLIC EplTimeruInit()
138 {
139 	tEplKernel Ret;
140 
141 	Ret = EplTimeruAddInstance();
142 
143 	return Ret;
144 }
145 
146 //---------------------------------------------------------------------------
147 //
148 // Function:    EplTimeruAddInstance
149 //
150 // Description: function inits additional instance
151 //
152 // Parameters:  void
153 //
154 // Returns:     tEplKernel  = errorcode
155 //
156 // State:
157 //
158 //---------------------------------------------------------------------------
159 
EplTimeruAddInstance()160 tEplKernel PUBLIC EplTimeruAddInstance()
161 {
162 	tEplKernel Ret;
163 
164 	Ret = kEplSuccessful;
165 
166 	return Ret;
167 }
168 
169 //---------------------------------------------------------------------------
170 //
171 // Function:    EplTimeruDelInstance
172 //
173 // Description: function deletes instance
174 //              -> under Linux nothing to do
175 //              -> no instance table needed
176 //
177 // Parameters:  void
178 //
179 // Returns:     tEplKernel  = errorcode
180 //
181 // State:
182 //
183 //---------------------------------------------------------------------------
184 
EplTimeruDelInstance()185 tEplKernel PUBLIC EplTimeruDelInstance()
186 {
187 	tEplKernel Ret;
188 
189 	Ret = kEplSuccessful;
190 
191 	return Ret;
192 }
193 
194 //---------------------------------------------------------------------------
195 //
196 // Function:    EplTimeruSetTimerMs
197 //
198 // Description: function creates a timer and returns the corresponding handle
199 //
200 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
201 //              ulTime_p    = time for timer in ms
202 //              Argument_p  = argument for timer
203 //
204 // Returns:     tEplKernel  = errorcode
205 //
206 // State:
207 //
208 //---------------------------------------------------------------------------
209 
EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,unsigned long ulTime_p,tEplTimerArg Argument_p)210 tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
211 				      unsigned long ulTime_p,
212 				      tEplTimerArg Argument_p)
213 {
214 	tEplKernel Ret = kEplSuccessful;
215 	tEplTimeruData *pData;
216 
217 	// check pointer to handle
218 	if (pTimerHdl_p == NULL) {
219 		Ret = kEplTimerInvalidHandle;
220 		goto Exit;
221 	}
222 
223 	pData = (tEplTimeruData *) EPL_MALLOC(sizeof(tEplTimeruData));
224 	if (pData == NULL) {
225 		Ret = kEplNoResource;
226 		goto Exit;
227 	}
228 
229 	init_timer(&pData->m_Timer);
230 	pData->m_Timer.function = EplTimeruCbMs;
231 	pData->m_Timer.data = (unsigned long)pData;
232 	pData->m_Timer.expires = jiffies + ulTime_p * HZ / 1000;
233 
234 	EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
235 
236 	add_timer(&pData->m_Timer);
237 
238 	*pTimerHdl_p = (tEplTimerHdl) pData;
239 
240       Exit:
241 	return Ret;
242 }
243 
244 //---------------------------------------------------------------------------
245 //
246 // Function:    EplTimeruModifyTimerMs
247 //
248 // Description: function changes a timer and returns the corresponding handle
249 //
250 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
251 //              ulTime_p    = time for timer in ms
252 //              Argument_p  = argument for timer
253 //
254 // Returns:     tEplKernel  = errorcode
255 //
256 // State:
257 //
258 //---------------------------------------------------------------------------
259 
EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,unsigned long ulTime_p,tEplTimerArg Argument_p)260 tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
261 					 unsigned long ulTime_p,
262 					 tEplTimerArg Argument_p)
263 {
264 	tEplKernel Ret = kEplSuccessful;
265 	tEplTimeruData *pData;
266 
267 	// check pointer to handle
268 	if (pTimerHdl_p == NULL) {
269 		Ret = kEplTimerInvalidHandle;
270 		goto Exit;
271 	}
272 	// check handle itself, i.e. was the handle initialized before
273 	if (*pTimerHdl_p == 0) {
274 		Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p);
275 		goto Exit;
276 	}
277 	pData = (tEplTimeruData *) * pTimerHdl_p;
278 	if ((tEplTimeruData *) pData->m_Timer.data != pData) {
279 		Ret = kEplTimerInvalidHandle;
280 		goto Exit;
281 	}
282 
283 	mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));
284 
285 	// copy the TimerArg after the timer is restarted,
286 	// so that a timer occured immediately before mod_timer
287 	// won't use the new TimerArg and
288 	// therefore the old timer cannot be distinguished from the new one.
289 	// But if the new timer is too fast, it may get lost.
290 	EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
291 
292 	// check if timer is really running
293 	if (timer_pending(&pData->m_Timer) == 0) {	// timer is not running
294 		// retry starting it
295 		add_timer(&pData->m_Timer);
296 	}
297 	// set handle to pointer of tEplTimeruData
298 //    *pTimerHdl_p = (tEplTimerHdl) pData;
299 
300       Exit:
301 	return Ret;
302 }
303 
304 //---------------------------------------------------------------------------
305 //
306 // Function:    EplTimeruDeleteTimer
307 //
308 // Description: function deletes a timer
309 //
310 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
311 //
312 // Returns:     tEplKernel  = errorcode
313 //
314 // State:
315 //
316 //---------------------------------------------------------------------------
317 
EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)318 tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
319 {
320 	tEplKernel Ret = kEplSuccessful;
321 	tEplTimeruData *pData;
322 
323 	// check pointer to handle
324 	if (pTimerHdl_p == NULL) {
325 		Ret = kEplTimerInvalidHandle;
326 		goto Exit;
327 	}
328 	// check handle itself, i.e. was the handle initialized before
329 	if (*pTimerHdl_p == 0) {
330 		Ret = kEplSuccessful;
331 		goto Exit;
332 	}
333 	pData = (tEplTimeruData *) * pTimerHdl_p;
334 	if ((tEplTimeruData *) pData->m_Timer.data != pData) {
335 		Ret = kEplTimerInvalidHandle;
336 		goto Exit;
337 	}
338 
339 /*    if (del_timer(&pData->m_Timer) == 1)
340     {
341         kfree(pData);
342     }
343 */
344 	// try to delete the timer
345 	del_timer(&pData->m_Timer);
346 	// free memory in any case
347 	kfree(pData);
348 
349 	// uninitialize handle
350 	*pTimerHdl_p = 0;
351 
352       Exit:
353 	return Ret;
354 
355 }
356 
357 //---------------------------------------------------------------------------
358 //
359 // Function:    EplTimeruIsTimerActive
360 //
361 // Description: checks if the timer referenced by the handle is currently
362 //              active.
363 //
364 // Parameters:  TimerHdl_p  = handle of the timer to check
365 //
366 // Returns:     BOOL        = TRUE, if active;
367 //                            FALSE, otherwise
368 //
369 // State:
370 //
371 //---------------------------------------------------------------------------
372 
EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)373 BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
374 {
375 	BOOL fActive = FALSE;
376 	tEplTimeruData *pData;
377 
378 	// check handle itself, i.e. was the handle initialized before
379 	if (TimerHdl_p == 0) {	// timer was not created yet, so it is not active
380 		goto Exit;
381 	}
382 	pData = (tEplTimeruData *) TimerHdl_p;
383 	if ((tEplTimeruData *) pData->m_Timer.data != pData) {	// invalid timer
384 		goto Exit;
385 	}
386 	// check if timer is running
387 	if (timer_pending(&pData->m_Timer) == 0) {	// timer is not running
388 		goto Exit;
389 	}
390 
391 	fActive = TRUE;
392 
393       Exit:
394 	return fActive;
395 }
396 
397 //=========================================================================//
398 //                                                                         //
399 //          P R I V A T E   F U N C T I O N S                              //
400 //                                                                         //
401 //=========================================================================//
402 
403 //---------------------------------------------------------------------------
404 //
405 // Function:    EplTimeruCbMs
406 //
407 // Description: function to process timer
408 //
409 //
410 //
411 // Parameters:  lpParameter = pointer to structur of type tEplTimeruData
412 //
413 //
414 // Returns:     (none)
415 //
416 //
417 // State:
418 //
419 //---------------------------------------------------------------------------
EplTimeruCbMs(unsigned long ulParameter_p)420 static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
421 {
422 	tEplKernel Ret = kEplSuccessful;
423 	tEplTimeruData *pData;
424 	tEplEvent EplEvent;
425 	tEplTimerEventArg TimerEventArg;
426 
427 	pData = (tEplTimeruData *) ulParameter_p;
428 
429 	// call event function
430 	TimerEventArg.m_TimerHdl = (tEplTimerHdl) pData;
431 	TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg;
432 
433 	EplEvent.m_EventSink = pData->TimerArgument.m_EventSink;
434 	EplEvent.m_EventType = kEplEventTypeTimer;
435 	EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
436 	EplEvent.m_pArg = &TimerEventArg;
437 	EplEvent.m_uiSize = sizeof(TimerEventArg);
438 
439 	Ret = EplEventuPost(&EplEvent);
440 
441 	// d.k. do not free memory, user has to call EplTimeruDeleteTimer()
442 	//kfree(pData);
443 
444 }
445 
446 // EOF
447