at v2.6.29 446 lines 14 kB view raw
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//--------------------------------------------------------------------------- 89typedef 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//--------------------------------------------------------------------------- 102static 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 137tEplKernel 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 160tEplKernel 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 185tEplKernel 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 210tEplKernel 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 260tEplKernel 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 318tEplKernel 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 373BOOL 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//--------------------------------------------------------------------------- 420static 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