Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.31-rc7 3192 lines 92 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 api function of EplOBD-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: EplObd.c,v $ 53 54 $Author: D.Krueger $ 55 56 $Revision: 1.12 $ $Date: 2008/10/17 15:32:32 $ 57 58 $State: Exp $ 59 60 Build Environment: 61 Microsoft VC7 62 63 ------------------------------------------------------------------------- 64 65 Revision History: 66 67 2006/06/02 k.t.: start of the implementation, version 1.00 68 ->based on CANopen OBD-Modul 69 70****************************************************************************/ 71 72#include "EplInc.h" 73#include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul 74 75#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) 76 77/***************************************************************************/ 78/* */ 79/* */ 80/* G L O B A L D E F I N I T I O N S */ 81/* */ 82/* */ 83/***************************************************************************/ 84 85//--------------------------------------------------------------------------- 86// const defines 87//--------------------------------------------------------------------------- 88 89// float definitions and macros 90#define _SHIFTED_EXPONENT_MASK_SP 0xff 91#define _BIAS_SP 126 92#define T_SP 23 93#define EXPONENT_DENORM_SP (-_BIAS_SP) 94#define BASE_TO_THE_T_SP ((float) 8388608.0) 95#define GET_EXPONENT_SP(x) ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP) 96 97//--------------------------------------------------------------------------- 98// local types 99//--------------------------------------------------------------------------- 100 101// struct for instance table 102INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER() 103 104STATIC tEplObdInitParam m_ObdInitParam; 105STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback; 106 107INSTANCE_TYPE_END 108// decomposition of float 109typedef union { 110 tEplObdReal32 m_flRealPart; 111 int m_nIntegerPart; 112 113} tEplObdRealParts; 114 115//--------------------------------------------------------------------------- 116// modul globale vars 117//--------------------------------------------------------------------------- 118 119// This macro replace the unspecific pointer to an instance through 120// the modul specific type for the local instance table. This macro 121// must defined in each modul. 122//#define tEplPtrInstance tEplInstanceInfo * 123 124EPL_MCO_DECL_INSTANCE_VAR() 125 126u8 abEplObdTrashObject_g[8]; 127 128//--------------------------------------------------------------------------- 129// local function prototypes 130//--------------------------------------------------------------------------- 131 132EPL_MCO_DEFINE_INSTANCE_FCT() 133 134static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_ 135 tEplObdCallback fpCallback_p, 136 tEplObdCbParam *pCbParam_p); 137 138static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p); 139 140static tEplObdSize EplObdGetStrLen(void *pObjData_p, 141 tEplObdSize ObjLen_p, tEplObdType ObjType_p); 142 143#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) 144static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p, 145 void *pData_p); 146#endif 147 148static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p, 149 tEplObdVarEntry **ppVarEntry_p); 150 151static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_ 152 unsigned int uiIndex_p, 153 unsigned int uiSubindex_p, 154 tEplObdEntryPtr * ppObdEntry_p, 155 tEplObdSubEntryPtr * ppObdSubEntry_p); 156 157static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p); 158 159static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p, 160 unsigned int uiIndex_p, 161 tEplObdEntryPtr * ppObdEntry_p); 162 163static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p, 164 unsigned int uiSubIndex_p, 165 tEplObdSubEntryPtr * ppObdSubEntry_p); 166 167static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_ 168 tEplObdPart CurrentOdPart_p, 169 tEplObdEntryPtr pObdEnty_p, 170 tEplObdDir Direction_p); 171 172static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p); 173static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p); 174 175#if (EPL_OBD_USE_STORE_RESTORE != FALSE) 176 177static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam *pCbStoreParam_p); 178 179#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) 180 181static void EplObdCopyObjectData(void *pDstData_p, 182 void *pSrcData_p, 183 tEplObdSize ObjSize_p, tEplObdType ObjType_p); 184 185void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p); 186 187static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p, 188 BOOL * pfEntryNumerical_p); 189 190static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 191 unsigned int uiSubIndex_p, 192 void *pSrcData_p, 193 void **ppDstData_p, 194 tEplObdSize Size_p, 195 tEplObdEntryPtr *ppObdEntry_p, 196 tEplObdSubEntryPtr *ppSubEntry_p, 197 tEplObdCbParam *pCbParam_p, 198 tEplObdSize *pObdSize_p); 199 200static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p, 201 tEplObdSubEntryPtr pSubEntry_p, 202 tEplObdCbParam *pCbParam_p, 203 void *pSrcData_p, 204 void *pDstData_p, 205 tEplObdSize ObdSize_p); 206 207//=========================================================================// 208// // 209// P U B L I C F U N C T I O N S // 210// // 211//=========================================================================// 212 213//--------------------------------------------------------------------------- 214// 215// Function: EplObdInit() 216// 217// Description: initializes the first instance 218// 219// Parameters: pInitParam_p = init parameter 220// 221// Return: tEplKernel = errorcode 222// 223// State: 224// 225//--------------------------------------------------------------------------- 226 227tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p) 228{ 229 230 tEplKernel Ret; 231 EPL_MCO_DELETE_INSTANCE_TABLE(); 232 233 if (pInitParam_p == NULL) { 234 Ret = kEplSuccessful; 235 goto Exit; 236 } 237 238 Ret = EplObdAddInstance(EPL_MCO_PTR_INSTANCE_PTR_ pInitParam_p); 239 240 Exit: 241 return Ret; 242 243} 244 245//--------------------------------------------------------------------------- 246// 247// Function: EplObdAddInstance() 248// 249// Description: adds a new instance 250// 251// Parameters: pInitParam_p 252// 253// Return: tEplKernel 254// 255// State: 256// 257//--------------------------------------------------------------------------- 258 259tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p) 260{ 261 262 EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret; 263 264 // check if pointer to instance pointer valid 265 // get free instance and set the globale instance pointer 266 // set also the instance addr to parameterlist 267 EPL_MCO_CHECK_PTR_INSTANCE_PTR(); 268 EPL_MCO_GET_FREE_INSTANCE_PTR(); 269 EPL_MCO_SET_PTR_INSTANCE_PTR(); 270 271 // save init parameters 272 EPL_MEMCPY(&EPL_MCO_GLB_VAR(m_ObdInitParam), pInitParam_p, 273 sizeof(tEplObdInitParam)); 274 275 // clear callback function for command LOAD and STORE 276 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = NULL; 277 278 // sign instance as used 279 EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed); 280 281 // initialize object dictionary 282 // so all all VarEntries will be initialized to trash object and default values will be set to current data 283 Ret = EplObdAccessOdPart(EPL_MCO_INSTANCE_PTR_ 284 kEplObdPartAll, kEplObdDirInit); 285 286 return Ret; 287 288} 289 290//--------------------------------------------------------------------------- 291// 292// Function: EplObdDeleteInstance() 293// 294// Description: delete instance 295// 296// Parameters: EPL_MCO_DECL_INSTANCE_PTR 297// 298// Return: tEplKernel 299// 300// State: 301// 302//--------------------------------------------------------------------------- 303#if (EPL_USE_DELETEINST_FUNC != FALSE) 304tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR) 305{ 306 // check for all API function if instance is valid 307 EPL_MCO_CHECK_INSTANCE_STATE(); 308 309 // sign instance as unused 310 EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused); 311 312 return kEplSuccessful; 313 314} 315#endif // (EPL_USE_DELETEINST_FUNC != FALSE) 316 317//--------------------------------------------------------------------------- 318// 319// Function: EplObdWriteEntry() 320// 321// Description: Function writes data to an OBD entry. Strings 322// are stored with added '\0' character. 323// 324// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 325// uiIndex_p = Index of the OD entry 326// uiSubIndex_p = Subindex of the OD Entry 327// pSrcData_p = Pointer to the data to write 328// Size_p = Size of the data in Byte 329// 330// Return: tEplKernel = Errorcode 331// 332// 333// State: 334// 335//--------------------------------------------------------------------------- 336 337tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 338 unsigned int uiSubIndex_p, 339 void *pSrcData_p, tEplObdSize Size_p) 340{ 341 342 tEplKernel Ret; 343 tEplObdEntryPtr pObdEntry; 344 tEplObdSubEntryPtr pSubEntry; 345 tEplObdCbParam CbParam; 346 void *pDstData; 347 tEplObdSize ObdSize; 348 349 Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_ 350 uiIndex_p, 351 uiSubIndex_p, 352 pSrcData_p, 353 &pDstData, 354 Size_p, 355 &pObdEntry, &pSubEntry, &CbParam, &ObdSize); 356 if (Ret != kEplSuccessful) { 357 goto Exit; 358 } 359 360 Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_ 361 pObdEntry, 362 pSubEntry, 363 &CbParam, pSrcData_p, pDstData, ObdSize); 364 if (Ret != kEplSuccessful) { 365 goto Exit; 366 } 367 368 Exit: 369 370 return Ret; 371 372} 373 374//--------------------------------------------------------------------------- 375// 376// Function: EplObdReadEntry() 377// 378// Description: The function reads an object entry. The application 379// can always read the data even if attrib kEplObdAccRead 380// is not set. The attrib is only checked up for SDO transfer. 381// 382// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 383// uiIndex_p = Index oof the OD entry to read 384// uiSubIndex_p = Subindex to read 385// pDstData_p = pointer to the buffer for data 386// Offset_p = offset in data for read access 387// pSize_p = IN: Size of the buffer 388// OUT: number of readed Bytes 389// 390// Return: tEplKernel 391// 392// State: 393// 394//--------------------------------------------------------------------------- 395 396tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 397 unsigned int uiSubIndex_p, 398 void *pDstData_p, tEplObdSize *pSize_p) 399{ 400 401 tEplKernel Ret; 402 tEplObdEntryPtr pObdEntry; 403 tEplObdSubEntryPtr pSubEntry; 404 tEplObdCbParam CbParam; 405 void *pSrcData; 406 tEplObdSize ObdSize; 407 408 // check for all API function if instance is valid 409 EPL_MCO_CHECK_INSTANCE_STATE(); 410 411 ASSERT(pDstData_p != NULL); 412 ASSERT(pSize_p != NULL); 413 414 // get address of index and subindex entry 415 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ 416 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); 417 if (Ret != kEplSuccessful) { 418 goto Exit; 419 } 420 // get pointer to object data 421 pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry); 422 423 // check source pointer 424 if (pSrcData == NULL) { 425 Ret = kEplObdReadViolation; 426 goto Exit; 427 } 428 //------------------------------------------------------------------------ 429 // address of source data to structure of callback parameters 430 // so callback function can change this data before reading 431 CbParam.m_uiIndex = uiIndex_p; 432 CbParam.m_uiSubIndex = uiSubIndex_p; 433 CbParam.m_pArg = pSrcData; 434 CbParam.m_ObdEvent = kEplObdEvPreRead; 435 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 436 pObdEntry->m_fpCallback, &CbParam); 437 if (Ret != kEplSuccessful) { 438 goto Exit; 439 } 440 // get size of data and check if application has reserved enough memory 441 ObdSize = EplObdGetDataSizeIntern(pSubEntry); 442 // check if offset given and calc correct number of bytes to read 443 if (*pSize_p < ObdSize) { 444 Ret = kEplObdValueLengthError; 445 goto Exit; 446 } 447 // read value from object 448 EPL_MEMCPY(pDstData_p, pSrcData, ObdSize); 449 *pSize_p = ObdSize; 450 451 // write address of destination data to structure of callback parameters 452 // so callback function can change this data after reading 453 CbParam.m_pArg = pDstData_p; 454 CbParam.m_ObdEvent = kEplObdEvPostRead; 455 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 456 pObdEntry->m_fpCallback, &CbParam); 457 458 Exit: 459 460 return Ret; 461 462} 463 464//--------------------------------------------------------------------------- 465// 466// Function: EplObdAccessOdPart() 467// 468// Description: restores default values of one part of OD 469// 470// Parameters: ObdPart_p 471// Direction_p 472// 473// Return: tEplKernel 474// 475// State: 476// 477//--------------------------------------------------------------------------- 478 479tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p, 480 tEplObdDir Direction_p) 481{ 482 483 tEplKernel Ret = kEplSuccessful; 484 BOOL fPartFount; 485 tEplObdEntryPtr pObdEntry; 486 487 // check for all API function if instance is valid 488 EPL_MCO_CHECK_INSTANCE_STATE(); 489 490 // part always has to be unequal to NULL 491 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pPart); 492 ASSERTMSG(pObdEntry != NULL, 493 "EplObdAccessOdPart(): no OD part is defined!\n"); 494 495 // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart 496 fPartFount = FALSE; 497 498 // access to part 499 if ((ObdPart_p & kEplObdPartGen) != 0) { 500 fPartFount = TRUE; 501 502 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ 503 kEplObdPartGen, pObdEntry, 504 Direction_p); 505 if (Ret != kEplSuccessful) { 506 goto Exit; 507 } 508 } 509 // access to manufacturer part 510 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pManufacturerPart); 511 512 if (((ObdPart_p & kEplObdPartMan) != 0) && (pObdEntry != NULL)) { 513 fPartFount = TRUE; 514 515 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ 516 kEplObdPartMan, pObdEntry, 517 Direction_p); 518 if (Ret != kEplSuccessful) { 519 goto Exit; 520 } 521 } 522 // access to device part 523 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pDevicePart); 524 525 if (((ObdPart_p & kEplObdPartDev) != 0) && (pObdEntry != NULL)) { 526 fPartFount = TRUE; 527 528 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ 529 kEplObdPartDev, pObdEntry, 530 Direction_p); 531 if (Ret != kEplSuccessful) { 532 goto Exit; 533 } 534 } 535#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) 536 { 537 // access to user part 538 pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart); 539 540 if (((ObdPart_p & kEplObdPartUsr) != 0) && (pObdEntry != NULL)) { 541 fPartFount = TRUE; 542 543 Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_ 544 kEplObdPartUsr, 545 pObdEntry, Direction_p); 546 if (Ret != kEplSuccessful) { 547 goto Exit; 548 } 549 } 550 } 551#endif 552 553 // no access to an OD part was done? illegal OD part was specified! 554 if (fPartFount == FALSE) { 555 Ret = kEplObdIllegalPart; 556 } 557 558 Exit: 559 560 return Ret; 561 562} 563 564//--------------------------------------------------------------------------- 565// 566// Function: EplObdDefineVar() 567// 568// Description: defines a variable in OD 569// 570// Parameters: pEplVarParam_p 571// 572// Return: tEplKernel 573// 574// State: 575// 576//--------------------------------------------------------------------------- 577 578tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p) 579{ 580 581 tEplKernel Ret; 582 tEplObdVarEntry *pVarEntry; 583 tEplVarParamValid VarValid; 584 tEplObdSubEntryPtr pSubindexEntry; 585 586 // check for all API function if instance is valid 587 EPL_MCO_CHECK_INSTANCE_STATE(); 588 589 ASSERT(pVarParam_p != NULL); // is not allowed to be NULL 590 591 // get address of subindex entry 592 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ 593 pVarParam_p->m_uiIndex, 594 pVarParam_p->m_uiSubindex, NULL, &pSubindexEntry); 595 if (Ret != kEplSuccessful) { 596 goto Exit; 597 } 598 // get var entry 599 Ret = EplObdGetVarEntry(pSubindexEntry, &pVarEntry); 600 if (Ret != kEplSuccessful) { 601 goto Exit; 602 } 603 604 VarValid = pVarParam_p->m_ValidFlag; 605 606 // copy only this values, which valid flag is set 607 if ((VarValid & kVarValidSize) != 0) { 608 if (pSubindexEntry->m_Type != kEplObdTypDomain) { 609 tEplObdSize DataSize; 610 611 // check passed size parameter 612 DataSize = EplObdGetObjectSize(pSubindexEntry); 613 if (DataSize != pVarParam_p->m_Size) { // size of variable does not match 614 Ret = kEplObdValueLengthError; 615 goto Exit; 616 } 617 } else { // size can be set only for objects of type DOMAIN 618 pVarEntry->m_Size = pVarParam_p->m_Size; 619 } 620 } 621 622 if ((VarValid & kVarValidData) != 0) { 623 pVarEntry->m_pData = pVarParam_p->m_pData; 624 } 625/* 626 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) 627 { 628 if ((VarValid & kVarValidCallback) != 0) 629 { 630 pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback; 631 } 632 633 if ((VarValid & kVarValidArg) != 0) 634 { 635 pVarEntry->m_pArg = pVarParam_p->m_pArg; 636 } 637 } 638 #endif 639*/ 640 // Ret is already set to kEplSuccessful from ObdGetVarIntern() 641 642 Exit: 643 644 return Ret; 645 646} 647 648//--------------------------------------------------------------------------- 649// 650// Function: EplObdGetObjectDataPtr() 651// 652// Description: It returnes the current data pointer. But if object is an 653// constant object it returnes the default pointer. 654// 655// Parameters: uiIndex_p = Index of the entry 656// uiSubindex_p = Subindex of the entry 657// 658// Return: void * = pointer to object data 659// 660// State: 661// 662//--------------------------------------------------------------------------- 663 664void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 665 unsigned int uiSubIndex_p) 666{ 667 tEplKernel Ret; 668 void *pData; 669 tEplObdEntryPtr pObdEntry; 670 tEplObdSubEntryPtr pObdSubEntry; 671 672 // get pointer to index structure 673 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), 674 uiIndex_p, &pObdEntry); 675 if (Ret != kEplSuccessful) { 676 pData = NULL; 677 goto Exit; 678 } 679 // get pointer to subindex structure 680 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); 681 if (Ret != kEplSuccessful) { 682 pData = NULL; 683 goto Exit; 684 } 685 // get Datapointer 686 pData = EplObdGetObjectDataPtrIntern(pObdSubEntry); 687 688 Exit: 689 return pData; 690 691} 692 693#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) 694 695//--------------------------------------------------------------------------- 696// 697// Function: EplObdRegisterUserOd() 698// 699// Description: function registers the user OD 700// 701// Parameters: pUserOd_p =pointer to user ODd 702// 703// Return: tEplKernel = errorcode 704// 705// State: 706// 707//--------------------------------------------------------------------------- 708tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p) 709{ 710 711 EPL_MCO_CHECK_INSTANCE_STATE(); 712 713 EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart) = pUserOd_p; 714 715 return kEplSuccessful; 716 717} 718 719#endif 720 721//--------------------------------------------------------------------------- 722// 723// Function: EplObdInitVarEntry() 724// 725// Description: function to initialize VarEntry dependened on object type 726// 727// Parameters: pVarEntry_p = pointer to var entry structure 728// Type_p = object type 729// ObdSize_p = size of object data 730// 731// Returns: none 732// 733// State: 734// 735//--------------------------------------------------------------------------- 736 737void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p, 738 tEplObdType Type_p, tEplObdSize ObdSize_p) 739{ 740/* 741 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE) 742 { 743 // reset pointer to VAR callback and argument 744 pVarEntry_p->m_fpCallback = NULL; 745 pVarEntry_p->m_pArg = NULL; 746 } 747 #endif 748*/ 749 750// 10-dec-2004 r.d.: this function will not be used for strings 751 if ((Type_p == kEplObdTypDomain)) 752// (bType_p == kEplObdTypVString) /* || 753// (bType_p == kEplObdTypOString) || 754// (bType_p == kEplObdTypUString) */ ) 755 { 756 // variables which are defined as DOMAIN or VSTRING should not point to 757 // trash object, because this trash object contains only 8 bytes. DOMAINS or 758 // STRINGS can be longer. 759 pVarEntry_p->m_pData = NULL; 760 pVarEntry_p->m_Size = 0; 761 } else { 762 // set address to variable data to trash object 763 // This prevents an access violation if user forgets to call EplObdDefineVar() 764 // for this variable but mappes it in a PDO. 765 pVarEntry_p->m_pData = &abEplObdTrashObject_g[0]; 766 pVarEntry_p->m_Size = ObdSize_p; 767 } 768 769} 770 771//--------------------------------------------------------------------------- 772// 773// Function: EplObdGetDataSize() 774// 775// Description: function to initialize VarEntry dependened on object type 776// 777// gets the data size of an object 778// for string objects it returnes the string length 779// 780// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer 781// uiIndex_p = Index 782// uiSubIndex_p= Subindex 783// 784// Return: tEplObdSize 785// 786// State: 787// 788//--------------------------------------------------------------------------- 789tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 790 unsigned int uiSubIndex_p) 791{ 792 tEplKernel Ret; 793 tEplObdSize ObdSize; 794 tEplObdEntryPtr pObdEntry; 795 tEplObdSubEntryPtr pObdSubEntry; 796 797 // get pointer to index structure 798 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), 799 uiIndex_p, &pObdEntry); 800 if (Ret != kEplSuccessful) { 801 ObdSize = 0; 802 goto Exit; 803 } 804 // get pointer to subindex structure 805 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); 806 if (Ret != kEplSuccessful) { 807 ObdSize = 0; 808 goto Exit; 809 } 810 // get size 811 ObdSize = EplObdGetDataSizeIntern(pObdSubEntry); 812 Exit: 813 return ObdSize; 814} 815 816//--------------------------------------------------------------------------- 817// 818// Function: EplObdGetNodeId() 819// 820// Description: function returns nodeid from entry 0x1F93 821// 822// 823// Parameters: EPL_MCO_DECL_INSTANCE_PTR = Instancepointer 824// 825// Return: unsigned int = Node Id 826// 827// State: 828// 829//--------------------------------------------------------------------------- 830unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR) 831{ 832 tEplKernel Ret; 833 tEplObdSize ObdSize; 834 u8 bNodeId; 835 836 bNodeId = 0; 837 ObdSize = sizeof(bNodeId); 838 Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_ 839 EPL_OBD_NODE_ID_INDEX, 840 EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, &ObdSize); 841 if (Ret != kEplSuccessful) { 842 bNodeId = EPL_C_ADR_INVALID; 843 goto Exit; 844 } 845 846 Exit: 847 return (unsigned int)bNodeId; 848 849} 850 851//--------------------------------------------------------------------------- 852// 853// Function: EplObdSetNodeId() 854// 855// Description: function sets nodeid in entry 0x1F93 856// 857// 858// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer 859// uiNodeId_p = Node Id to set 860// NodeIdType_p= Type on which way the Node Id was set 861// 862// Return: tEplKernel = Errorcode 863// 864// State: 865// 866//--------------------------------------------------------------------------- 867tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p, 868 tEplObdNodeIdType NodeIdType_p) 869{ 870 tEplKernel Ret; 871 tEplObdSize ObdSize; 872 u8 fHwBool; 873 u8 bNodeId; 874 875 // check Node Id 876 if (uiNodeId_p == EPL_C_ADR_INVALID) { 877 Ret = kEplInvalidNodeId; 878 goto Exit; 879 } 880 bNodeId = (u8) uiNodeId_p; 881 ObdSize = sizeof(u8); 882 // write NodeId to OD entry 883 Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_ 884 EPL_OBD_NODE_ID_INDEX, 885 EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, ObdSize); 886 if (Ret != kEplSuccessful) { 887 goto Exit; 888 } 889 // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX 890 switch (NodeIdType_p) { 891 // type unknown 892 case kEplObdNodeIdUnknown: 893 { 894 fHwBool = OBD_FALSE; 895 break; 896 } 897 898 case kEplObdNodeIdSoftware: 899 { 900 fHwBool = OBD_FALSE; 901 break; 902 } 903 904 case kEplObdNodeIdHardware: 905 { 906 fHwBool = OBD_TRUE; 907 break; 908 } 909 910 default: 911 { 912 fHwBool = OBD_FALSE; 913 } 914 915 } // end of switch (NodeIdType_p) 916 917 // write flag 918 ObdSize = sizeof(fHwBool); 919 Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR 920 EPL_OBD_NODE_ID_INDEX, 921 EPL_OBD_NODE_ID_HWBOOL_SUBINDEX, 922 &fHwBool, ObdSize); 923 if (Ret != kEplSuccessful) { 924 goto Exit; 925 } 926 927 Exit: 928 return Ret; 929} 930 931//--------------------------------------------------------------------------- 932// 933// Function: EplObdIsNumerical() 934// 935// Description: function checks if a entry is numerical or not 936// 937// 938// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer 939// uiIndex_p = Index 940// uiSubIndex_p = Subindex 941// pfEntryNumerical_p = pointer to BOOL for returnvalue 942// -> TRUE if entry a numerical value 943// -> FALSE if entry not a numerical value 944// 945// Return: tEplKernel = Errorcode 946// 947// State: 948// 949//--------------------------------------------------------------------------- 950tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 951 unsigned int uiSubIndex_p, 952 BOOL *pfEntryNumerical_p) 953{ 954 tEplKernel Ret; 955 tEplObdEntryPtr pObdEntry; 956 tEplObdSubEntryPtr pObdSubEntry; 957 958 // get pointer to index structure 959 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), 960 uiIndex_p, &pObdEntry); 961 if (Ret != kEplSuccessful) { 962 goto Exit; 963 } 964 // get pointer to subindex structure 965 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); 966 if (Ret != kEplSuccessful) { 967 goto Exit; 968 } 969 970 Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p); 971 972 Exit: 973 return Ret; 974 975} 976 977//--------------------------------------------------------------------------- 978// 979// Function: EplObdReadEntryToLe() 980// 981// Description: The function reads an object entry from the byteoder 982// of the system to the little endian byteorder for numerical values. 983// For other types a normal read will be processed. This is usefull for 984// the PDO and SDO module. The application 985// can always read the data even if attrib kEplObdAccRead 986// is not set. The attrib is only checked up for SDO transfer. 987// 988// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 989// uiIndex_p = Index of the OD entry to read 990// uiSubIndex_p = Subindex to read 991// pDstData_p = pointer to the buffer for data 992// Offset_p = offset in data for read access 993// pSize_p = IN: Size of the buffer 994// OUT: number of readed Bytes 995// 996// Return: tEplKernel 997// 998// State: 999// 1000//--------------------------------------------------------------------------- 1001tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 1002 unsigned int uiSubIndex_p, 1003 void *pDstData_p, tEplObdSize *pSize_p) 1004{ 1005 tEplKernel Ret; 1006 tEplObdEntryPtr pObdEntry; 1007 tEplObdSubEntryPtr pSubEntry; 1008 tEplObdCbParam CbParam; 1009 void *pSrcData; 1010 tEplObdSize ObdSize; 1011 1012 // check for all API function if instance is valid 1013 EPL_MCO_CHECK_INSTANCE_STATE(); 1014 1015 ASSERT(pDstData_p != NULL); 1016 ASSERT(pSize_p != NULL); 1017 1018 // get address of index and subindex entry 1019 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ 1020 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); 1021 if (Ret != kEplSuccessful) { 1022 goto Exit; 1023 } 1024 // get pointer to object data 1025 pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry); 1026 1027 // check source pointer 1028 if (pSrcData == NULL) { 1029 Ret = kEplObdReadViolation; 1030 goto Exit; 1031 } 1032 //------------------------------------------------------------------------ 1033 // address of source data to structure of callback parameters 1034 // so callback function can change this data before reading 1035 CbParam.m_uiIndex = uiIndex_p; 1036 CbParam.m_uiSubIndex = uiSubIndex_p; 1037 CbParam.m_pArg = pSrcData; 1038 CbParam.m_ObdEvent = kEplObdEvPreRead; 1039 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 1040 pObdEntry->m_fpCallback, &CbParam); 1041 if (Ret != kEplSuccessful) { 1042 goto Exit; 1043 } 1044 // get size of data and check if application has reserved enough memory 1045 ObdSize = EplObdGetDataSizeIntern(pSubEntry); 1046 // check if offset given and calc correct number of bytes to read 1047 if (*pSize_p < ObdSize) { 1048 Ret = kEplObdValueLengthError; 1049 goto Exit; 1050 } 1051 // check if numerical type 1052 switch (pSubEntry->m_Type) { 1053 //----------------------------------------------- 1054 // types without ami 1055 case kEplObdTypVString: 1056 case kEplObdTypOString: 1057 case kEplObdTypDomain: 1058 default: 1059 { 1060 // read value from object 1061 EPL_MEMCPY(pDstData_p, pSrcData, ObdSize); 1062 break; 1063 } 1064 1065 //----------------------------------------------- 1066 // numerical type which needs ami-write 1067 // 8 bit or smaller values 1068 case kEplObdTypBool: 1069 case kEplObdTypInt8: 1070 case kEplObdTypUInt8: 1071 { 1072 AmiSetByteToLe(pDstData_p, *((u8 *) pSrcData)); 1073 break; 1074 } 1075 1076 // 16 bit values 1077 case kEplObdTypInt16: 1078 case kEplObdTypUInt16: 1079 { 1080 AmiSetWordToLe(pDstData_p, *((u16 *) pSrcData)); 1081 break; 1082 } 1083 1084 // 24 bit values 1085 case kEplObdTypInt24: 1086 case kEplObdTypUInt24: 1087 { 1088 AmiSetDword24ToLe(pDstData_p, *((u32 *) pSrcData)); 1089 break; 1090 } 1091 1092 // 32 bit values 1093 case kEplObdTypInt32: 1094 case kEplObdTypUInt32: 1095 case kEplObdTypReal32: 1096 { 1097 AmiSetDwordToLe(pDstData_p, *((u32 *) pSrcData)); 1098 break; 1099 } 1100 1101 // 40 bit values 1102 case kEplObdTypInt40: 1103 case kEplObdTypUInt40: 1104 { 1105 AmiSetQword40ToLe(pDstData_p, *((u64 *) pSrcData)); 1106 break; 1107 } 1108 1109 // 48 bit values 1110 case kEplObdTypInt48: 1111 case kEplObdTypUInt48: 1112 { 1113 AmiSetQword48ToLe(pDstData_p, *((u64 *) pSrcData)); 1114 break; 1115 } 1116 1117 // 56 bit values 1118 case kEplObdTypInt56: 1119 case kEplObdTypUInt56: 1120 { 1121 AmiSetQword56ToLe(pDstData_p, *((u64 *) pSrcData)); 1122 break; 1123 } 1124 1125 // 64 bit values 1126 case kEplObdTypInt64: 1127 case kEplObdTypUInt64: 1128 case kEplObdTypReal64: 1129 { 1130 AmiSetQword64ToLe(pDstData_p, *((u64 *) pSrcData)); 1131 break; 1132 } 1133 1134 // time of day 1135 case kEplObdTypTimeOfDay: 1136 case kEplObdTypTimeDiff: 1137 { 1138 AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay *) pSrcData)); 1139 break; 1140 } 1141 1142 } // end of switch(pSubEntry->m_Type) 1143 1144 *pSize_p = ObdSize; 1145 1146 // write address of destination data to structure of callback parameters 1147 // so callback function can change this data after reading 1148 CbParam.m_pArg = pDstData_p; 1149 CbParam.m_ObdEvent = kEplObdEvPostRead; 1150 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 1151 pObdEntry->m_fpCallback, &CbParam); 1152 1153 Exit: 1154 1155 return Ret; 1156 1157} 1158 1159//--------------------------------------------------------------------------- 1160// 1161// Function: EplObdWriteEntryFromLe() 1162// 1163// Description: Function writes data to an OBD entry from a source with 1164// little endian byteorder to the od with system specuific 1165// byteorder. Not numerical values will only by copied. Strings 1166// are stored with added '\0' character. 1167// 1168// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 1169// uiIndex_p = Index of the OD entry 1170// uiSubIndex_p = Subindex of the OD Entry 1171// pSrcData_p = Pointer to the data to write 1172// Size_p = Size of the data in Byte 1173// 1174// Return: tEplKernel = Errorcode 1175// 1176// 1177// State: 1178// 1179//--------------------------------------------------------------------------- 1180tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 1181 unsigned int uiSubIndex_p, 1182 void *pSrcData_p, tEplObdSize Size_p) 1183{ 1184 tEplKernel Ret; 1185 tEplObdEntryPtr pObdEntry; 1186 tEplObdSubEntryPtr pSubEntry; 1187 tEplObdCbParam CbParam; 1188 void *pDstData; 1189 tEplObdSize ObdSize; 1190 u64 qwBuffer; 1191 void *pBuffer = &qwBuffer; 1192 1193 Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_ 1194 uiIndex_p, 1195 uiSubIndex_p, 1196 pSrcData_p, 1197 &pDstData, 1198 Size_p, 1199 &pObdEntry, &pSubEntry, &CbParam, &ObdSize); 1200 if (Ret != kEplSuccessful) { 1201 goto Exit; 1202 } 1203 1204 // check if numerical type 1205 switch (pSubEntry->m_Type) { 1206 //----------------------------------------------- 1207 // types without ami 1208 default: 1209 { // do nothing, i.e. use the given source pointer 1210 pBuffer = pSrcData_p; 1211 break; 1212 } 1213 1214 //----------------------------------------------- 1215 // numerical type which needs ami-write 1216 // 8 bit or smaller values 1217 case kEplObdTypBool: 1218 case kEplObdTypInt8: 1219 case kEplObdTypUInt8: 1220 { 1221 *((u8 *) pBuffer) = AmiGetByteFromLe(pSrcData_p); 1222 break; 1223 } 1224 1225 // 16 bit values 1226 case kEplObdTypInt16: 1227 case kEplObdTypUInt16: 1228 { 1229 *((u16 *) pBuffer) = AmiGetWordFromLe(pSrcData_p); 1230 break; 1231 } 1232 1233 // 24 bit values 1234 case kEplObdTypInt24: 1235 case kEplObdTypUInt24: 1236 { 1237 *((u32 *) pBuffer) = AmiGetDword24FromLe(pSrcData_p); 1238 break; 1239 } 1240 1241 // 32 bit values 1242 case kEplObdTypInt32: 1243 case kEplObdTypUInt32: 1244 case kEplObdTypReal32: 1245 { 1246 *((u32 *) pBuffer) = AmiGetDwordFromLe(pSrcData_p); 1247 break; 1248 } 1249 1250 // 40 bit values 1251 case kEplObdTypInt40: 1252 case kEplObdTypUInt40: 1253 { 1254 *((u64 *) pBuffer) = AmiGetQword40FromLe(pSrcData_p); 1255 break; 1256 } 1257 1258 // 48 bit values 1259 case kEplObdTypInt48: 1260 case kEplObdTypUInt48: 1261 { 1262 *((u64 *) pBuffer) = AmiGetQword48FromLe(pSrcData_p); 1263 break; 1264 } 1265 1266 // 56 bit values 1267 case kEplObdTypInt56: 1268 case kEplObdTypUInt56: 1269 { 1270 *((u64 *) pBuffer) = AmiGetQword56FromLe(pSrcData_p); 1271 break; 1272 } 1273 1274 // 64 bit values 1275 case kEplObdTypInt64: 1276 case kEplObdTypUInt64: 1277 case kEplObdTypReal64: 1278 { 1279 *((u64 *) pBuffer) = AmiGetQword64FromLe(pSrcData_p); 1280 break; 1281 } 1282 1283 // time of day 1284 case kEplObdTypTimeOfDay: 1285 case kEplObdTypTimeDiff: 1286 { 1287 AmiGetTimeOfDay(pBuffer, ((tTimeOfDay *) pSrcData_p)); 1288 break; 1289 } 1290 1291 } // end of switch(pSubEntry->m_Type) 1292 1293 Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_ 1294 pObdEntry, 1295 pSubEntry, 1296 &CbParam, pBuffer, pDstData, ObdSize); 1297 if (Ret != kEplSuccessful) { 1298 goto Exit; 1299 } 1300 1301 Exit: 1302 1303 return Ret; 1304 1305} 1306 1307//--------------------------------------------------------------------------- 1308// 1309// Function: EplObdGetAccessType() 1310// 1311// Description: Function returns accesstype of the entry 1312// 1313// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 1314// uiIndex_p = Index of the OD entry 1315// uiSubIndex_p = Subindex of the OD Entry 1316// pAccessTyp_p = pointer to buffer to store accesstype 1317// 1318// Return: tEplKernel = errorcode 1319// 1320// 1321// State: 1322// 1323//--------------------------------------------------------------------------- 1324tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 1325 unsigned int uiSubIndex_p, 1326 tEplObdAccess *pAccessTyp_p) 1327{ 1328 tEplKernel Ret; 1329 tEplObdEntryPtr pObdEntry; 1330 tEplObdSubEntryPtr pObdSubEntry; 1331 1332 // get pointer to index structure 1333 Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), 1334 uiIndex_p, &pObdEntry); 1335 if (Ret != kEplSuccessful) { 1336 goto Exit; 1337 } 1338 // get pointer to subindex structure 1339 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry); 1340 if (Ret != kEplSuccessful) { 1341 goto Exit; 1342 } 1343 // get accessType 1344 *pAccessTyp_p = pObdSubEntry->m_Access; 1345 1346 Exit: 1347 return Ret; 1348} 1349 1350//--------------------------------------------------------------------------- 1351// 1352// Function: EplObdSearchVarEntry() 1353// 1354// Description: gets variable from OD 1355// 1356// Parameters: uiIndex_p = index of the var entry to search 1357// uiSubindex_p = subindex of var entry to search 1358// ppVarEntry_p = pointer to the pointer to the varentry 1359// 1360// Return: tEplKernel 1361// 1362// State: 1363// 1364//--------------------------------------------------------------------------- 1365 1366tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 1367 unsigned int uiSubindex_p, 1368 tEplObdVarEntry **ppVarEntry_p) 1369{ 1370 1371 tEplKernel Ret; 1372 tEplObdSubEntryPtr pSubindexEntry; 1373 1374 // check for all API function if instance is valid 1375 EPL_MCO_CHECK_INSTANCE_STATE(); 1376 1377 // get address of subindex entry 1378 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ 1379 uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry); 1380 if (Ret == kEplSuccessful) { 1381 // get var entry 1382 Ret = EplObdGetVarEntry(pSubindexEntry, ppVarEntry_p); 1383 } 1384 1385 return Ret; 1386 1387} 1388 1389//=========================================================================// 1390// // 1391// P R I V A T E D E F I N I T I O N S // 1392// // 1393//=========================================================================// 1394 1395EPL_MCO_DECL_INSTANCE_FCT() 1396//--------------------------------------------------------------------------- 1397// 1398// Function: EplObdCallObjectCallback() 1399// 1400// Description: calls callback function of an object or of a variable 1401// 1402// Parameters: fpCallback_p 1403// pCbParam_p 1404// 1405// Return: tEplKernel 1406// 1407// State: 1408// 1409//--------------------------------------------------------------------------- 1410static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_ 1411 tEplObdCallback fpCallback_p, 1412 tEplObdCbParam *pCbParam_p) 1413{ 1414 1415 tEplKernel Ret; 1416 tEplObdCallback fpCallback; 1417 1418 // check for all API function if instance is valid 1419 EPL_MCO_CHECK_INSTANCE_STATE(); 1420 1421 ASSERT(pCbParam_p != NULL); 1422 1423 Ret = kEplSuccessful; 1424 1425 // check address of callback function before calling it 1426 if (fpCallback_p != NULL) { 1427 // KEIL C51 V6.01 has a bug. 1428 // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback. 1429 fpCallback = fpCallback_p; 1430 1431 // call callback function for this object 1432 Ret = fpCallback(EPL_MCO_INSTANCE_PARAM_IDX_() 1433 pCbParam_p); 1434 } 1435 1436 return Ret; 1437} 1438 1439//--------------------------------------------------------------------------- 1440// 1441// Function: EplObdGetDataSizeIntern() 1442// 1443// Description: gets the data size of an object 1444// for string objects it returnes the string length 1445// 1446// Parameters: pSubIndexEntry_p 1447// 1448// Return: tEplObdSize 1449// 1450// State: 1451// 1452//--------------------------------------------------------------------------- 1453 1454static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p) 1455{ 1456 1457 tEplObdSize DataSize; 1458 void *pData; 1459 1460 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING 1461 // then the current pointer is always NULL. The function 1462 // returns the length of default string. 1463 DataSize = EplObdGetObjectSize(pSubIndexEntry_p); 1464 1465 if (pSubIndexEntry_p->m_Type == kEplObdTypVString) { 1466 // The pointer to current value can be received from EplObdGetObjectCurrentPtr() 1467 pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p)); 1468 if (pData != NULL) { 1469 DataSize = 1470 EplObdGetStrLen((void *)pData, DataSize, 1471 pSubIndexEntry_p->m_Type); 1472 } 1473 1474 } 1475 1476 return DataSize; 1477 1478} 1479 1480//--------------------------------------------------------------------------- 1481// 1482// Function: EplObdGetStrLen() 1483// 1484// Description: The function calculates the length of string. The '\0' 1485// character is included!! 1486// 1487// Parameters: pObjData_p = pointer to string 1488// ObjLen_p = max. length of objectr entry 1489// bObjType_p = object type (VSTRING, ...) 1490// 1491// Returns: string length + 1 1492// 1493// State: 1494// 1495//--------------------------------------------------------------------------- 1496 1497static tEplObdSize EplObdGetStrLen(void *pObjData_p, 1498 tEplObdSize ObjLen_p, tEplObdType ObjType_p) 1499{ 1500 1501 tEplObdSize StrLen = 0; 1502 u8 *pbString; 1503 1504 if (pObjData_p == NULL) { 1505 goto Exit; 1506 } 1507 //---------------------------------------- 1508 // Visible String: data format byte 1509 if (ObjType_p == kEplObdTypVString) { 1510 pbString = pObjData_p; 1511 1512 for (StrLen = 0; StrLen < ObjLen_p; StrLen++) { 1513 if (*pbString == '\0') { 1514 StrLen++; 1515 break; 1516 } 1517 1518 pbString++; 1519 } 1520 } 1521 //---------------------------------------- 1522 // other string types ... 1523 1524 Exit: 1525 return (StrLen); 1526 1527} 1528 1529#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) 1530 1531//--------------------------------------------------------------------------- 1532// 1533// Function: EplObdCheckObjectRange() 1534// 1535// Description: function to check value range of object data 1536// 1537// NOTICE: The pointer of data (pData_p) must point out to an even address, 1538// if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is 1539// always realiced because pointer m_pDefault points always to an 1540// array of the SPECIFIED type. 1541// 1542// Parameters: pSubindexEntry_p 1543// pData_p 1544// 1545// Return: tEplKernel 1546// 1547// State: 1548// 1549//--------------------------------------------------------------------------- 1550 1551static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p, 1552 void *pData_p) 1553{ 1554 1555 tEplKernel Ret; 1556 void *pRangeData; 1557 1558 ASSERTMSG(pSubindexEntry_p != NULL, 1559 "EplObdCheckObjectRange(): no address to subindex struct!\n"); 1560 1561 Ret = kEplSuccessful; 1562 1563 // check if data range has to be checked 1564 if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0) { 1565 goto Exit; 1566 } 1567 // get address of default data 1568 pRangeData = pSubindexEntry_p->m_pDefault; 1569 1570 // jump to called object type 1571 switch ((tEplObdType) pSubindexEntry_p->m_Type) { 1572 // ----------------------------------------------------------------- 1573 // ObdType kEplObdTypBool will not be checked because there are only 1574 // two possible values 0 or 1. 1575 1576 // ----------------------------------------------------------------- 1577 // ObdTypes which has to be check up because numerical values 1578 case kEplObdTypInt8: 1579 1580 // switch to lower limit 1581 pRangeData = ((tEplObdInteger8 *) pRangeData) + 1; 1582 1583 // check if value is to low 1584 if (*((tEplObdInteger8 *) pData_p) < 1585 *((tEplObdInteger8 *) pRangeData)) { 1586 Ret = kEplObdValueTooLow; 1587 break; 1588 } 1589 // switch to higher limit 1590 pRangeData = ((tEplObdInteger8 *) pRangeData) + 1; 1591 1592 // check if value is to high 1593 if (*((tEplObdInteger8 *) pData_p) > 1594 *((tEplObdInteger8 *) pRangeData)) { 1595 Ret = kEplObdValueTooHigh; 1596 } 1597 1598 break; 1599 1600 case kEplObdTypUInt8: 1601 1602 // switch to lower limit 1603 pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1; 1604 1605 // check if value is to low 1606 if (*((tEplObdUnsigned8 *) pData_p) < 1607 *((tEplObdUnsigned8 *) pRangeData)) { 1608 Ret = kEplObdValueTooLow; 1609 break; 1610 } 1611 // switch to higher limit 1612 pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1; 1613 1614 // check if value is to high 1615 if (*((tEplObdUnsigned8 *) pData_p) > 1616 *((tEplObdUnsigned8 *) pRangeData)) { 1617 Ret = kEplObdValueTooHigh; 1618 } 1619 1620 break; 1621 1622 case kEplObdTypInt16: 1623 1624 // switch to lower limit 1625 pRangeData = ((tEplObdInteger16 *) pRangeData) + 1; 1626 1627 // check if value is to low 1628 if (*((tEplObdInteger16 *) pData_p) < 1629 *((tEplObdInteger16 *) pRangeData)) { 1630 Ret = kEplObdValueTooLow; 1631 break; 1632 } 1633 // switch to higher limit 1634 pRangeData = ((tEplObdInteger16 *) pRangeData) + 1; 1635 1636 // check if value is to high 1637 if (*((tEplObdInteger16 *) pData_p) > 1638 *((tEplObdInteger16 *) pRangeData)) { 1639 Ret = kEplObdValueTooHigh; 1640 } 1641 1642 break; 1643 1644 case kEplObdTypUInt16: 1645 1646 // switch to lower limit 1647 pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1; 1648 1649 // check if value is to low 1650 if (*((tEplObdUnsigned16 *) pData_p) < 1651 *((tEplObdUnsigned16 *) pRangeData)) { 1652 Ret = kEplObdValueTooLow; 1653 break; 1654 } 1655 // switch to higher limit 1656 pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1; 1657 1658 // check if value is to high 1659 if (*((tEplObdUnsigned16 *) pData_p) > 1660 *((tEplObdUnsigned16 *) pRangeData)) { 1661 Ret = kEplObdValueTooHigh; 1662 } 1663 1664 break; 1665 1666 case kEplObdTypInt32: 1667 1668 // switch to lower limit 1669 pRangeData = ((tEplObdInteger32 *) pRangeData) + 1; 1670 1671 // check if value is to low 1672 if (*((tEplObdInteger32 *) pData_p) < 1673 *((tEplObdInteger32 *) pRangeData)) { 1674 Ret = kEplObdValueTooLow; 1675 break; 1676 } 1677 // switch to higher limit 1678 pRangeData = ((tEplObdInteger32 *) pRangeData) + 1; 1679 1680 // check if value is to high 1681 if (*((tEplObdInteger32 *) pData_p) > 1682 *((tEplObdInteger32 *) pRangeData)) { 1683 Ret = kEplObdValueTooHigh; 1684 } 1685 1686 break; 1687 1688 case kEplObdTypUInt32: 1689 1690 // switch to lower limit 1691 pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1; 1692 1693 // check if value is to low 1694 if (*((tEplObdUnsigned32 *) pData_p) < 1695 *((tEplObdUnsigned32 *) pRangeData)) { 1696 Ret = kEplObdValueTooLow; 1697 break; 1698 } 1699 // switch to higher limit 1700 pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1; 1701 1702 // check if value is to high 1703 if (*((tEplObdUnsigned32 *) pData_p) > 1704 *((tEplObdUnsigned32 *) pRangeData)) { 1705 Ret = kEplObdValueTooHigh; 1706 } 1707 1708 break; 1709 1710 case kEplObdTypReal32: 1711 1712 // switch to lower limit 1713 pRangeData = ((tEplObdReal32 *) pRangeData) + 1; 1714 1715 // check if value is to low 1716 if (*((tEplObdReal32 *) pData_p) < 1717 *((tEplObdReal32 *) pRangeData)) { 1718 Ret = kEplObdValueTooLow; 1719 break; 1720 } 1721 // switch to higher limit 1722 pRangeData = ((tEplObdReal32 *) pRangeData) + 1; 1723 1724 // check if value is to high 1725 if (*((tEplObdReal32 *) pData_p) > 1726 *((tEplObdReal32 *) pRangeData)) { 1727 Ret = kEplObdValueTooHigh; 1728 } 1729 1730 break; 1731 1732 // ----------------------------------------------------------------- 1733 case kEplObdTypInt40: 1734 case kEplObdTypInt48: 1735 case kEplObdTypInt56: 1736 case kEplObdTypInt64: 1737 1738 // switch to lower limit 1739 pRangeData = ((signed u64 *)pRangeData) + 1; 1740 1741 // check if value is to low 1742 if (*((signed u64 *)pData_p) < *((signed u64 *)pRangeData)) { 1743 Ret = kEplObdValueTooLow; 1744 break; 1745 } 1746 // switch to higher limit 1747 pRangeData = ((signed u64 *)pRangeData) + 1; 1748 1749 // check if value is to high 1750 if (*((signed u64 *)pData_p) > *((signed u64 *)pRangeData)) { 1751 Ret = kEplObdValueTooHigh; 1752 } 1753 1754 break; 1755 1756 // ----------------------------------------------------------------- 1757 case kEplObdTypUInt40: 1758 case kEplObdTypUInt48: 1759 case kEplObdTypUInt56: 1760 case kEplObdTypUInt64: 1761 1762 // switch to lower limit 1763 pRangeData = ((unsigned u64 *)pRangeData) + 1; 1764 1765 // check if value is to low 1766 if (*((unsigned u64 *)pData_p) < 1767 *((unsigned u64 *)pRangeData)) { 1768 Ret = kEplObdValueTooLow; 1769 break; 1770 } 1771 // switch to higher limit 1772 pRangeData = ((unsigned u64 *)pRangeData) + 1; 1773 1774 // check if value is to high 1775 if (*((unsigned u64 *)pData_p) > 1776 *((unsigned u64 *)pRangeData)) { 1777 Ret = kEplObdValueTooHigh; 1778 } 1779 1780 break; 1781 1782 // ----------------------------------------------------------------- 1783 case kEplObdTypReal64: 1784 1785 // switch to lower limit 1786 pRangeData = ((tEplObdReal64 *) pRangeData) + 1; 1787 1788 // check if value is to low 1789 if (*((tEplObdReal64 *) pData_p) < 1790 *((tEplObdReal64 *) pRangeData)) { 1791 Ret = kEplObdValueTooLow; 1792 break; 1793 } 1794 // switch to higher limit 1795 pRangeData = ((tEplObdReal64 *) pRangeData) + 1; 1796 1797 // check if value is to high 1798 if (*((tEplObdReal64 *) pData_p) > 1799 *((tEplObdReal64 *) pRangeData)) { 1800 Ret = kEplObdValueTooHigh; 1801 } 1802 1803 break; 1804 1805 // ----------------------------------------------------------------- 1806 case kEplObdTypTimeOfDay: 1807 case kEplObdTypTimeDiff: 1808 break; 1809 1810 // ----------------------------------------------------------------- 1811 // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because 1812 // they have no numerical value. 1813 default: 1814 1815 Ret = kEplObdUnknownObjectType; 1816 break; 1817 } 1818 1819 Exit: 1820 1821 return Ret; 1822 1823} 1824#endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) 1825 1826//--------------------------------------------------------------------------- 1827// 1828// Function: EplObdWriteEntryPre() 1829// 1830// Description: Function prepares write of data to an OBD entry. Strings 1831// are stored with added '\0' character. 1832// 1833// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 1834// uiIndex_p = Index of the OD entry 1835// uiSubIndex_p = Subindex of the OD Entry 1836// pSrcData_p = Pointer to the data to write 1837// Size_p = Size of the data in Byte 1838// 1839// Return: tEplKernel = Errorcode 1840// 1841// 1842// State: 1843// 1844//--------------------------------------------------------------------------- 1845 1846static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p, 1847 unsigned int uiSubIndex_p, 1848 void *pSrcData_p, 1849 void **ppDstData_p, 1850 tEplObdSize Size_p, 1851 tEplObdEntryPtr *ppObdEntry_p, 1852 tEplObdSubEntryPtr *ppSubEntry_p, 1853 tEplObdCbParam *pCbParam_p, 1854 tEplObdSize *pObdSize_p) 1855{ 1856 1857 tEplKernel Ret; 1858 tEplObdEntryPtr pObdEntry; 1859 tEplObdSubEntryPtr pSubEntry; 1860 tEplObdAccess Access; 1861 void *pDstData; 1862 tEplObdSize ObdSize; 1863 BOOL fEntryNumerical; 1864 1865#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) 1866 tEplObdVStringDomain MemVStringDomain; 1867 void *pCurrData; 1868#endif 1869 1870 // check for all API function if instance is valid 1871 EPL_MCO_CHECK_INSTANCE_STATE(); 1872 1873 ASSERT(pSrcData_p != NULL); // should never be NULL 1874 1875 //------------------------------------------------------------------------ 1876 // get address of index and subindex entry 1877 Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_ 1878 uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry); 1879 if (Ret != kEplSuccessful) { 1880 goto Exit; 1881 } 1882 // get pointer to object data 1883 pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry); 1884 1885 Access = (tEplObdAccess) pSubEntry->m_Access; 1886 1887 // check access for write 1888 // access violation if adress to current value is NULL 1889 if (((Access & kEplObdAccConst) != 0) || (pDstData == NULL)) { 1890 Ret = kEplObdAccessViolation; 1891 goto Exit; 1892 } 1893 //------------------------------------------------------------------------ 1894 // get size of object 1895 // -as ObdSize = ObdGetObjectSize (pSubEntry); 1896 1897 //------------------------------------------------------------------------ 1898 // To use the same callback function for ObdWriteEntry as well as for 1899 // an SDO download call at first (kEplObdEvPre...) the callback function 1900 // with the argument pointer to object size. 1901 pCbParam_p->m_uiIndex = uiIndex_p; 1902 pCbParam_p->m_uiSubIndex = uiSubIndex_p; 1903 1904 // Because object size and object pointer are 1905 // adapted by user callback function, re-read 1906 // this values. 1907 ObdSize = EplObdGetObjectSize(pSubEntry); 1908 pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry); 1909 1910 // 09-dec-2004 r.d.: 1911 // Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain 1912 // for String or Domain which lets called module directly change 1913 // the data pointer or size. This prevents a recursive call to 1914 // the callback function if it calls EplObdGetEntry(). 1915#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) 1916 if ((pSubEntry->m_Type == kEplObdTypVString) || 1917 (pSubEntry->m_Type == kEplObdTypDomain) || 1918 (pSubEntry->m_Type == kEplObdTypOString)) { 1919 if (pSubEntry->m_Type == kEplObdTypVString) { 1920 // reserve one byte for 0-termination 1921 // -as ObdSize -= 1; 1922 Size_p += 1; 1923 } 1924 // fill out new arg-struct 1925 MemVStringDomain.m_DownloadSize = Size_p; 1926 MemVStringDomain.m_ObjSize = ObdSize; 1927 MemVStringDomain.m_pData = pDstData; 1928 1929 pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain; 1930 pCbParam_p->m_pArg = &MemVStringDomain; 1931 // call user callback 1932 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 1933 pObdEntry->m_fpCallback, 1934 pCbParam_p); 1935 if (Ret != kEplSuccessful) { 1936 goto Exit; 1937 } 1938 // write back new settings 1939 pCurrData = pSubEntry->m_pCurrent; 1940 if ((pSubEntry->m_Type == kEplObdTypVString) 1941 || (pSubEntry->m_Type == kEplObdTypOString)) { 1942 ((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize; 1943 ((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData; 1944 } else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain) 1945 { 1946 ((tEplObdVarEntry *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize; 1947 ((tEplObdVarEntry *)pCurrData)->m_pData = (void *)MemVStringDomain.m_pData; 1948 } 1949 1950 // Because object size and object pointer are 1951 // adapted by user callback function, re-read 1952 // this values. 1953 ObdSize = MemVStringDomain.m_ObjSize; 1954 pDstData = (void *)MemVStringDomain.m_pData; 1955 } 1956#endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE) 1957 1958 // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size 1959 // -as 16.11.04 CbParam.m_pArg = &ObdSize; 1960 // 09-dec-2004 r.d.: CbParam.m_pArg = &Size_p; 1961 pCbParam_p->m_pArg = &ObdSize; 1962 pCbParam_p->m_ObdEvent = kEplObdEvInitWrite; 1963 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 1964 pObdEntry->m_fpCallback, pCbParam_p); 1965 if (Ret != kEplSuccessful) { 1966 goto Exit; 1967 } 1968 1969 if (Size_p > ObdSize) { 1970 Ret = kEplObdValueLengthError; 1971 goto Exit; 1972 } 1973 1974 if (pSubEntry->m_Type == kEplObdTypVString) { 1975 if (((char *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character 1976 1977 // reserve one byte in destination for 0-termination 1978 Size_p -= 1; 1979 } else if (Size_p >= ObdSize) { // source string is not 0-terminated 1980 // and destination buffer is too short 1981 Ret = kEplObdValueLengthError; 1982 goto Exit; 1983 } 1984 } 1985 1986 Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical); 1987 if (Ret != kEplSuccessful) { 1988 goto Exit; 1989 } 1990 1991 if ((fEntryNumerical != FALSE) 1992 && (Size_p != ObdSize)) { 1993 // type is numerical, therefor size has to fit, but it does not. 1994 Ret = kEplObdValueLengthError; 1995 goto Exit; 1996 } 1997 // use given size, because non-numerical objects can be written with shorter values 1998 ObdSize = Size_p; 1999 2000 // set output parameters 2001 *pObdSize_p = ObdSize; 2002 *ppObdEntry_p = pObdEntry; 2003 *ppSubEntry_p = pSubEntry; 2004 *ppDstData_p = pDstData; 2005 2006 // all checks are done 2007 // the caller may now convert the numerial source value to platform byte order in a temporary buffer 2008 2009 Exit: 2010 2011 return Ret; 2012 2013} 2014 2015//--------------------------------------------------------------------------- 2016// 2017// Function: EplObdWriteEntryPost() 2018// 2019// Description: Function finishes write of data to an OBD entry. Strings 2020// are stored with added '\0' character. 2021// 2022// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ 2023// uiIndex_p = Index of the OD entry 2024// uiSubIndex_p = Subindex of the OD Entry 2025// pSrcData_p = Pointer to the data to write 2026// Size_p = Size of the data in Byte 2027// 2028// Return: tEplKernel = Errorcode 2029// 2030// 2031// State: 2032// 2033//--------------------------------------------------------------------------- 2034 2035static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p, 2036 tEplObdSubEntryPtr pSubEntry_p, 2037 tEplObdCbParam *pCbParam_p, 2038 void *pSrcData_p, 2039 void *pDstData_p, 2040 tEplObdSize ObdSize_p) 2041{ 2042 2043 tEplKernel Ret; 2044 2045 // caller converted the source value to platform byte order 2046 // now the range of the value may be checked 2047 2048#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE) 2049 { 2050 // check data range 2051 Ret = EplObdCheckObjectRange(pSubEntry_p, pSrcData_p); 2052 if (Ret != kEplSuccessful) { 2053 goto Exit; 2054 } 2055 } 2056#endif 2057 2058 // now call user callback function to check value 2059 // write address of source data to structure of callback parameters 2060 // so callback function can check this data 2061 pCbParam_p->m_pArg = pSrcData_p; 2062 pCbParam_p->m_ObdEvent = kEplObdEvPreWrite; 2063 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 2064 pObdEntry_p->m_fpCallback, pCbParam_p); 2065 if (Ret != kEplSuccessful) { 2066 goto Exit; 2067 } 2068 // copy object data to OBD 2069 EPL_MEMCPY(pDstData_p, pSrcData_p, ObdSize_p); 2070 2071 // terminate string with 0 2072 if (pSubEntry_p->m_Type == kEplObdTypVString) { 2073 ((char *)pDstData_p)[ObdSize_p] = '\0'; 2074 } 2075 // write address of destination to structure of callback parameters 2076 // so callback function can change data subsequently 2077 pCbParam_p->m_pArg = pDstData_p; 2078 pCbParam_p->m_ObdEvent = kEplObdEvPostWrite; 2079 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 2080 pObdEntry_p->m_fpCallback, pCbParam_p); 2081 2082 Exit: 2083 2084 return Ret; 2085 2086} 2087 2088//--------------------------------------------------------------------------- 2089// 2090// Function: EplObdGetObjectSize() 2091// 2092// Description: function to get size of object 2093// The function determines if an object type an fixed data type (u8, u16, ...) 2094// or non fixed object (string, domain). This information is used to decide 2095// if download data are stored temporary or not. For objects with fixed data length 2096// and types a value range checking can process. 2097// For strings the function returns the whole object size not the 2098// length of string. 2099// 2100// Parameters: pSubIndexEntry_p 2101// 2102// Return: tEplObdSize 2103// 2104// State: 2105// 2106//--------------------------------------------------------------------------- 2107 2108static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p) 2109{ 2110 2111 tEplObdSize DataSize = 0; 2112 void *pData; 2113 2114 switch (pSubIndexEntry_p->m_Type) { 2115 // ----------------------------------------------------------------- 2116 case kEplObdTypBool: 2117 2118 DataSize = 1; 2119 break; 2120 2121 // ----------------------------------------------------------------- 2122 // ObdTypes which has to be check because numerical values 2123 case kEplObdTypInt8: 2124 DataSize = sizeof(tEplObdInteger8); 2125 break; 2126 2127 // ----------------------------------------------------------------- 2128 case kEplObdTypUInt8: 2129 DataSize = sizeof(tEplObdUnsigned8); 2130 break; 2131 2132 // ----------------------------------------------------------------- 2133 case kEplObdTypInt16: 2134 DataSize = sizeof(tEplObdInteger16); 2135 break; 2136 2137 // ----------------------------------------------------------------- 2138 case kEplObdTypUInt16: 2139 DataSize = sizeof(tEplObdUnsigned16); 2140 break; 2141 2142 // ----------------------------------------------------------------- 2143 case kEplObdTypInt32: 2144 DataSize = sizeof(tEplObdInteger32); 2145 break; 2146 2147 // ----------------------------------------------------------------- 2148 case kEplObdTypUInt32: 2149 DataSize = sizeof(tEplObdUnsigned32); 2150 break; 2151 2152 // ----------------------------------------------------------------- 2153 case kEplObdTypReal32: 2154 DataSize = sizeof(tEplObdReal32); 2155 break; 2156 2157 // ----------------------------------------------------------------- 2158 // ObdTypes which has to be not checked because not NUM values 2159 case kEplObdTypDomain: 2160 2161 pData = (void *)pSubIndexEntry_p->m_pCurrent; 2162 if ((void *)pData != (void *)NULL) { 2163 DataSize = ((tEplObdVarEntry *) pData)->m_Size; 2164 } 2165 break; 2166 2167 // ----------------------------------------------------------------- 2168 case kEplObdTypVString: 2169 //case kEplObdTypUString: 2170 2171 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING 2172 // then the current pointer is always NULL. The function 2173 // returns the length of default string. 2174 pData = (void *)pSubIndexEntry_p->m_pCurrent; 2175 if ((void *)pData != (void *)NULL) { 2176 // The max. size of strings defined by STRING-Macro is stored in 2177 // tEplObdVString of current value. 2178 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members) 2179 DataSize = ((tEplObdVString *) pData)->m_Size; 2180 } else { 2181 // The current position is not decleared. The string 2182 // is located in ROM, therefor use default pointer. 2183 pData = (void *)pSubIndexEntry_p->m_pDefault; 2184 if ((const void *)pData != (const void *)NULL) { 2185 // The max. size of strings defined by STRING-Macro is stored in 2186 // tEplObdVString of default value. 2187 DataSize = ((const tEplObdVString *)pData)->m_Size; 2188 } 2189 } 2190 2191 break; 2192 2193 // ----------------------------------------------------------------- 2194 case kEplObdTypOString: 2195 2196 pData = (void *)pSubIndexEntry_p->m_pCurrent; 2197 if ((void *)pData != (void *)NULL) { 2198 // The max. size of strings defined by STRING-Macro is stored in 2199 // tEplObdVString of current value. 2200 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members) 2201 DataSize = ((tEplObdOString *) pData)->m_Size; 2202 } else { 2203 // The current position is not decleared. The string 2204 // is located in ROM, therefor use default pointer. 2205 pData = (void *)pSubIndexEntry_p->m_pDefault; 2206 if ((const void *)pData != (const void *)NULL) { 2207 // The max. size of strings defined by STRING-Macro is stored in 2208 // tEplObdVString of default value. 2209 DataSize = ((const tEplObdOString *)pData)->m_Size; 2210 } 2211 } 2212 break; 2213 2214 // ----------------------------------------------------------------- 2215 case kEplObdTypInt24: 2216 case kEplObdTypUInt24: 2217 2218 DataSize = 3; 2219 break; 2220 2221 // ----------------------------------------------------------------- 2222 case kEplObdTypInt40: 2223 case kEplObdTypUInt40: 2224 2225 DataSize = 5; 2226 break; 2227 2228 // ----------------------------------------------------------------- 2229 case kEplObdTypInt48: 2230 case kEplObdTypUInt48: 2231 2232 DataSize = 6; 2233 break; 2234 2235 // ----------------------------------------------------------------- 2236 case kEplObdTypInt56: 2237 case kEplObdTypUInt56: 2238 2239 DataSize = 7; 2240 break; 2241 2242 // ----------------------------------------------------------------- 2243 case kEplObdTypInt64: 2244 case kEplObdTypUInt64: 2245 case kEplObdTypReal64: 2246 2247 DataSize = 8; 2248 break; 2249 2250 // ----------------------------------------------------------------- 2251 case kEplObdTypTimeOfDay: 2252 case kEplObdTypTimeDiff: 2253 2254 DataSize = 6; 2255 break; 2256 2257 // ----------------------------------------------------------------- 2258 default: 2259 break; 2260 } 2261 2262 return DataSize; 2263} 2264 2265//--------------------------------------------------------------------------- 2266// 2267// Function: EplObdGetObjectDefaultPtr() 2268// 2269// Description: function to get the default pointer (type specific) 2270// 2271// Parameters: pSubIndexEntry_p = pointer to subindex structure 2272// 2273// Returns: (void *) = pointer to default value 2274// 2275// State: 2276// 2277//--------------------------------------------------------------------------- 2278 2279static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p) 2280{ 2281 2282 void *pDefault; 2283 tEplObdType Type; 2284 2285 ASSERTMSG(pSubIndexEntry_p != NULL, 2286 "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n"); 2287 2288 // get address to default data from default pointer 2289 pDefault = pSubIndexEntry_p->m_pDefault; 2290 if (pDefault != NULL) { 2291 // there are some special types, whose default pointer always is NULL or has to get from other structure 2292 // get type from subindex structure 2293 Type = pSubIndexEntry_p->m_Type; 2294 2295 // check if object type is a string value 2296 if ((Type == kEplObdTypVString) /* || 2297 (Type == kEplObdTypUString) */ ) { 2298 2299 // EPL_OBD_SUBINDEX_RAM_VSTRING 2300 // tEplObdSize m_Size; --> size of default string 2301 // char * m_pDefString; --> pointer to default string 2302 // char * m_pString; --> pointer to string in RAM 2303 // 2304 pDefault = 2305 (void *)((tEplObdVString *) pDefault)->m_pString; 2306 } else if (Type == kEplObdTypOString) { 2307 pDefault = 2308 (void *)((tEplObdOString *) pDefault)->m_pString; 2309 } 2310 } 2311 2312 return pDefault; 2313 2314} 2315 2316//--------------------------------------------------------------------------- 2317// 2318// Function: EplObdGetVarEntry() 2319// 2320// Description: gets a variable entry of an object 2321// 2322// Parameters: pSubindexEntry_p 2323// ppVarEntry_p 2324// 2325// Return: tCopKernel 2326// 2327// State: 2328// 2329//--------------------------------------------------------------------------- 2330 2331static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p, 2332 tEplObdVarEntry **ppVarEntry_p) 2333{ 2334 2335 tEplKernel Ret = kEplObdVarEntryNotExist; 2336 2337 ASSERT(ppVarEntry_p != NULL); // is not allowed to be NULL 2338 ASSERT(pSubindexEntry_p != NULL); 2339 2340 // check VAR-Flag - only this object points to variables 2341 if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) { 2342 // check if object is an array 2343 if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) { 2344 *ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1]; 2345 } else { 2346 *ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent; 2347 } 2348 2349 Ret = kEplSuccessful; 2350 } 2351 2352 return Ret; 2353 2354} 2355 2356//--------------------------------------------------------------------------- 2357// 2358// Function: EplObdGetEntry() 2359// 2360// Description: gets a index entry from OD 2361// 2362// Parameters: uiIndex_p = Index number 2363// uiSubindex_p = Subindex number 2364// ppObdEntry_p = pointer to the pointer to the entry 2365// ppObdSubEntry_p = pointer to the pointer to the subentry 2366// 2367// Return: tEplKernel 2368 2369// 2370// State: 2371// 2372//--------------------------------------------------------------------------- 2373 2374static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_ 2375 unsigned int uiIndex_p, 2376 unsigned int uiSubindex_p, 2377 tEplObdEntryPtr * ppObdEntry_p, 2378 tEplObdSubEntryPtr * ppObdSubEntry_p) 2379{ 2380 2381 tEplObdEntryPtr pObdEntry; 2382 tEplObdCbParam CbParam; 2383 tEplKernel Ret; 2384 2385 // check for all API function if instance is valid 2386 EPL_MCO_CHECK_INSTANCE_STATE(); 2387 2388 //------------------------------------------------------------------------ 2389 // get address of entry of index 2390 Ret = 2391 EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), uiIndex_p, 2392 &pObdEntry); 2393 if (Ret != kEplSuccessful) { 2394 goto Exit; 2395 } 2396 //------------------------------------------------------------------------ 2397 // get address of entry of subindex 2398 Ret = EplObdGetSubindexIntern(pObdEntry, uiSubindex_p, ppObdSubEntry_p); 2399 if (Ret != kEplSuccessful) { 2400 goto Exit; 2401 } 2402 //------------------------------------------------------------------------ 2403 // call callback function to inform user/stack that an object will be searched 2404 // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist 2405 CbParam.m_uiIndex = uiIndex_p; 2406 CbParam.m_uiSubIndex = uiSubindex_p; 2407 CbParam.m_pArg = NULL; 2408 CbParam.m_ObdEvent = kEplObdEvCheckExist; 2409 Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_ 2410 pObdEntry->m_fpCallback, &CbParam); 2411 if (Ret != kEplSuccessful) { 2412 Ret = kEplObdIndexNotExist; 2413 goto Exit; 2414 } 2415 //------------------------------------------------------------------------ 2416 // it is allowed to set ppObdEntry_p to NULL 2417 // if so, no address will be written to calling function 2418 if (ppObdEntry_p != NULL) { 2419 *ppObdEntry_p = pObdEntry; 2420 } 2421 2422 Exit: 2423 2424 return Ret; 2425 2426} 2427 2428//--------------------------------------------------------------------------- 2429// 2430// Function: EplObdGetObjectCurrentPtr() 2431// 2432// Description: function to get Current pointer (type specific) 2433// 2434// Parameters: pSubIndexEntry_p 2435// 2436// Return: void * 2437// 2438// State: 2439// 2440//--------------------------------------------------------------------------- 2441 2442static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p) 2443{ 2444 2445 void *pData; 2446 unsigned int uiArrayIndex; 2447 tEplObdSize Size; 2448 2449 pData = pSubIndexEntry_p->m_pCurrent; 2450 2451 // check if constant object 2452 if (pData != NULL) { 2453 // check if object is an array 2454 if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0) { 2455 // calculate correct data pointer 2456 uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1; 2457 if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) { 2458 Size = sizeof(tEplObdVarEntry); 2459 } else { 2460 Size = EplObdGetObjectSize(pSubIndexEntry_p); 2461 } 2462 pData = ((u8 *) pData) + (Size * uiArrayIndex); 2463 } 2464 // check if VarEntry 2465 if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) { 2466 // The data pointer is stored in VarEntry->pData 2467 pData = ((tEplObdVarEntry *) pData)->m_pData; 2468 } 2469 // the default pointer is stored for strings in tEplObdVString 2470 else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* || 2471 (pSubIndexEntry_p->m_Type == kEplObdTypUString) */ 2472 ) { 2473 pData = (void *)((tEplObdVString *)pData)->m_pString; 2474 } else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) { 2475 pData = 2476 (void *)((tEplObdOString *)pData)->m_pString; 2477 } 2478 } 2479 2480 return pData; 2481 2482} 2483 2484//--------------------------------------------------------------------------- 2485// 2486// Function: EplObdGetIndexIntern() 2487// 2488// Description: gets a index entry from OD 2489// 2490// Parameters: pInitParam_p 2491// uiIndex_p 2492// ppObdEntry_p 2493// 2494// Return: tEplKernel 2495// 2496// State: 2497// 2498//--------------------------------------------------------------------------- 2499 2500static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p, 2501 unsigned int uiIndex_p, 2502 tEplObdEntryPtr * ppObdEntry_p) 2503{ 2504 2505 tEplObdEntryPtr pObdEntry; 2506 tEplKernel Ret; 2507 unsigned int uiIndex; 2508 2509#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) 2510 2511 unsigned int nLoop; 2512 2513 // if user OD is used then objekts also has to be searched in user OD 2514 // there is less code need if we do this in a loop 2515 nLoop = 2; 2516 2517#endif 2518 2519 ASSERTMSG(ppObdEntry_p != NULL, 2520 "EplObdGetIndexIntern(): pointer to index entry is NULL!\n"); 2521 2522 Ret = kEplObdIndexNotExist; 2523 2524 // get start address of OD part 2525 // start address depends on object index because 2526 // object dictionary is divided in 3 parts 2527 if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000)) { 2528 pObdEntry = pInitParam_p->m_pPart; 2529 } else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000)) { 2530 pObdEntry = pInitParam_p->m_pManufacturerPart; 2531 } 2532 // index range 0xA000 to 0xFFFF is reserved for DSP-405 2533 // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3. 2534 // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE. 2535 // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000... 2536 // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE. 2537 2538#if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE) 2539 else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF)) 2540#else 2541 else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF)) 2542#endif 2543 { 2544 pObdEntry = pInitParam_p->m_pDevicePart; 2545 } 2546 2547#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) 2548 2549 // if index does not match in static OD then index only has to be searched in user OD 2550 else { 2551 // begin from first entry of user OD part 2552 pObdEntry = pInitParam_p->m_pUserPart; 2553 2554 // no user OD is available 2555 if (pObdEntry == NULL) { 2556 goto Exit; 2557 } 2558 // loop must only run once 2559 nLoop = 1; 2560 } 2561 2562 do { 2563 2564#else 2565 2566 // no user OD is available 2567 // so other object can be found in OD 2568 else { 2569 Ret = kEplObdIllegalPart; 2570 goto Exit; 2571 } 2572 2573#endif 2574 2575 // note: 2576 // The end of Index table is marked with m_uiIndex = 0xFFFF. 2577 // If this function will be called with wIndex_p = 0xFFFF, entry 2578 // should not be found. Therefor it is important to use 2579 // while{} instead of do{}while !!! 2580 2581 // get first index of index table 2582 uiIndex = pObdEntry->m_uiIndex; 2583 2584 // search Index in OD part 2585 while (uiIndex != EPL_OBD_TABLE_INDEX_END) { 2586 // go to the end of this function if index is found 2587 if (uiIndex_p == uiIndex) { 2588 // write address of OD entry to calling function 2589 *ppObdEntry_p = pObdEntry; 2590 Ret = kEplSuccessful; 2591 goto Exit; 2592 } 2593 // objects are sorted in OD 2594 // if the current index in OD is greater than the index which is to search then break loop 2595 // in this case user OD has to be search too 2596 if (uiIndex_p < uiIndex) { 2597 break; 2598 } 2599 // next entry in index table 2600 pObdEntry++; 2601 2602 // get next index of index table 2603 uiIndex = pObdEntry->m_uiIndex; 2604 } 2605 2606#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE)) 2607 2608 // begin from first entry of user OD part 2609 pObdEntry = pInitParam_p->m_pUserPart; 2610 2611 // no user OD is available 2612 if (pObdEntry == NULL) { 2613 goto Exit; 2614 } 2615 // switch next loop for user OD 2616 nLoop--; 2617 2618} 2619 2620while (nLoop > 0) ; 2621 2622#endif 2623 2624 // in this line Index was not found 2625 2626Exit: 2627 2628return Ret; 2629 2630} 2631 2632//--------------------------------------------------------------------------- 2633// 2634// Function: EplObdGetSubindexIntern() 2635// 2636// Description: gets a subindex entry from a index entry 2637// 2638// Parameters: pObdEntry_p 2639// bSubIndex_p 2640// ppObdSubEntry_p 2641// 2642// Return: tEplKernel 2643// 2644// State: 2645// 2646//--------------------------------------------------------------------------- 2647 2648static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p, 2649 unsigned int uiSubIndex_p, 2650 tEplObdSubEntryPtr * ppObdSubEntry_p) 2651{ 2652 2653 tEplObdSubEntryPtr pSubEntry; 2654 unsigned int nSubIndexCount; 2655 tEplKernel Ret; 2656 2657 ASSERTMSG(pObdEntry_p != NULL, 2658 "EplObdGetSubindexIntern(): pointer to index is NULL!\n"); 2659 ASSERTMSG(ppObdSubEntry_p != NULL, 2660 "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n"); 2661 2662 Ret = kEplObdSubindexNotExist; 2663 2664 // get start address of subindex table and count of subindices 2665 pSubEntry = pObdEntry_p->m_pSubIndex; 2666 nSubIndexCount = pObdEntry_p->m_uiCount; 2667 ASSERTMSG((pSubEntry != NULL) && (nSubIndexCount > 0), "ObdGetSubindexIntern(): invalid subindex table within index table!\n"); // should never be NULL 2668 2669 // search subindex in subindex table 2670 while (nSubIndexCount > 0) { 2671 // check if array is found 2672 if ((pSubEntry->m_Access & kEplObdAccArray) != 0) { 2673 // check if subindex is in range 2674 if (uiSubIndex_p < pObdEntry_p->m_uiCount) { 2675 // update subindex number (subindex entry of an array is always in RAM !!!) 2676 pSubEntry->m_uiSubIndex = uiSubIndex_p; 2677 *ppObdSubEntry_p = pSubEntry; 2678 Ret = kEplSuccessful; 2679 goto Exit; 2680 } 2681 } 2682 // go to the end of this function if subindex is found 2683 else if (uiSubIndex_p == pSubEntry->m_uiSubIndex) { 2684 *ppObdSubEntry_p = pSubEntry; 2685 Ret = kEplSuccessful; 2686 goto Exit; 2687 } 2688 // objects are sorted in OD 2689 // if the current subindex in OD is greater than the subindex which is to search then break loop 2690 // in this case user OD has to be search too 2691 if (uiSubIndex_p < pSubEntry->m_uiSubIndex) { 2692 break; 2693 } 2694 2695 pSubEntry++; 2696 nSubIndexCount--; 2697 } 2698 2699 // in this line SubIndex was not fount 2700 2701 Exit: 2702 2703 return Ret; 2704 2705} 2706 2707//--------------------------------------------------------------------------- 2708// 2709// Function: EplObdSetStoreLoadObjCallback() 2710// 2711// Description: function set address to callbackfunction for command Store and Load 2712// 2713// Parameters: fpCallback_p 2714// 2715// Return: tEplKernel 2716// 2717// State: 2718// 2719//--------------------------------------------------------------------------- 2720#if (EPL_OBD_USE_STORE_RESTORE != FALSE) 2721tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p) 2722{ 2723 2724 EPL_MCO_CHECK_INSTANCE_STATE(); 2725 2726 // set new address of callback function 2727 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = fpCallback_p; 2728 2729 return kEplSuccessful; 2730 2731} 2732#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) 2733 2734//--------------------------------------------------------------------------- 2735// 2736// Function: EplObdAccessOdPartIntern() 2737// 2738// Description: runs through OD and executes a job 2739// 2740// Parameters: CurrentOdPart_p 2741// pObdEnty_p 2742// Direction_p = what is to do (load values from flash or EEPROM, store, ...) 2743// 2744// Return: tEplKernel 2745// 2746// State: 2747// 2748//--------------------------------------------------------------------------- 2749 2750static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_ 2751 tEplObdPart CurrentOdPart_p, 2752 tEplObdEntryPtr pObdEnty_p, 2753 tEplObdDir Direction_p) 2754{ 2755 2756 tEplObdSubEntryPtr pSubIndex; 2757 unsigned int nSubIndexCount; 2758 tEplObdAccess Access; 2759 void *pDstData; 2760 void *pDefault; 2761 tEplObdSize ObjSize; 2762 tEplKernel Ret; 2763 tEplObdCbStoreParam CbStore; 2764 tEplObdVarEntry *pVarEntry; 2765 2766 ASSERT(pObdEnty_p != NULL); 2767 2768 Ret = kEplSuccessful; 2769 2770 // prepare structure for STORE RESTORE callback function 2771 CbStore.m_bCurrentOdPart = (u8) CurrentOdPart_p; 2772 CbStore.m_pData = NULL; 2773 CbStore.m_ObjSize = 0; 2774 2775 // command of first action depends on direction to access 2776#if (EPL_OBD_USE_STORE_RESTORE != FALSE) 2777 if (Direction_p == kEplObdDirLoad) { 2778 CbStore.m_bCommand = (u8) kEplObdCommOpenRead; 2779 2780 // call callback function for previous command 2781 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore); 2782 if (Ret != kEplSuccessful) { 2783 goto Exit; 2784 } 2785 // set command for index and subindex loop 2786 CbStore.m_bCommand = (u8) kEplObdCommReadObj; 2787 } else if (Direction_p == kEplObdDirStore) { 2788 CbStore.m_bCommand = (u8) kEplObdCommOpenWrite; 2789 2790 // call callback function for previous command 2791 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore); 2792 if (Ret != kEplSuccessful) { 2793 goto Exit; 2794 } 2795 // set command for index and subindex loop 2796 CbStore.m_bCommand = (u8) kEplObdCommWriteObj; 2797 } 2798#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) 2799 2800 // we should not restore the OD values here 2801 // the next NMT command "Reset Node" or "Reset Communication" resets the OD data 2802 if (Direction_p != kEplObdDirRestore) { 2803 // walk through OD part till end is found 2804 while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END) { 2805 // get address to subindex table and count of subindices 2806 pSubIndex = pObdEnty_p->m_pSubIndex; 2807 nSubIndexCount = pObdEnty_p->m_uiCount; 2808 ASSERT((pSubIndex != NULL) && (nSubIndexCount > 0)); // should never be NULL 2809 2810 // walk through subindex table till all subinices were restored 2811 while (nSubIndexCount != 0) { 2812 Access = (tEplObdAccess) pSubIndex->m_Access; 2813 2814 // get pointer to current and default data 2815 pDefault = EplObdGetObjectDefaultPtr(pSubIndex); 2816 pDstData = EplObdGetObjectCurrentPtr(pSubIndex); 2817 2818 // NOTE (for kEplObdTypVString): 2819 // The function returnes the max. number of bytes for a 2820 // current string. 2821 // r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit). 2822 ObjSize = EplObdGetObjectSize(pSubIndex); 2823 2824 // switch direction of OD access 2825 switch (Direction_p) { 2826 // -------------------------------------------------------------------------- 2827 // VarEntry structures has to be initialized 2828 case kEplObdDirInit: 2829 2830 // If VAR-Flag is set, m_pCurrent means not address of data 2831 // but address of tEplObdVarEntry. Address of data has to be get from 2832 // this structure. 2833 if ((Access & kEplObdAccVar) != 0) { 2834 EplObdGetVarEntry(pSubIndex, 2835 &pVarEntry); 2836 EplObdInitVarEntry(pVarEntry, 2837 pSubIndex-> 2838 m_Type, 2839 ObjSize); 2840/* 2841 if ((Access & kEplObdAccArray) == 0) 2842 { 2843 EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize); 2844 } 2845 else 2846 { 2847 EplObdInitVarEntry ((tEplObdVarEntry *) (((u8 *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)), 2848 pSubIndex->m_Type, ObjSize); 2849 } 2850*/ 2851 // at this time no application variable is defined !!! 2852 // therefore data can not be copied. 2853 break; 2854 } else if (pSubIndex->m_Type == 2855 kEplObdTypVString) { 2856 // If pointer m_pCurrent is not equal to NULL then the 2857 // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current 2858 // pointer points to struct tEplObdVString located in MEM. 2859 // The element size includes the max. number of 2860 // bytes. The element m_pString includes the pointer 2861 // to string in MEM. The memory location of default string 2862 // must be copied to memory location of current string. 2863 2864 pDstData = 2865 pSubIndex->m_pCurrent; 2866 if (pDstData != NULL) { 2867 // 08-dec-2004: code optimization !!! 2868 // entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString 2869 // and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read 2870 // twice. thats not necessary! 2871 2872 // For copying data we have to set the destination pointer to the real RAM string. This 2873 // pointer to RAM string is located in default string info structure. (translated r.d.) 2874 pDstData = (void *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString; 2875 ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size; 2876 2877 ((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData; 2878 ((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize; 2879 } 2880 2881 } else if (pSubIndex->m_Type == 2882 kEplObdTypOString) { 2883 pDstData = 2884 pSubIndex->m_pCurrent; 2885 if (pDstData != NULL) { 2886 // 08-dec-2004: code optimization !!! 2887 // entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString 2888 // and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read 2889 // twice. thats not necessary! 2890 2891 // For copying data we have to set the destination pointer to the real RAM string. This 2892 // pointer to RAM string is located in default string info structure. (translated r.d.) 2893 pDstData = (void *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString; 2894 ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size; 2895 2896 ((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData; 2897 ((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize; 2898 } 2899 2900 } 2901 2902 // no break !! because copy of data has to done too. 2903 2904 // -------------------------------------------------------------------------- 2905 // all objects has to be restored with default values 2906 case kEplObdDirRestore: 2907 2908 // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad 2909 // is replaced to function ObdCopyObjectData() with a new parameter. 2910 2911 // restore object data for init phase 2912 EplObdCopyObjectData(pDstData, pDefault, 2913 ObjSize, 2914 pSubIndex->m_Type); 2915 break; 2916 2917 // -------------------------------------------------------------------------- 2918 // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file 2919 case kEplObdDirLoad: 2920 2921 // restore object data for init phase 2922 EplObdCopyObjectData(pDstData, pDefault, 2923 ObjSize, 2924 pSubIndex->m_Type); 2925 2926 // no break !! because callback function has to be called too. 2927 2928 // -------------------------------------------------------------------------- 2929 // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file 2930 case kEplObdDirStore: 2931 2932 // when attribute kEplObdAccStore is set, then call callback function 2933#if (EPL_OBD_USE_STORE_RESTORE != FALSE) 2934 if ((Access & kEplObdAccStore) != 0) { 2935 // fill out data pointer and size of data 2936 CbStore.m_pData = pDstData; 2937 CbStore.m_ObjSize = ObjSize; 2938 2939 // call callback function for read or write object 2940 Ret = 2941 ObdCallStoreCallback 2942 (EPL_MCO_INSTANCE_PTR_ & 2943 CbStore); 2944 if (Ret != kEplSuccessful) { 2945 goto Exit; 2946 } 2947 } 2948#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) 2949 break; 2950 2951 // -------------------------------------------------------------------------- 2952 // if OD Builder key has to be checked no access to subindex and data should be made 2953 case kEplObdDirOBKCheck: 2954 2955 // no break !! because we want to break the second loop too. 2956 2957 // -------------------------------------------------------------------------- 2958 // unknown Direction 2959 default: 2960 2961 // so we can break the second loop earler 2962 nSubIndexCount = 1; 2963 break; 2964 } 2965 2966 nSubIndexCount--; 2967 2968 // next subindex entry 2969 if ((Access & kEplObdAccArray) == 0) { 2970 pSubIndex++; 2971 if ((nSubIndexCount > 0) 2972 && 2973 ((pSubIndex-> 2974 m_Access & kEplObdAccArray) != 2975 0)) { 2976 // next subindex points to an array 2977 // reset subindex number 2978 pSubIndex->m_uiSubIndex = 1; 2979 } 2980 } else { 2981 if (nSubIndexCount > 0) { 2982 // next subindex points to an array 2983 // increment subindex number 2984 pSubIndex->m_uiSubIndex++; 2985 } 2986 } 2987 } 2988 2989 // next index entry 2990 pObdEnty_p++; 2991 } 2992 } 2993 // ----------------------------------------------------------------------------------------- 2994 // command of last action depends on direction to access 2995 if (Direction_p == kEplObdDirOBKCheck) { 2996 2997 goto Exit; 2998 } 2999#if (EPL_OBD_USE_STORE_RESTORE != FALSE) 3000 else { 3001 if (Direction_p == kEplObdDirLoad) { 3002 CbStore.m_bCommand = (u8) kEplObdCommCloseRead; 3003 } else if (Direction_p == kEplObdDirStore) { 3004 CbStore.m_bCommand = (u8) kEplObdCommCloseWrite; 3005 } else if (Direction_p == kEplObdDirRestore) { 3006 CbStore.m_bCommand = (u8) kEplObdCommClear; 3007 } else { 3008 goto Exit; 3009 } 3010 3011 // call callback function for last command 3012 Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore); 3013 } 3014#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) 3015 3016// goto Exit; 3017 3018 Exit: 3019 3020 return Ret; 3021 3022} 3023 3024// ---------------------------------------------------------------------------- 3025// Function: EplObdCopyObjectData() 3026// 3027// Description: checks pointers to object data and copy them from source to destination 3028// 3029// Parameters: pDstData_p = destination pointer 3030// pSrcData_p = source pointer 3031// ObjSize_p = size of object 3032// ObjType_p = 3033// 3034// Returns: tEplKernel = error code 3035// ---------------------------------------------------------------------------- 3036 3037static void EplObdCopyObjectData(void *pDstData_p, 3038 void *pSrcData_p, 3039 tEplObdSize ObjSize_p, tEplObdType ObjType_p) 3040{ 3041 3042 tEplObdSize StrSize = 0; 3043 3044 // it is allowed to set default and current address to NULL (nothing to copy) 3045 if (pDstData_p != NULL) { 3046 3047 if (ObjType_p == kEplObdTypVString) { 3048 // The function calculates the really number of characters of string. The 3049 // object entry size can be bigger as string size of default string. 3050 // The '\0'-termination is included. A string with no characters has a 3051 // size of 1. 3052 StrSize = 3053 EplObdGetStrLen((void *)pSrcData_p, ObjSize_p, 3054 kEplObdTypVString); 3055 3056 // If the string length is greater than or equal to the entry size in OD then only copy 3057 // entry size - 1 and always set the '\0'-termination. 3058 if (StrSize >= ObjSize_p) { 3059 StrSize = ObjSize_p - 1; 3060 } 3061 } 3062 3063 if (pSrcData_p != NULL) { 3064 // copy data 3065 EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p); 3066 3067 if (ObjType_p == kEplObdTypVString) { 3068 ((char *)pDstData_p)[StrSize] = '\0'; 3069 } 3070 } 3071 } 3072 3073} 3074 3075//--------------------------------------------------------------------------- 3076// 3077// Function: EplObdIsNumericalIntern() 3078// 3079// Description: function checks if a entry is numerical or not 3080// 3081// 3082// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer 3083// uiIndex_p = Index 3084// uiSubIndex_p = Subindex 3085// pfEntryNumerical_p = pointer to BOOL for returnvalue 3086// -> TRUE if entry a numerical value 3087// -> FALSE if entry not a numerical value 3088// 3089// Return: tEplKernel = Errorcode 3090// 3091// State: 3092// 3093//--------------------------------------------------------------------------- 3094static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p, 3095 BOOL * pfEntryNumerical_p) 3096{ 3097 tEplKernel Ret = kEplSuccessful; 3098 3099 // get Type 3100 if ((pObdSubEntry_p->m_Type == kEplObdTypVString) 3101 || (pObdSubEntry_p->m_Type == kEplObdTypOString) 3102 || (pObdSubEntry_p->m_Type == kEplObdTypDomain)) { // not numerical types 3103 *pfEntryNumerical_p = FALSE; 3104 } else { // numerical types 3105 *pfEntryNumerical_p = TRUE; 3106 } 3107 3108 return Ret; 3109 3110} 3111 3112// ------------------------------------------------------------------------- 3113// function to classify object type (fixed/non fixed) 3114// ------------------------------------------------------------------------- 3115 3116// ---------------------------------------------------------------------------- 3117// Function: EplObdCallStoreCallback() 3118// 3119// Description: checks address to callback function and calles it when unequal 3120// to NULL 3121// 3122// Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer) 3123// pCbStoreParam_p = address to callback parameters 3124// 3125// Returns: tEplKernel = error code 3126// ---------------------------------------------------------------------------- 3127#if (EPL_OBD_USE_STORE_RESTORE != FALSE) 3128static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ 3129 tEplObdCbStoreParam * 3130 pCbStoreParam_p) 3131{ 3132 3133 tEplKernel Ret = kEplSuccessful; 3134 3135 ASSERT(pCbStoreParam_p != NULL); 3136 3137 // check if function pointer is NULL - if so, no callback should be called 3138 if (EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) != NULL) { 3139 Ret = 3140 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) 3141 (EPL_MCO_INSTANCE_PARAM_IDX_() 3142 pCbStoreParam_p); 3143 } 3144 3145 return Ret; 3146 3147} 3148#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE) 3149//--------------------------------------------------------------------------- 3150// 3151// Function: EplObdGetObjectDataPtrIntern() 3152// 3153// Description: Function gets the data pointer of an object. 3154// It returnes the current data pointer. But if object is an 3155// constant object it returnes the default pointer. 3156// 3157// Parameters: pSubindexEntry_p = pointer to subindex entry 3158// 3159// Return: void * = pointer to object data 3160// 3161// State: 3162// 3163//--------------------------------------------------------------------------- 3164 3165void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p) 3166{ 3167 3168 void *pData; 3169 tEplObdAccess Access; 3170 3171 ASSERTMSG(pSubindexEntry_p != NULL, 3172 "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n"); 3173 3174 // there are are some objects whose data pointer has to get from other structure 3175 // get access type for this object 3176 Access = pSubindexEntry_p->m_Access; 3177 3178 // If object has access type = const, 3179 // for data only exists default values. 3180 if ((Access & kEplObdAccConst) != 0) { 3181 // The pointer to defualt value can be received from ObdGetObjectDefaultPtr() 3182 pData = ((void *)EplObdGetObjectDefaultPtr(pSubindexEntry_p)); 3183 } else { 3184 // The pointer to current value can be received from ObdGetObjectCurrentPtr() 3185 pData = ((void *)EplObdGetObjectCurrentPtr(pSubindexEntry_p)); 3186 } 3187 3188 return pData; 3189 3190} 3191#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0) 3192// EOF