1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for EPL User Timermodule for Linux kernel module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
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.
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.
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.
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.
50 -------------------------------------------------------------------------
52 $RCSfile: EplTimeruLinuxKernel.c,v $
56 $Revision: 1.6 $ $Date: 2008/04/17 21:36:32 $
63 -------------------------------------------------------------------------
67 2006/09/12 d.k.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplTimeru.h"
72 #include <linux/timer.h>
74 /***************************************************************************/
77 /* G L O B A L D E F I N I T I O N S */
80 /***************************************************************************/
82 //---------------------------------------------------------------------------
84 //---------------------------------------------------------------------------
86 //---------------------------------------------------------------------------
88 //---------------------------------------------------------------------------
90 struct timer_list m_Timer;
91 tEplTimerArg TimerArgument;
95 //---------------------------------------------------------------------------
97 //---------------------------------------------------------------------------
99 //---------------------------------------------------------------------------
100 // local function prototypes
101 //---------------------------------------------------------------------------
102 static void EplTimeruCbMs(unsigned long ulParameter_p);
104 /***************************************************************************/
107 /* C L A S S <Epl Userspace-Timermodule for Linux Kernel> */
110 /***************************************************************************/
112 // Description: Epl Userspace-Timermodule for Linux Kernel
115 /***************************************************************************/
117 //=========================================================================//
119 // P U B L I C F U N C T I O N S //
121 //=========================================================================//
123 //---------------------------------------------------------------------------
125 // Function: EplTimeruInit
127 // Description: function inits first instance
131 // Returns: tEplKernel = errorcode
135 //---------------------------------------------------------------------------
137 tEplKernel EplTimeruInit(void)
141 Ret = EplTimeruAddInstance();
146 //---------------------------------------------------------------------------
148 // Function: EplTimeruAddInstance
150 // Description: function inits additional instance
154 // Returns: tEplKernel = errorcode
158 //---------------------------------------------------------------------------
160 tEplKernel EplTimeruAddInstance(void)
164 Ret = kEplSuccessful;
169 //---------------------------------------------------------------------------
171 // Function: EplTimeruDelInstance
173 // Description: function deletes instance
174 // -> under Linux nothing to do
175 // -> no instance table needed
179 // Returns: tEplKernel = errorcode
183 //---------------------------------------------------------------------------
185 tEplKernel EplTimeruDelInstance(void)
189 Ret = kEplSuccessful;
194 //---------------------------------------------------------------------------
196 // Function: EplTimeruSetTimerMs
198 // Description: function creates a timer and returns the corresponding handle
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
204 // Returns: tEplKernel = errorcode
208 //---------------------------------------------------------------------------
210 tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
211 unsigned long ulTime_p,
212 tEplTimerArg Argument_p)
214 tEplKernel Ret = kEplSuccessful;
215 tEplTimeruData *pData;
217 // check pointer to handle
218 if (pTimerHdl_p == NULL) {
219 Ret = kEplTimerInvalidHandle;
223 pData = (tEplTimeruData *) EPL_MALLOC(sizeof(tEplTimeruData));
225 Ret = kEplNoResource;
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;
234 EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
236 add_timer(&pData->m_Timer);
238 *pTimerHdl_p = (tEplTimerHdl) pData;
244 //---------------------------------------------------------------------------
246 // Function: EplTimeruModifyTimerMs
248 // Description: function changes a timer and returns the corresponding handle
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
254 // Returns: tEplKernel = errorcode
258 //---------------------------------------------------------------------------
260 tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
261 unsigned long ulTime_p,
262 tEplTimerArg Argument_p)
264 tEplKernel Ret = kEplSuccessful;
265 tEplTimeruData *pData;
267 // check pointer to handle
268 if (pTimerHdl_p == NULL) {
269 Ret = kEplTimerInvalidHandle;
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);
277 pData = (tEplTimeruData *) * pTimerHdl_p;
278 if ((tEplTimeruData *) pData->m_Timer.data != pData) {
279 Ret = kEplTimerInvalidHandle;
283 mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));
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));
292 // check if timer is really running
293 if (timer_pending(&pData->m_Timer) == 0) { // timer is not running
295 add_timer(&pData->m_Timer);
297 // set handle to pointer of tEplTimeruData
298 // *pTimerHdl_p = (tEplTimerHdl) pData;
304 //---------------------------------------------------------------------------
306 // Function: EplTimeruDeleteTimer
308 // Description: function deletes a timer
310 // Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
312 // Returns: tEplKernel = errorcode
316 //---------------------------------------------------------------------------
318 tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p)
320 tEplKernel Ret = kEplSuccessful;
321 tEplTimeruData *pData;
323 // check pointer to handle
324 if (pTimerHdl_p == NULL) {
325 Ret = kEplTimerInvalidHandle;
328 // check handle itself, i.e. was the handle initialized before
329 if (*pTimerHdl_p == 0) {
330 Ret = kEplSuccessful;
333 pData = (tEplTimeruData *) * pTimerHdl_p;
334 if ((tEplTimeruData *) pData->m_Timer.data != pData) {
335 Ret = kEplTimerInvalidHandle;
339 /* if (del_timer(&pData->m_Timer) == 1)
344 // try to delete the timer
345 del_timer(&pData->m_Timer);
346 // free memory in any case
349 // uninitialize handle
357 //---------------------------------------------------------------------------
359 // Function: EplTimeruIsTimerActive
361 // Description: checks if the timer referenced by the handle is currently
364 // Parameters: TimerHdl_p = handle of the timer to check
366 // Returns: BOOL = TRUE, if active;
371 //---------------------------------------------------------------------------
373 BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
375 BOOL fActive = FALSE;
376 tEplTimeruData *pData;
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
382 pData = (tEplTimeruData *) TimerHdl_p;
383 if ((tEplTimeruData *) pData->m_Timer.data != pData) { // invalid timer
386 // check if timer is running
387 if (timer_pending(&pData->m_Timer) == 0) { // timer is not running
397 //=========================================================================//
399 // P R I V A T E F U N C T I O N S //
401 //=========================================================================//
403 //---------------------------------------------------------------------------
405 // Function: EplTimeruCbMs
407 // Description: function to process timer
411 // Parameters: lpParameter = pointer to structur of type tEplTimeruData
419 //---------------------------------------------------------------------------
420 static void EplTimeruCbMs(unsigned long ulParameter_p)
422 tEplKernel Ret = kEplSuccessful;
423 tEplTimeruData *pData;
425 tEplTimerEventArg TimerEventArg;
427 pData = (tEplTimeruData *) ulParameter_p;
429 // call event function
430 TimerEventArg.m_TimerHdl = (tEplTimerHdl) pData;
431 TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg;
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);
439 Ret = EplEventuPost(&EplEvent);
441 // d.k. do not free memory, user has to call EplTimeruDeleteTimer()