1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for api function of EplOBD-Module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplObd.c,v $
56 $Revision: 1.12 $ $Date: 2008/10/17 15:32:32 $
63 -------------------------------------------------------------------------
67 2006/06/02 k.t.: start of the implementation, version 1.00
68 ->based on CANopen OBD-Modul
70 ****************************************************************************/
73 #include "kernel/EplObdk.h" // function prototyps of the EplOBD-Modul
75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
77 /***************************************************************************/
80 /* G L O B A L D E F I N I T I O N S */
83 /***************************************************************************/
85 //---------------------------------------------------------------------------
87 //---------------------------------------------------------------------------
89 // float definitions and macros
90 #define _SHIFTED_EXPONENT_MASK_SP 0xff
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)
97 //---------------------------------------------------------------------------
99 //---------------------------------------------------------------------------
101 // struct for instance table
102 INSTANCE_TYPE_BEGIN
EPL_MCO_DECL_INSTANCE_MEMBER()
104 STATIC tEplObdInitParam m_ObdInitParam
;
105 STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback
;
108 // decomposition of float
110 tEplObdReal32 m_flRealPart
;
115 //---------------------------------------------------------------------------
116 // modul globale vars
117 //---------------------------------------------------------------------------
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 *
124 EPL_MCO_DECL_INSTANCE_VAR()
126 BYTE abEplObdTrashObject_g
[8];
128 //---------------------------------------------------------------------------
129 // local function prototypes
130 //---------------------------------------------------------------------------
132 EPL_MCO_DEFINE_INSTANCE_FCT()
134 static tEplKernel
EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
135 tEplObdCallback fpCallback_p
,
136 tEplObdCbParam
*pCbParam_p
);
138 static tEplObdSize
EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p
);
140 static tEplObdSize
EplObdGetStrLen(void *pObjData_p
,
141 tEplObdSize ObjLen_p
, tEplObdType ObjType_p
);
143 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
144 static tEplKernel
EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p
,
148 static tEplKernel
EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p
,
149 tEplObdVarEntry
**ppVarEntry_p
);
151 static 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
);
157 static tEplObdSize
EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p
);
159 static tEplKernel
EplObdGetIndexIntern(tEplObdInitParam
*pInitParam_p
,
160 unsigned int uiIndex_p
,
161 tEplObdEntryPtr
* ppObdEntry_p
);
163 static tEplKernel
EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p
,
164 unsigned int uiSubIndex_p
,
165 tEplObdSubEntryPtr
* ppObdSubEntry_p
);
167 static tEplKernel
EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
168 tEplObdPart CurrentOdPart_p
,
169 tEplObdEntryPtr pObdEnty_p
,
170 tEplObdDir Direction_p
);
172 static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p
);
173 static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p
);
175 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
177 static tEplKernel
EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam
*pCbStoreParam_p
);
179 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
181 static void EplObdCopyObjectData(void *pDstData_p
,
183 tEplObdSize ObjSize_p
, tEplObdType ObjType_p
);
185 void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p
);
187 static tEplKernel
EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p
,
188 BOOL
* pfEntryNumerical_p
);
190 static tEplKernel
EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
191 unsigned int uiSubIndex_p
,
195 tEplObdEntryPtr
*ppObdEntry_p
,
196 tEplObdSubEntryPtr
*ppSubEntry_p
,
197 tEplObdCbParam
*pCbParam_p
,
198 tEplObdSize
*pObdSize_p
);
200 static tEplKernel
EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p
,
201 tEplObdSubEntryPtr pSubEntry_p
,
202 tEplObdCbParam
*pCbParam_p
,
205 tEplObdSize ObdSize_p
);
207 //=========================================================================//
209 // P U B L I C F U N C T I O N S //
211 //=========================================================================//
213 //---------------------------------------------------------------------------
215 // Function: EplObdInit()
217 // Description: initializes the first instance
219 // Parameters: pInitParam_p = init parameter
221 // Return: tEplKernel = errorcode
225 //---------------------------------------------------------------------------
227 EPLDLLEXPORT tEplKernel
EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam
*pInitParam_p
)
231 EPL_MCO_DELETE_INSTANCE_TABLE();
233 if (pInitParam_p
== NULL
) {
234 Ret
= kEplSuccessful
;
238 Ret
= EplObdAddInstance(EPL_MCO_PTR_INSTANCE_PTR_ pInitParam_p
);
245 //---------------------------------------------------------------------------
247 // Function: EplObdAddInstance()
249 // Description: adds a new instance
251 // Parameters: pInitParam_p
253 // Return: tEplKernel
257 //---------------------------------------------------------------------------
259 EPLDLLEXPORT tEplKernel
EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam
*pInitParam_p
)
262 EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret
;
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();
271 // save init parameters
272 EPL_MEMCPY(&EPL_MCO_GLB_VAR(m_ObdInitParam
), pInitParam_p
,
273 sizeof(tEplObdInitParam
));
275 // clear callback function for command LOAD and STORE
276 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback
) = NULL
;
278 // sign instance as used
279 EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed
);
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
);
290 //---------------------------------------------------------------------------
292 // Function: EplObdDeleteInstance()
294 // Description: delete instance
296 // Parameters: EPL_MCO_DECL_INSTANCE_PTR
298 // Return: tEplKernel
302 //---------------------------------------------------------------------------
303 #if (EPL_USE_DELETEINST_FUNC != FALSE)
304 EPLDLLEXPORT tEplKernel
EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR
)
306 // check for all API function if instance is valid
307 EPL_MCO_CHECK_INSTANCE_STATE();
309 // sign instance as unused
310 EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused
);
312 return kEplSuccessful
;
315 #endif // (EPL_USE_DELETEINST_FUNC != FALSE)
317 //---------------------------------------------------------------------------
319 // Function: EplObdWriteEntry()
321 // Description: Function writes data to an OBD entry. Strings
322 // are stored with added '\0' character.
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
330 // Return: tEplKernel = Errorcode
335 //---------------------------------------------------------------------------
337 EPLDLLEXPORT tEplKernel
EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
338 unsigned int uiSubIndex_p
,
344 tEplObdEntryPtr pObdEntry
;
345 tEplObdSubEntryPtr pSubEntry
;
346 tEplObdCbParam CbParam
;
350 Ret
= EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
356 &pObdEntry
, &pSubEntry
, &CbParam
, &ObdSize
);
357 if (Ret
!= kEplSuccessful
) {
361 Ret
= EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
364 &CbParam
, pSrcData_p
, pDstData
, ObdSize
);
365 if (Ret
!= kEplSuccessful
) {
375 //---------------------------------------------------------------------------
377 // Function: EplObdReadEntry()
379 // Description: The function reads an object entry. The application
380 // can always read the data even if attrib kEplObdAccRead
381 // is not set. The attrib is only checked up for SDO transfer.
383 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
384 // uiIndex_p = Index oof the OD entry to read
385 // uiSubIndex_p = Subindex to read
386 // pDstData_p = pointer to the buffer for data
387 // Offset_p = offset in data for read access
388 // pSize_p = IN: Size of the buffer
389 // OUT: number of readed Bytes
391 // Return: tEplKernel
395 //---------------------------------------------------------------------------
397 EPLDLLEXPORT tEplKernel
EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
398 unsigned int uiSubIndex_p
,
400 tEplObdSize
*pSize_p
)
404 tEplObdEntryPtr pObdEntry
;
405 tEplObdSubEntryPtr pSubEntry
;
406 tEplObdCbParam CbParam
;
410 // check for all API function if instance is valid
411 EPL_MCO_CHECK_INSTANCE_STATE();
413 ASSERT(pDstData_p
!= NULL
);
414 ASSERT(pSize_p
!= NULL
);
416 // get address of index and subindex entry
417 Ret
= EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
418 uiIndex_p
, uiSubIndex_p
, &pObdEntry
, &pSubEntry
);
419 if (Ret
!= kEplSuccessful
) {
422 // get pointer to object data
423 pSrcData
= EplObdGetObjectDataPtrIntern(pSubEntry
);
425 // check source pointer
426 if (pSrcData
== NULL
) {
427 Ret
= kEplObdReadViolation
;
430 //------------------------------------------------------------------------
431 // address of source data to structure of callback parameters
432 // so callback function can change this data before reading
433 CbParam
.m_uiIndex
= uiIndex_p
;
434 CbParam
.m_uiSubIndex
= uiSubIndex_p
;
435 CbParam
.m_pArg
= pSrcData
;
436 CbParam
.m_ObdEvent
= kEplObdEvPreRead
;
437 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
438 pObdEntry
->m_fpCallback
, &CbParam
);
439 if (Ret
!= kEplSuccessful
) {
442 // get size of data and check if application has reserved enough memory
443 ObdSize
= EplObdGetDataSizeIntern(pSubEntry
);
444 // check if offset given and calc correct number of bytes to read
445 if (*pSize_p
< ObdSize
) {
446 Ret
= kEplObdValueLengthError
;
449 // read value from object
450 EPL_MEMCPY(pDstData_p
, pSrcData
, ObdSize
);
453 // write address of destination data to structure of callback parameters
454 // so callback function can change this data after reading
455 CbParam
.m_pArg
= pDstData_p
;
456 CbParam
.m_ObdEvent
= kEplObdEvPostRead
;
457 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
458 pObdEntry
->m_fpCallback
, &CbParam
);
466 //---------------------------------------------------------------------------
468 // Function: EplObdAccessOdPart()
470 // Description: restores default values of one part of OD
472 // Parameters: ObdPart_p
475 // Return: tEplKernel
479 //---------------------------------------------------------------------------
481 EPLDLLEXPORT tEplKernel
EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p
,
482 tEplObdDir Direction_p
)
485 tEplKernel Ret
= kEplSuccessful
;
487 tEplObdEntryPtr pObdEntry
;
489 // check for all API function if instance is valid
490 EPL_MCO_CHECK_INSTANCE_STATE();
492 // part always has to be unequal to NULL
493 pObdEntry
= EPL_MCO_GLB_VAR(m_ObdInitParam
.m_pPart
);
494 ASSERTMSG(pObdEntry
!= NULL
,
495 "EplObdAccessOdPart(): no OD part is defined!\n");
497 // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart
501 if ((ObdPart_p
& kEplObdPartGen
) != 0) {
504 Ret
= EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
505 kEplObdPartGen
, pObdEntry
,
507 if (Ret
!= kEplSuccessful
) {
511 // access to manufacturer part
512 pObdEntry
= EPL_MCO_GLB_VAR(m_ObdInitParam
.m_pManufacturerPart
);
514 if (((ObdPart_p
& kEplObdPartMan
) != 0) && (pObdEntry
!= NULL
)) {
517 Ret
= EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
518 kEplObdPartMan
, pObdEntry
,
520 if (Ret
!= kEplSuccessful
) {
524 // access to device part
525 pObdEntry
= EPL_MCO_GLB_VAR(m_ObdInitParam
.m_pDevicePart
);
527 if (((ObdPart_p
& kEplObdPartDev
) != 0) && (pObdEntry
!= NULL
)) {
530 Ret
= EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
531 kEplObdPartDev
, pObdEntry
,
533 if (Ret
!= kEplSuccessful
) {
537 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
539 // access to user part
540 pObdEntry
= EPL_MCO_GLB_VAR(m_ObdInitParam
.m_pUserPart
);
542 if (((ObdPart_p
& kEplObdPartUsr
) != 0) && (pObdEntry
!= NULL
)) {
545 Ret
= EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
547 pObdEntry
, Direction_p
);
548 if (Ret
!= kEplSuccessful
) {
555 // no access to an OD part was done? illegal OD part was specified!
556 if (fPartFount
== FALSE
) {
557 Ret
= kEplObdIllegalPart
;
566 //---------------------------------------------------------------------------
568 // Function: EplObdDefineVar()
570 // Description: defines a variable in OD
572 // Parameters: pEplVarParam_p
574 // Return: tEplKernel
578 //---------------------------------------------------------------------------
580 EPLDLLEXPORT tEplKernel
EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam
*pVarParam_p
)
584 tEplObdVarEntry
*pVarEntry
;
585 tEplVarParamValid VarValid
;
586 tEplObdSubEntryPtr pSubindexEntry
;
588 // check for all API function if instance is valid
589 EPL_MCO_CHECK_INSTANCE_STATE();
591 ASSERT(pVarParam_p
!= NULL
); // is not allowed to be NULL
593 // get address of subindex entry
594 Ret
= EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
595 pVarParam_p
->m_uiIndex
,
596 pVarParam_p
->m_uiSubindex
, NULL
, &pSubindexEntry
);
597 if (Ret
!= kEplSuccessful
) {
601 Ret
= EplObdGetVarEntry(pSubindexEntry
, &pVarEntry
);
602 if (Ret
!= kEplSuccessful
) {
606 VarValid
= pVarParam_p
->m_ValidFlag
;
608 // copy only this values, which valid flag is set
609 if ((VarValid
& kVarValidSize
) != 0) {
610 if (pSubindexEntry
->m_Type
!= kEplObdTypDomain
) {
611 tEplObdSize DataSize
;
613 // check passed size parameter
614 DataSize
= EplObdGetObjectSize(pSubindexEntry
);
615 if (DataSize
!= pVarParam_p
->m_Size
) { // size of variable does not match
616 Ret
= kEplObdValueLengthError
;
619 } else { // size can be set only for objects of type DOMAIN
620 pVarEntry
->m_Size
= pVarParam_p
->m_Size
;
624 if ((VarValid
& kVarValidData
) != 0) {
625 pVarEntry
->m_pData
= pVarParam_p
->m_pData
;
628 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
630 if ((VarValid & kVarValidCallback) != 0)
632 pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback;
635 if ((VarValid & kVarValidArg) != 0)
637 pVarEntry->m_pArg = pVarParam_p->m_pArg;
642 // Ret is already set to kEplSuccessful from ObdGetVarIntern()
650 //---------------------------------------------------------------------------
652 // Function: EplObdGetObjectDataPtr()
654 // Description: It returnes the current data pointer. But if object is an
655 // constant object it returnes the default pointer.
657 // Parameters: uiIndex_p = Index of the entry
658 // uiSubindex_p = Subindex of the entry
660 // Return: void * = pointer to object data
664 //---------------------------------------------------------------------------
666 EPLDLLEXPORT
void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
667 unsigned int uiSubIndex_p
)
671 tEplObdEntryPtr pObdEntry
;
672 tEplObdSubEntryPtr pObdSubEntry
;
674 // get pointer to index structure
675 Ret
= EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam
),
676 uiIndex_p
, &pObdEntry
);
677 if (Ret
!= kEplSuccessful
) {
681 // get pointer to subindex structure
682 Ret
= EplObdGetSubindexIntern(pObdEntry
, uiSubIndex_p
, &pObdSubEntry
);
683 if (Ret
!= kEplSuccessful
) {
688 pData
= EplObdGetObjectDataPtrIntern(pObdSubEntry
);
695 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
697 //---------------------------------------------------------------------------
699 // Function: EplObdRegisterUserOd()
701 // Description: function registers the user OD
703 // Parameters: pUserOd_p =pointer to user ODd
705 // Return: tEplKernel = errorcode
709 //---------------------------------------------------------------------------
710 EPLDLLEXPORT tEplKernel
EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p
)
713 EPL_MCO_CHECK_INSTANCE_STATE();
715 EPL_MCO_GLB_VAR(m_ObdInitParam
.m_pUserPart
) = pUserOd_p
;
717 return kEplSuccessful
;
723 //---------------------------------------------------------------------------
725 // Function: EplObdInitVarEntry()
727 // Description: function to initialize VarEntry dependened on object type
729 // Parameters: pVarEntry_p = pointer to var entry structure
730 // Type_p = object type
731 // ObdSize_p = size of object data
737 //---------------------------------------------------------------------------
739 EPLDLLEXPORT
void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry
*pVarEntry_p
,
740 tEplObdType Type_p
, tEplObdSize ObdSize_p
)
743 #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
745 // reset pointer to VAR callback and argument
746 pVarEntry_p->m_fpCallback = NULL;
747 pVarEntry_p->m_pArg = NULL;
752 // 10-dec-2004 r.d.: this function will not be used for strings
753 if ((Type_p
== kEplObdTypDomain
))
754 // (bType_p == kEplObdTypVString) /* ||
755 // (bType_p == kEplObdTypOString) ||
756 // (bType_p == kEplObdTypUString) */ )
758 // variables which are defined as DOMAIN or VSTRING should not point to
759 // trash object, because this trash object contains only 8 bytes. DOMAINS or
760 // STRINGS can be longer.
761 pVarEntry_p
->m_pData
= NULL
;
762 pVarEntry_p
->m_Size
= 0;
764 // set address to variable data to trash object
765 // This prevents an access violation if user forgets to call EplObdDefineVar()
766 // for this variable but mappes it in a PDO.
767 pVarEntry_p
->m_pData
= &abEplObdTrashObject_g
[0];
768 pVarEntry_p
->m_Size
= ObdSize_p
;
773 //---------------------------------------------------------------------------
775 // Function: EplObdGetDataSize()
777 // Description: function to initialize VarEntry dependened on object type
779 // gets the data size of an object
780 // for string objects it returnes the string length
782 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
784 // uiSubIndex_p= Subindex
786 // Return: tEplObdSize
790 //---------------------------------------------------------------------------
791 EPLDLLEXPORT tEplObdSize
EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
792 unsigned int uiSubIndex_p
)
796 tEplObdEntryPtr pObdEntry
;
797 tEplObdSubEntryPtr pObdSubEntry
;
799 // get pointer to index structure
800 Ret
= EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam
),
801 uiIndex_p
, &pObdEntry
);
802 if (Ret
!= kEplSuccessful
) {
806 // get pointer to subindex structure
807 Ret
= EplObdGetSubindexIntern(pObdEntry
, uiSubIndex_p
, &pObdSubEntry
);
808 if (Ret
!= kEplSuccessful
) {
813 ObdSize
= EplObdGetDataSizeIntern(pObdSubEntry
);
818 //---------------------------------------------------------------------------
820 // Function: EplObdGetNodeId()
822 // Description: function returns nodeid from entry 0x1F93
825 // Parameters: EPL_MCO_DECL_INSTANCE_PTR = Instancepointer
827 // Return: unsigned int = Node Id
831 //---------------------------------------------------------------------------
832 EPLDLLEXPORT
unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR
)
839 ObdSize
= sizeof(bNodeId
);
840 Ret
= EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
841 EPL_OBD_NODE_ID_INDEX
,
842 EPL_OBD_NODE_ID_SUBINDEX
, &bNodeId
, &ObdSize
);
843 if (Ret
!= kEplSuccessful
) {
844 bNodeId
= EPL_C_ADR_INVALID
;
849 return (unsigned int)bNodeId
;
853 //---------------------------------------------------------------------------
855 // Function: EplObdSetNodeId()
857 // Description: function sets nodeid in entry 0x1F93
860 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
861 // uiNodeId_p = Node Id to set
862 // NodeIdType_p= Type on which way the Node Id was set
864 // Return: tEplKernel = Errorcode
868 //---------------------------------------------------------------------------
869 EPLDLLEXPORT tEplKernel
EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
unsigned int uiNodeId_p
,
870 tEplObdNodeIdType NodeIdType_p
)
878 if (uiNodeId_p
== EPL_C_ADR_INVALID
) {
879 Ret
= kEplInvalidNodeId
;
882 bNodeId
= (BYTE
) uiNodeId_p
;
883 ObdSize
= sizeof(BYTE
);
884 // write NodeId to OD entry
885 Ret
= EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
886 EPL_OBD_NODE_ID_INDEX
,
887 EPL_OBD_NODE_ID_SUBINDEX
, &bNodeId
, ObdSize
);
888 if (Ret
!= kEplSuccessful
) {
891 // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
892 switch (NodeIdType_p
) {
894 case kEplObdNodeIdUnknown
:
900 case kEplObdNodeIdSoftware
:
906 case kEplObdNodeIdHardware
:
917 } // end of switch (NodeIdType_p)
920 ObdSize
= sizeof(fHwBool
);
921 Ret
= EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR
922 EPL_OBD_NODE_ID_INDEX
,
923 EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
,
925 if (Ret
!= kEplSuccessful
) {
933 //---------------------------------------------------------------------------
935 // Function: EplObdIsNumerical()
937 // Description: function checks if a entry is numerical or not
940 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
942 // uiSubIndex_p = Subindex
943 // pfEntryNumerical_p = pointer to BOOL for returnvalue
944 // -> TRUE if entry a numerical value
945 // -> FALSE if entry not a numerical value
947 // Return: tEplKernel = Errorcode
951 //---------------------------------------------------------------------------
952 EPLDLLEXPORT tEplKernel
EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
953 unsigned int uiSubIndex_p
,
954 BOOL
*pfEntryNumerical_p
)
957 tEplObdEntryPtr pObdEntry
;
958 tEplObdSubEntryPtr pObdSubEntry
;
960 // get pointer to index structure
961 Ret
= EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam
),
962 uiIndex_p
, &pObdEntry
);
963 if (Ret
!= kEplSuccessful
) {
966 // get pointer to subindex structure
967 Ret
= EplObdGetSubindexIntern(pObdEntry
, uiSubIndex_p
, &pObdSubEntry
);
968 if (Ret
!= kEplSuccessful
) {
972 Ret
= EplObdIsNumericalIntern(pObdSubEntry
, pfEntryNumerical_p
);
979 //---------------------------------------------------------------------------
981 // Function: EplObdReadEntryToLe()
983 // Description: The function reads an object entry from the byteoder
984 // of the system to the little endian byteorder for numerical values.
985 // For other types a normal read will be processed. This is usefull for
986 // the PDO and SDO module. The application
987 // can always read the data even if attrib kEplObdAccRead
988 // is not set. The attrib is only checked up for SDO transfer.
990 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
991 // uiIndex_p = Index of the OD entry to read
992 // uiSubIndex_p = Subindex to read
993 // pDstData_p = pointer to the buffer for data
994 // Offset_p = offset in data for read access
995 // pSize_p = IN: Size of the buffer
996 // OUT: number of readed Bytes
998 // Return: tEplKernel
1002 //---------------------------------------------------------------------------
1003 EPLDLLEXPORT tEplKernel
EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
1004 unsigned int uiSubIndex_p
,
1006 tEplObdSize
*pSize_p
)
1009 tEplObdEntryPtr pObdEntry
;
1010 tEplObdSubEntryPtr pSubEntry
;
1011 tEplObdCbParam CbParam
;
1013 tEplObdSize ObdSize
;
1015 // check for all API function if instance is valid
1016 EPL_MCO_CHECK_INSTANCE_STATE();
1018 ASSERT(pDstData_p
!= NULL
);
1019 ASSERT(pSize_p
!= NULL
);
1021 // get address of index and subindex entry
1022 Ret
= EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1023 uiIndex_p
, uiSubIndex_p
, &pObdEntry
, &pSubEntry
);
1024 if (Ret
!= kEplSuccessful
) {
1027 // get pointer to object data
1028 pSrcData
= EplObdGetObjectDataPtrIntern(pSubEntry
);
1030 // check source pointer
1031 if (pSrcData
== NULL
) {
1032 Ret
= kEplObdReadViolation
;
1035 //------------------------------------------------------------------------
1036 // address of source data to structure of callback parameters
1037 // so callback function can change this data before reading
1038 CbParam
.m_uiIndex
= uiIndex_p
;
1039 CbParam
.m_uiSubIndex
= uiSubIndex_p
;
1040 CbParam
.m_pArg
= pSrcData
;
1041 CbParam
.m_ObdEvent
= kEplObdEvPreRead
;
1042 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1043 pObdEntry
->m_fpCallback
, &CbParam
);
1044 if (Ret
!= kEplSuccessful
) {
1047 // get size of data and check if application has reserved enough memory
1048 ObdSize
= EplObdGetDataSizeIntern(pSubEntry
);
1049 // check if offset given and calc correct number of bytes to read
1050 if (*pSize_p
< ObdSize
) {
1051 Ret
= kEplObdValueLengthError
;
1054 // check if numerical type
1055 switch (pSubEntry
->m_Type
) {
1056 //-----------------------------------------------
1057 // types without ami
1058 case kEplObdTypVString
:
1059 case kEplObdTypOString
:
1060 case kEplObdTypDomain
:
1063 // read value from object
1064 EPL_MEMCPY(pDstData_p
, pSrcData
, ObdSize
);
1068 //-----------------------------------------------
1069 // numerical type which needs ami-write
1070 // 8 bit or smaller values
1071 case kEplObdTypBool
:
1072 case kEplObdTypInt8
:
1073 case kEplObdTypUInt8
:
1075 AmiSetByteToLe(pDstData_p
, *((BYTE
*) pSrcData
));
1080 case kEplObdTypInt16
:
1081 case kEplObdTypUInt16
:
1083 AmiSetWordToLe(pDstData_p
, *((WORD
*) pSrcData
));
1088 case kEplObdTypInt24
:
1089 case kEplObdTypUInt24
:
1091 AmiSetDword24ToLe(pDstData_p
, *((DWORD
*) pSrcData
));
1096 case kEplObdTypInt32
:
1097 case kEplObdTypUInt32
:
1098 case kEplObdTypReal32
:
1100 AmiSetDwordToLe(pDstData_p
, *((DWORD
*) pSrcData
));
1105 case kEplObdTypInt40
:
1106 case kEplObdTypUInt40
:
1108 AmiSetQword40ToLe(pDstData_p
, *((QWORD
*) pSrcData
));
1113 case kEplObdTypInt48
:
1114 case kEplObdTypUInt48
:
1116 AmiSetQword48ToLe(pDstData_p
, *((QWORD
*) pSrcData
));
1121 case kEplObdTypInt56
:
1122 case kEplObdTypUInt56
:
1124 AmiSetQword56ToLe(pDstData_p
, *((QWORD
*) pSrcData
));
1129 case kEplObdTypInt64
:
1130 case kEplObdTypUInt64
:
1131 case kEplObdTypReal64
:
1133 AmiSetQword64ToLe(pDstData_p
, *((QWORD
*) pSrcData
));
1138 case kEplObdTypTimeOfDay
:
1139 case kEplObdTypTimeDiff
:
1141 AmiSetTimeOfDay(pDstData_p
, ((tTimeOfDay
*) pSrcData
));
1145 } // end of switch(pSubEntry->m_Type)
1149 // write address of destination data to structure of callback parameters
1150 // so callback function can change this data after reading
1151 CbParam
.m_pArg
= pDstData_p
;
1152 CbParam
.m_ObdEvent
= kEplObdEvPostRead
;
1153 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1154 pObdEntry
->m_fpCallback
, &CbParam
);
1162 //---------------------------------------------------------------------------
1164 // Function: EplObdWriteEntryFromLe()
1166 // Description: Function writes data to an OBD entry from a source with
1167 // little endian byteorder to the od with system specuific
1168 // byteorder. Not numerical values will only by copied. Strings
1169 // are stored with added '\0' character.
1171 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1172 // uiIndex_p = Index of the OD entry
1173 // uiSubIndex_p = Subindex of the OD Entry
1174 // pSrcData_p = Pointer to the data to write
1175 // Size_p = Size of the data in Byte
1177 // Return: tEplKernel = Errorcode
1182 //---------------------------------------------------------------------------
1183 EPLDLLEXPORT tEplKernel
EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
1184 unsigned int uiSubIndex_p
,
1189 tEplObdEntryPtr pObdEntry
;
1190 tEplObdSubEntryPtr pSubEntry
;
1191 tEplObdCbParam CbParam
;
1193 tEplObdSize ObdSize
;
1195 void *pBuffer
= &qwBuffer
;
1197 Ret
= EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
1203 &pObdEntry
, &pSubEntry
, &CbParam
, &ObdSize
);
1204 if (Ret
!= kEplSuccessful
) {
1208 // check if numerical type
1209 switch (pSubEntry
->m_Type
) {
1210 //-----------------------------------------------
1211 // types without ami
1213 { // do nothing, i.e. use the given source pointer
1214 pBuffer
= pSrcData_p
;
1218 //-----------------------------------------------
1219 // numerical type which needs ami-write
1220 // 8 bit or smaller values
1221 case kEplObdTypBool
:
1222 case kEplObdTypInt8
:
1223 case kEplObdTypUInt8
:
1225 *((BYTE
*) pBuffer
) = AmiGetByteFromLe(pSrcData_p
);
1230 case kEplObdTypInt16
:
1231 case kEplObdTypUInt16
:
1233 *((WORD
*) pBuffer
) = AmiGetWordFromLe(pSrcData_p
);
1238 case kEplObdTypInt24
:
1239 case kEplObdTypUInt24
:
1241 *((DWORD
*) pBuffer
) = AmiGetDword24FromLe(pSrcData_p
);
1246 case kEplObdTypInt32
:
1247 case kEplObdTypUInt32
:
1248 case kEplObdTypReal32
:
1250 *((DWORD
*) pBuffer
) = AmiGetDwordFromLe(pSrcData_p
);
1255 case kEplObdTypInt40
:
1256 case kEplObdTypUInt40
:
1258 *((QWORD
*) pBuffer
) = AmiGetQword40FromLe(pSrcData_p
);
1263 case kEplObdTypInt48
:
1264 case kEplObdTypUInt48
:
1266 *((QWORD
*) pBuffer
) = AmiGetQword48FromLe(pSrcData_p
);
1271 case kEplObdTypInt56
:
1272 case kEplObdTypUInt56
:
1274 *((QWORD
*) pBuffer
) = AmiGetQword56FromLe(pSrcData_p
);
1279 case kEplObdTypInt64
:
1280 case kEplObdTypUInt64
:
1281 case kEplObdTypReal64
:
1283 *((QWORD
*) pBuffer
) = AmiGetQword64FromLe(pSrcData_p
);
1288 case kEplObdTypTimeOfDay
:
1289 case kEplObdTypTimeDiff
:
1291 AmiGetTimeOfDay(pBuffer
, ((tTimeOfDay
*) pSrcData_p
));
1295 } // end of switch(pSubEntry->m_Type)
1297 Ret
= EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
1300 &CbParam
, pBuffer
, pDstData
, ObdSize
);
1301 if (Ret
!= kEplSuccessful
) {
1311 //---------------------------------------------------------------------------
1313 // Function: EplObdGetAccessType()
1315 // Description: Function returns accesstype of the entry
1317 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1318 // uiIndex_p = Index of the OD entry
1319 // uiSubIndex_p = Subindex of the OD Entry
1320 // pAccessTyp_p = pointer to buffer to store accesstype
1322 // Return: tEplKernel = errorcode
1327 //---------------------------------------------------------------------------
1328 EPLDLLEXPORT tEplKernel
EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
1329 unsigned int uiSubIndex_p
,
1330 tEplObdAccess
*pAccessTyp_p
)
1333 tEplObdEntryPtr pObdEntry
;
1334 tEplObdSubEntryPtr pObdSubEntry
;
1336 // get pointer to index structure
1337 Ret
= EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam
),
1338 uiIndex_p
, &pObdEntry
);
1339 if (Ret
!= kEplSuccessful
) {
1342 // get pointer to subindex structure
1343 Ret
= EplObdGetSubindexIntern(pObdEntry
, uiSubIndex_p
, &pObdSubEntry
);
1344 if (Ret
!= kEplSuccessful
) {
1348 *pAccessTyp_p
= pObdSubEntry
->m_Access
;
1354 //---------------------------------------------------------------------------
1356 // Function: EplObdSearchVarEntry()
1358 // Description: gets variable from OD
1360 // Parameters: uiIndex_p = index of the var entry to search
1361 // uiSubindex_p = subindex of var entry to search
1362 // ppVarEntry_p = pointer to the pointer to the varentry
1364 // Return: tEplKernel
1368 //---------------------------------------------------------------------------
1370 tEplKernel
EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
1371 unsigned int uiSubindex_p
,
1372 tEplObdVarEntry
**ppVarEntry_p
)
1376 tEplObdSubEntryPtr pSubindexEntry
;
1378 // check for all API function if instance is valid
1379 EPL_MCO_CHECK_INSTANCE_STATE();
1381 // get address of subindex entry
1382 Ret
= EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1383 uiIndex_p
, uiSubindex_p
, NULL
, &pSubindexEntry
);
1384 if (Ret
== kEplSuccessful
) {
1386 Ret
= EplObdGetVarEntry(pSubindexEntry
, ppVarEntry_p
);
1393 //=========================================================================//
1395 // P R I V A T E D E F I N I T I O N S //
1397 //=========================================================================//
1399 EPL_MCO_DECL_INSTANCE_FCT()
1400 //---------------------------------------------------------------------------
1402 // Function: EplObdCallObjectCallback()
1404 // Description: calls callback function of an object or of a variable
1406 // Parameters: fpCallback_p
1409 // Return: tEplKernel
1413 //---------------------------------------------------------------------------
1414 static tEplKernel
EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
1415 tEplObdCallback fpCallback_p
,
1416 tEplObdCbParam
*pCbParam_p
)
1420 tEplObdCallback fpCallback
;
1422 // check for all API function if instance is valid
1423 EPL_MCO_CHECK_INSTANCE_STATE();
1425 ASSERT(pCbParam_p
!= NULL
);
1427 Ret
= kEplSuccessful
;
1429 // check address of callback function before calling it
1430 if (fpCallback_p
!= NULL
) {
1431 // KEIL C51 V6.01 has a bug.
1432 // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback.
1433 fpCallback
= fpCallback_p
;
1435 // call callback function for this object
1436 Ret
= fpCallback(EPL_MCO_INSTANCE_PARAM_IDX_()
1443 //---------------------------------------------------------------------------
1445 // Function: EplObdGetDataSizeIntern()
1447 // Description: gets the data size of an object
1448 // for string objects it returnes the string length
1450 // Parameters: pSubIndexEntry_p
1452 // Return: tEplObdSize
1456 //---------------------------------------------------------------------------
1458 static tEplObdSize
EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p
)
1461 tEplObdSize DataSize
;
1464 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
1465 // then the current pointer is always NULL. The function
1466 // returns the length of default string.
1467 DataSize
= EplObdGetObjectSize(pSubIndexEntry_p
);
1469 if (pSubIndexEntry_p
->m_Type
== kEplObdTypVString
) {
1470 // The pointer to current value can be received from EplObdGetObjectCurrentPtr()
1471 pData
= ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p
));
1472 if (pData
!= NULL
) {
1474 EplObdGetStrLen((void *)pData
, DataSize
,
1475 pSubIndexEntry_p
->m_Type
);
1484 //---------------------------------------------------------------------------
1486 // Function: EplObdGetStrLen()
1488 // Description: The function calculates the length of string. The '\0'
1489 // character is included!!
1491 // Parameters: pObjData_p = pointer to string
1492 // ObjLen_p = max. length of objectr entry
1493 // bObjType_p = object type (VSTRING, ...)
1495 // Returns: string length + 1
1499 //---------------------------------------------------------------------------
1501 static tEplObdSize
EplObdGetStrLen(void *pObjData_p
,
1502 tEplObdSize ObjLen_p
, tEplObdType ObjType_p
)
1505 tEplObdSize StrLen
= 0;
1508 if (pObjData_p
== NULL
) {
1511 //----------------------------------------
1512 // Visible String: data format byte
1513 if (ObjType_p
== kEplObdTypVString
) {
1514 pbString
= pObjData_p
;
1516 for (StrLen
= 0; StrLen
< ObjLen_p
; StrLen
++) {
1517 if (*pbString
== '\0') {
1525 //----------------------------------------
1526 // other string types ...
1533 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1535 //---------------------------------------------------------------------------
1537 // Function: EplObdCheckObjectRange()
1539 // Description: function to check value range of object data
1541 // NOTICE: The pointer of data (pData_p) must point out to an even address,
1542 // if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is
1543 // always realiced because pointer m_pDefault points always to an
1544 // array of the SPECIFIED type.
1546 // Parameters: pSubindexEntry_p
1549 // Return: tEplKernel
1553 //---------------------------------------------------------------------------
1555 static tEplKernel
EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p
,
1562 ASSERTMSG(pSubindexEntry_p
!= NULL
,
1563 "EplObdCheckObjectRange(): no address to subindex struct!\n");
1565 Ret
= kEplSuccessful
;
1567 // check if data range has to be checked
1568 if ((pSubindexEntry_p
->m_Access
& kEplObdAccRange
) == 0) {
1571 // get address of default data
1572 pRangeData
= pSubindexEntry_p
->m_pDefault
;
1574 // jump to called object type
1575 switch ((tEplObdType
) pSubindexEntry_p
->m_Type
) {
1576 // -----------------------------------------------------------------
1577 // ObdType kEplObdTypBool will not be checked because there are only
1578 // two possible values 0 or 1.
1580 // -----------------------------------------------------------------
1581 // ObdTypes which has to be check up because numerical values
1582 case kEplObdTypInt8
:
1584 // switch to lower limit
1585 pRangeData
= ((tEplObdInteger8
*) pRangeData
) + 1;
1587 // check if value is to low
1588 if (*((tEplObdInteger8
*) pData_p
) <
1589 *((tEplObdInteger8
*) pRangeData
)) {
1590 Ret
= kEplObdValueTooLow
;
1593 // switch to higher limit
1594 pRangeData
= ((tEplObdInteger8
*) pRangeData
) + 1;
1596 // check if value is to high
1597 if (*((tEplObdInteger8
*) pData_p
) >
1598 *((tEplObdInteger8
*) pRangeData
)) {
1599 Ret
= kEplObdValueTooHigh
;
1604 case kEplObdTypUInt8
:
1606 // switch to lower limit
1607 pRangeData
= ((tEplObdUnsigned8
*) pRangeData
) + 1;
1609 // check if value is to low
1610 if (*((tEplObdUnsigned8
*) pData_p
) <
1611 *((tEplObdUnsigned8
*) pRangeData
)) {
1612 Ret
= kEplObdValueTooLow
;
1615 // switch to higher limit
1616 pRangeData
= ((tEplObdUnsigned8
*) pRangeData
) + 1;
1618 // check if value is to high
1619 if (*((tEplObdUnsigned8
*) pData_p
) >
1620 *((tEplObdUnsigned8
*) pRangeData
)) {
1621 Ret
= kEplObdValueTooHigh
;
1626 case kEplObdTypInt16
:
1628 // switch to lower limit
1629 pRangeData
= ((tEplObdInteger16
*) pRangeData
) + 1;
1631 // check if value is to low
1632 if (*((tEplObdInteger16
*) pData_p
) <
1633 *((tEplObdInteger16
*) pRangeData
)) {
1634 Ret
= kEplObdValueTooLow
;
1637 // switch to higher limit
1638 pRangeData
= ((tEplObdInteger16
*) pRangeData
) + 1;
1640 // check if value is to high
1641 if (*((tEplObdInteger16
*) pData_p
) >
1642 *((tEplObdInteger16
*) pRangeData
)) {
1643 Ret
= kEplObdValueTooHigh
;
1648 case kEplObdTypUInt16
:
1650 // switch to lower limit
1651 pRangeData
= ((tEplObdUnsigned16
*) pRangeData
) + 1;
1653 // check if value is to low
1654 if (*((tEplObdUnsigned16
*) pData_p
) <
1655 *((tEplObdUnsigned16
*) pRangeData
)) {
1656 Ret
= kEplObdValueTooLow
;
1659 // switch to higher limit
1660 pRangeData
= ((tEplObdUnsigned16
*) pRangeData
) + 1;
1662 // check if value is to high
1663 if (*((tEplObdUnsigned16
*) pData_p
) >
1664 *((tEplObdUnsigned16
*) pRangeData
)) {
1665 Ret
= kEplObdValueTooHigh
;
1670 case kEplObdTypInt32
:
1672 // switch to lower limit
1673 pRangeData
= ((tEplObdInteger32
*) pRangeData
) + 1;
1675 // check if value is to low
1676 if (*((tEplObdInteger32
*) pData_p
) <
1677 *((tEplObdInteger32
*) pRangeData
)) {
1678 Ret
= kEplObdValueTooLow
;
1681 // switch to higher limit
1682 pRangeData
= ((tEplObdInteger32
*) pRangeData
) + 1;
1684 // check if value is to high
1685 if (*((tEplObdInteger32
*) pData_p
) >
1686 *((tEplObdInteger32
*) pRangeData
)) {
1687 Ret
= kEplObdValueTooHigh
;
1692 case kEplObdTypUInt32
:
1694 // switch to lower limit
1695 pRangeData
= ((tEplObdUnsigned32
*) pRangeData
) + 1;
1697 // check if value is to low
1698 if (*((tEplObdUnsigned32
*) pData_p
) <
1699 *((tEplObdUnsigned32
*) pRangeData
)) {
1700 Ret
= kEplObdValueTooLow
;
1703 // switch to higher limit
1704 pRangeData
= ((tEplObdUnsigned32
*) pRangeData
) + 1;
1706 // check if value is to high
1707 if (*((tEplObdUnsigned32
*) pData_p
) >
1708 *((tEplObdUnsigned32
*) pRangeData
)) {
1709 Ret
= kEplObdValueTooHigh
;
1714 case kEplObdTypReal32
:
1716 // switch to lower limit
1717 pRangeData
= ((tEplObdReal32
*) pRangeData
) + 1;
1719 // check if value is to low
1720 if (*((tEplObdReal32
*) pData_p
) <
1721 *((tEplObdReal32
*) pRangeData
)) {
1722 Ret
= kEplObdValueTooLow
;
1725 // switch to higher limit
1726 pRangeData
= ((tEplObdReal32
*) pRangeData
) + 1;
1728 // check if value is to high
1729 if (*((tEplObdReal32
*) pData_p
) >
1730 *((tEplObdReal32
*) pRangeData
)) {
1731 Ret
= kEplObdValueTooHigh
;
1736 // -----------------------------------------------------------------
1737 case kEplObdTypInt40
:
1738 case kEplObdTypInt48
:
1739 case kEplObdTypInt56
:
1740 case kEplObdTypInt64
:
1742 // switch to lower limit
1743 pRangeData
= ((signed QWORD
*)pRangeData
) + 1;
1745 // check if value is to low
1746 if (*((signed QWORD
*)pData_p
) < *((signed QWORD
*)pRangeData
)) {
1747 Ret
= kEplObdValueTooLow
;
1750 // switch to higher limit
1751 pRangeData
= ((signed QWORD
*)pRangeData
) + 1;
1753 // check if value is to high
1754 if (*((signed QWORD
*)pData_p
) > *((signed QWORD
*)pRangeData
)) {
1755 Ret
= kEplObdValueTooHigh
;
1760 // -----------------------------------------------------------------
1761 case kEplObdTypUInt40
:
1762 case kEplObdTypUInt48
:
1763 case kEplObdTypUInt56
:
1764 case kEplObdTypUInt64
:
1766 // switch to lower limit
1767 pRangeData
= ((unsigned QWORD
*)pRangeData
) + 1;
1769 // check if value is to low
1770 if (*((unsigned QWORD
*)pData_p
) <
1771 *((unsigned QWORD
*)pRangeData
)) {
1772 Ret
= kEplObdValueTooLow
;
1775 // switch to higher limit
1776 pRangeData
= ((unsigned QWORD
*)pRangeData
) + 1;
1778 // check if value is to high
1779 if (*((unsigned QWORD
*)pData_p
) >
1780 *((unsigned QWORD
*)pRangeData
)) {
1781 Ret
= kEplObdValueTooHigh
;
1786 // -----------------------------------------------------------------
1787 case kEplObdTypReal64
:
1789 // switch to lower limit
1790 pRangeData
= ((tEplObdReal64
*) pRangeData
) + 1;
1792 // check if value is to low
1793 if (*((tEplObdReal64
*) pData_p
) <
1794 *((tEplObdReal64
*) pRangeData
)) {
1795 Ret
= kEplObdValueTooLow
;
1798 // switch to higher limit
1799 pRangeData
= ((tEplObdReal64
*) pRangeData
) + 1;
1801 // check if value is to high
1802 if (*((tEplObdReal64
*) pData_p
) >
1803 *((tEplObdReal64
*) pRangeData
)) {
1804 Ret
= kEplObdValueTooHigh
;
1809 // -----------------------------------------------------------------
1810 case kEplObdTypTimeOfDay
:
1811 case kEplObdTypTimeDiff
:
1814 // -----------------------------------------------------------------
1815 // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because
1816 // they have no numerical value.
1819 Ret
= kEplObdUnknownObjectType
;
1828 #endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1830 //---------------------------------------------------------------------------
1832 // Function: EplObdWriteEntryPre()
1834 // Description: Function prepares write of data to an OBD entry. Strings
1835 // are stored with added '\0' character.
1837 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
1838 // uiIndex_p = Index of the OD entry
1839 // uiSubIndex_p = Subindex of the OD Entry
1840 // pSrcData_p = Pointer to the data to write
1841 // Size_p = Size of the data in Byte
1843 // Return: tEplKernel = Errorcode
1848 //---------------------------------------------------------------------------
1850 static tEplKernel
EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p
,
1851 unsigned int uiSubIndex_p
,
1855 tEplObdEntryPtr
*ppObdEntry_p
,
1856 tEplObdSubEntryPtr
*ppSubEntry_p
,
1857 tEplObdCbParam
*pCbParam_p
,
1858 tEplObdSize
*pObdSize_p
)
1862 tEplObdEntryPtr pObdEntry
;
1863 tEplObdSubEntryPtr pSubEntry
;
1864 tEplObdAccess Access
;
1866 tEplObdSize ObdSize
;
1867 BOOL fEntryNumerical
;
1869 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1870 tEplObdVStringDomain MemVStringDomain
;
1874 // check for all API function if instance is valid
1875 EPL_MCO_CHECK_INSTANCE_STATE();
1877 ASSERT(pSrcData_p
!= NULL
); // should never be NULL
1879 //------------------------------------------------------------------------
1880 // get address of index and subindex entry
1881 Ret
= EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
1882 uiIndex_p
, uiSubIndex_p
, &pObdEntry
, &pSubEntry
);
1883 if (Ret
!= kEplSuccessful
) {
1886 // get pointer to object data
1887 pDstData
= (void *)EplObdGetObjectDataPtrIntern(pSubEntry
);
1889 Access
= (tEplObdAccess
) pSubEntry
->m_Access
;
1891 // check access for write
1892 // access violation if adress to current value is NULL
1893 if (((Access
& kEplObdAccConst
) != 0) || (pDstData
== NULL
)) {
1894 Ret
= kEplObdAccessViolation
;
1897 //------------------------------------------------------------------------
1898 // get size of object
1899 // -as ObdSize = ObdGetObjectSize (pSubEntry);
1901 //------------------------------------------------------------------------
1902 // To use the same callback function for ObdWriteEntry as well as for
1903 // an SDO download call at first (kEplObdEvPre...) the callback function
1904 // with the argument pointer to object size.
1905 pCbParam_p
->m_uiIndex
= uiIndex_p
;
1906 pCbParam_p
->m_uiSubIndex
= uiSubIndex_p
;
1908 // Because object size and object pointer are
1909 // adapted by user callback function, re-read
1911 ObdSize
= EplObdGetObjectSize(pSubEntry
);
1912 pDstData
= (void *)EplObdGetObjectDataPtrIntern(pSubEntry
);
1914 // 09-dec-2004 r.d.:
1915 // Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
1916 // for String or Domain which lets called module directly change
1917 // the data pointer or size. This prevents a recursive call to
1918 // the callback function if it calls EplObdGetEntry().
1919 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1920 if ((pSubEntry
->m_Type
== kEplObdTypVString
) ||
1921 (pSubEntry
->m_Type
== kEplObdTypDomain
) ||
1922 (pSubEntry
->m_Type
== kEplObdTypOString
)) {
1923 if (pSubEntry
->m_Type
== kEplObdTypVString
) {
1924 // reserve one byte for 0-termination
1925 // -as ObdSize -= 1;
1928 // fill out new arg-struct
1929 MemVStringDomain
.m_DownloadSize
= Size_p
;
1930 MemVStringDomain
.m_ObjSize
= ObdSize
;
1931 MemVStringDomain
.m_pData
= pDstData
;
1933 pCbParam_p
->m_ObdEvent
= kEplObdEvWrStringDomain
;
1934 pCbParam_p
->m_pArg
= &MemVStringDomain
;
1935 // call user callback
1936 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1937 pObdEntry
->m_fpCallback
,
1939 if (Ret
!= kEplSuccessful
) {
1942 // write back new settings
1943 pCurrData
= pSubEntry
->m_pCurrent
;
1944 if ((pSubEntry
->m_Type
== kEplObdTypVString
)
1945 || (pSubEntry
->m_Type
== kEplObdTypOString
)) {
1946 ((tEplObdVString
*)pCurrData
)->m_Size
= MemVStringDomain
.m_ObjSize
;
1947 ((tEplObdVString
*)pCurrData
)->m_pString
= MemVStringDomain
.m_pData
;
1948 } else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
1950 ((tEplObdVarEntry
*)pCurrData
)->m_Size
= MemVStringDomain
.m_ObjSize
;
1951 ((tEplObdVarEntry
*)pCurrData
)->m_pData
= (void *)MemVStringDomain
.m_pData
;
1954 // Because object size and object pointer are
1955 // adapted by user callback function, re-read
1957 ObdSize
= MemVStringDomain
.m_ObjSize
;
1958 pDstData
= (void *)MemVStringDomain
.m_pData
;
1960 #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
1962 // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size
1963 // -as 16.11.04 CbParam.m_pArg = &ObdSize;
1964 // 09-dec-2004 r.d.: CbParam.m_pArg = &Size_p;
1965 pCbParam_p
->m_pArg
= &ObdSize
;
1966 pCbParam_p
->m_ObdEvent
= kEplObdEvInitWrite
;
1967 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
1968 pObdEntry
->m_fpCallback
, pCbParam_p
);
1969 if (Ret
!= kEplSuccessful
) {
1973 if (Size_p
> ObdSize
) {
1974 Ret
= kEplObdValueLengthError
;
1978 if (pSubEntry
->m_Type
== kEplObdTypVString
) {
1979 if (((char *)pSrcData_p
)[Size_p
- 1] == '\0') { // last byte of source string contains null character
1981 // reserve one byte in destination for 0-termination
1983 } else if (Size_p
>= ObdSize
) { // source string is not 0-terminated
1984 // and destination buffer is too short
1985 Ret
= kEplObdValueLengthError
;
1990 Ret
= EplObdIsNumericalIntern(pSubEntry
, &fEntryNumerical
);
1991 if (Ret
!= kEplSuccessful
) {
1995 if ((fEntryNumerical
!= FALSE
)
1996 && (Size_p
!= ObdSize
)) {
1997 // type is numerical, therefor size has to fit, but it does not.
1998 Ret
= kEplObdValueLengthError
;
2001 // use given size, because non-numerical objects can be written with shorter values
2004 // set output parameters
2005 *pObdSize_p
= ObdSize
;
2006 *ppObdEntry_p
= pObdEntry
;
2007 *ppSubEntry_p
= pSubEntry
;
2008 *ppDstData_p
= pDstData
;
2010 // all checks are done
2011 // the caller may now convert the numerial source value to platform byte order in a temporary buffer
2019 //---------------------------------------------------------------------------
2021 // Function: EplObdWriteEntryPost()
2023 // Description: Function finishes write of data to an OBD entry. Strings
2024 // are stored with added '\0' character.
2026 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_
2027 // uiIndex_p = Index of the OD entry
2028 // uiSubIndex_p = Subindex of the OD Entry
2029 // pSrcData_p = Pointer to the data to write
2030 // Size_p = Size of the data in Byte
2032 // Return: tEplKernel = Errorcode
2037 //---------------------------------------------------------------------------
2039 static tEplKernel
EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p
,
2040 tEplObdSubEntryPtr pSubEntry_p
,
2041 tEplObdCbParam
*pCbParam_p
,
2044 tEplObdSize ObdSize_p
)
2049 // caller converted the source value to platform byte order
2050 // now the range of the value may be checked
2052 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
2055 Ret
= EplObdCheckObjectRange(pSubEntry_p
, pSrcData_p
);
2056 if (Ret
!= kEplSuccessful
) {
2062 // now call user callback function to check value
2063 // write address of source data to structure of callback parameters
2064 // so callback function can check this data
2065 pCbParam_p
->m_pArg
= pSrcData_p
;
2066 pCbParam_p
->m_ObdEvent
= kEplObdEvPreWrite
;
2067 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2068 pObdEntry_p
->m_fpCallback
, pCbParam_p
);
2069 if (Ret
!= kEplSuccessful
) {
2072 // copy object data to OBD
2073 EPL_MEMCPY(pDstData_p
, pSrcData_p
, ObdSize_p
);
2075 // terminate string with 0
2076 if (pSubEntry_p
->m_Type
== kEplObdTypVString
) {
2077 ((char *)pDstData_p
)[ObdSize_p
] = '\0';
2079 // write address of destination to structure of callback parameters
2080 // so callback function can change data subsequently
2081 pCbParam_p
->m_pArg
= pDstData_p
;
2082 pCbParam_p
->m_ObdEvent
= kEplObdEvPostWrite
;
2083 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2084 pObdEntry_p
->m_fpCallback
, pCbParam_p
);
2092 //---------------------------------------------------------------------------
2094 // Function: EplObdGetObjectSize()
2096 // Description: function to get size of object
2097 // The function determines if an object type an fixed data type (BYTE, WORD, ...)
2098 // or non fixed object (string, domain). This information is used to decide
2099 // if download data are stored temporary or not. For objects with fixed data length
2100 // and types a value range checking can process.
2101 // For strings the function returns the whole object size not the
2102 // length of string.
2104 // Parameters: pSubIndexEntry_p
2106 // Return: tEplObdSize
2110 //---------------------------------------------------------------------------
2112 static tEplObdSize
EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p
)
2115 tEplObdSize DataSize
= 0;
2118 switch (pSubIndexEntry_p
->m_Type
) {
2119 // -----------------------------------------------------------------
2120 case kEplObdTypBool
:
2125 // -----------------------------------------------------------------
2126 // ObdTypes which has to be check because numerical values
2127 case kEplObdTypInt8
:
2128 DataSize
= sizeof(tEplObdInteger8
);
2131 // -----------------------------------------------------------------
2132 case kEplObdTypUInt8
:
2133 DataSize
= sizeof(tEplObdUnsigned8
);
2136 // -----------------------------------------------------------------
2137 case kEplObdTypInt16
:
2138 DataSize
= sizeof(tEplObdInteger16
);
2141 // -----------------------------------------------------------------
2142 case kEplObdTypUInt16
:
2143 DataSize
= sizeof(tEplObdUnsigned16
);
2146 // -----------------------------------------------------------------
2147 case kEplObdTypInt32
:
2148 DataSize
= sizeof(tEplObdInteger32
);
2151 // -----------------------------------------------------------------
2152 case kEplObdTypUInt32
:
2153 DataSize
= sizeof(tEplObdUnsigned32
);
2156 // -----------------------------------------------------------------
2157 case kEplObdTypReal32
:
2158 DataSize
= sizeof(tEplObdReal32
);
2161 // -----------------------------------------------------------------
2162 // ObdTypes which has to be not checked because not NUM values
2163 case kEplObdTypDomain
:
2165 pData
= (void *)pSubIndexEntry_p
->m_pCurrent
;
2166 if ((void *)pData
!= (void *)NULL
) {
2167 DataSize
= ((tEplObdVarEntry
*) pData
)->m_Size
;
2171 // -----------------------------------------------------------------
2172 case kEplObdTypVString
:
2173 //case kEplObdTypUString:
2175 // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
2176 // then the current pointer is always NULL. The function
2177 // returns the length of default string.
2178 pData
= (void *)pSubIndexEntry_p
->m_pCurrent
;
2179 if ((void *)pData
!= (void *)NULL
) {
2180 // The max. size of strings defined by STRING-Macro is stored in
2181 // tEplObdVString of current value.
2182 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2183 DataSize
= ((tEplObdVString
*) pData
)->m_Size
;
2185 // The current position is not decleared. The string
2186 // is located in ROM, therefor use default pointer.
2187 pData
= (void *)pSubIndexEntry_p
->m_pDefault
;
2188 if ((const void *)pData
!= (const void *)NULL
) {
2189 // The max. size of strings defined by STRING-Macro is stored in
2190 // tEplObdVString of default value.
2191 DataSize
= ((const tEplObdVString
*)pData
)->m_Size
;
2197 // -----------------------------------------------------------------
2198 case kEplObdTypOString
:
2200 pData
= (void *)pSubIndexEntry_p
->m_pCurrent
;
2201 if ((void *)pData
!= (void *)NULL
) {
2202 // The max. size of strings defined by STRING-Macro is stored in
2203 // tEplObdVString of current value.
2204 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2205 DataSize
= ((tEplObdOString
*) pData
)->m_Size
;
2207 // The current position is not decleared. The string
2208 // is located in ROM, therefor use default pointer.
2209 pData
= (void *)pSubIndexEntry_p
->m_pDefault
;
2210 if ((const void *)pData
!= (const void *)NULL
) {
2211 // The max. size of strings defined by STRING-Macro is stored in
2212 // tEplObdVString of default value.
2213 DataSize
= ((const tEplObdOString
*)pData
)->m_Size
;
2218 // -----------------------------------------------------------------
2219 case kEplObdTypInt24
:
2220 case kEplObdTypUInt24
:
2225 // -----------------------------------------------------------------
2226 case kEplObdTypInt40
:
2227 case kEplObdTypUInt40
:
2232 // -----------------------------------------------------------------
2233 case kEplObdTypInt48
:
2234 case kEplObdTypUInt48
:
2239 // -----------------------------------------------------------------
2240 case kEplObdTypInt56
:
2241 case kEplObdTypUInt56
:
2246 // -----------------------------------------------------------------
2247 case kEplObdTypInt64
:
2248 case kEplObdTypUInt64
:
2249 case kEplObdTypReal64
:
2254 // -----------------------------------------------------------------
2255 case kEplObdTypTimeOfDay
:
2256 case kEplObdTypTimeDiff
:
2261 // -----------------------------------------------------------------
2269 //---------------------------------------------------------------------------
2271 // Function: EplObdGetObjectDefaultPtr()
2273 // Description: function to get the default pointer (type specific)
2275 // Parameters: pSubIndexEntry_p = pointer to subindex structure
2277 // Returns: (void *) = pointer to default value
2281 //---------------------------------------------------------------------------
2283 static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p
)
2289 ASSERTMSG(pSubIndexEntry_p
!= NULL
,
2290 "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n");
2292 // get address to default data from default pointer
2293 pDefault
= pSubIndexEntry_p
->m_pDefault
;
2294 if (pDefault
!= NULL
) {
2295 // there are some special types, whose default pointer always is NULL or has to get from other structure
2296 // get type from subindex structure
2297 Type
= pSubIndexEntry_p
->m_Type
;
2299 // check if object type is a string value
2300 if ((Type
== kEplObdTypVString
) /* ||
2301 (Type == kEplObdTypUString) */ ) {
2303 // EPL_OBD_SUBINDEX_RAM_VSTRING
2304 // tEplObdSize m_Size; --> size of default string
2305 // char * m_pDefString; --> pointer to default string
2306 // char * m_pString; --> pointer to string in RAM
2309 (void *)((tEplObdVString
*) pDefault
)->m_pString
;
2310 } else if (Type
== kEplObdTypOString
) {
2312 (void *)((tEplObdOString
*) pDefault
)->m_pString
;
2320 //---------------------------------------------------------------------------
2322 // Function: EplObdGetVarEntry()
2324 // Description: gets a variable entry of an object
2326 // Parameters: pSubindexEntry_p
2329 // Return: tCopKernel
2333 //---------------------------------------------------------------------------
2335 static tEplKernel
EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p
,
2336 tEplObdVarEntry
**ppVarEntry_p
)
2339 tEplKernel Ret
= kEplObdVarEntryNotExist
;
2341 ASSERT(ppVarEntry_p
!= NULL
); // is not allowed to be NULL
2342 ASSERT(pSubindexEntry_p
!= NULL
);
2344 // check VAR-Flag - only this object points to variables
2345 if ((pSubindexEntry_p
->m_Access
& kEplObdAccVar
) != 0) {
2346 // check if object is an array
2347 if ((pSubindexEntry_p
->m_Access
& kEplObdAccArray
) != 0) {
2348 *ppVarEntry_p
= &((tEplObdVarEntry
*)pSubindexEntry_p
->m_pCurrent
)[pSubindexEntry_p
->m_uiSubIndex
- 1];
2350 *ppVarEntry_p
= (tEplObdVarEntry
*)pSubindexEntry_p
->m_pCurrent
;
2353 Ret
= kEplSuccessful
;
2360 //---------------------------------------------------------------------------
2362 // Function: EplObdGetEntry()
2364 // Description: gets a index entry from OD
2366 // Parameters: uiIndex_p = Index number
2367 // uiSubindex_p = Subindex number
2368 // ppObdEntry_p = pointer to the pointer to the entry
2369 // ppObdSubEntry_p = pointer to the pointer to the subentry
2371 // Return: tEplKernel
2376 //---------------------------------------------------------------------------
2378 static tEplKernel
EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
2379 unsigned int uiIndex_p
,
2380 unsigned int uiSubindex_p
,
2381 tEplObdEntryPtr
* ppObdEntry_p
,
2382 tEplObdSubEntryPtr
* ppObdSubEntry_p
)
2385 tEplObdEntryPtr pObdEntry
;
2386 tEplObdCbParam CbParam
;
2389 // check for all API function if instance is valid
2390 EPL_MCO_CHECK_INSTANCE_STATE();
2392 //------------------------------------------------------------------------
2393 // get address of entry of index
2395 EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam
), uiIndex_p
,
2397 if (Ret
!= kEplSuccessful
) {
2400 //------------------------------------------------------------------------
2401 // get address of entry of subindex
2402 Ret
= EplObdGetSubindexIntern(pObdEntry
, uiSubindex_p
, ppObdSubEntry_p
);
2403 if (Ret
!= kEplSuccessful
) {
2406 //------------------------------------------------------------------------
2407 // call callback function to inform user/stack that an object will be searched
2408 // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist
2409 CbParam
.m_uiIndex
= uiIndex_p
;
2410 CbParam
.m_uiSubIndex
= uiSubindex_p
;
2411 CbParam
.m_pArg
= NULL
;
2412 CbParam
.m_ObdEvent
= kEplObdEvCheckExist
;
2413 Ret
= EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
2414 pObdEntry
->m_fpCallback
, &CbParam
);
2415 if (Ret
!= kEplSuccessful
) {
2416 Ret
= kEplObdIndexNotExist
;
2419 //------------------------------------------------------------------------
2420 // it is allowed to set ppObdEntry_p to NULL
2421 // if so, no address will be written to calling function
2422 if (ppObdEntry_p
!= NULL
) {
2423 *ppObdEntry_p
= pObdEntry
;
2432 //---------------------------------------------------------------------------
2434 // Function: EplObdGetObjectCurrentPtr()
2436 // Description: function to get Current pointer (type specific)
2438 // Parameters: pSubIndexEntry_p
2444 //---------------------------------------------------------------------------
2446 static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p
)
2450 unsigned int uiArrayIndex
;
2453 pData
= pSubIndexEntry_p
->m_pCurrent
;
2455 // check if constant object
2456 if (pData
!= NULL
) {
2457 // check if object is an array
2458 if ((pSubIndexEntry_p
->m_Access
& kEplObdAccArray
) != 0) {
2459 // calculate correct data pointer
2460 uiArrayIndex
= pSubIndexEntry_p
->m_uiSubIndex
- 1;
2461 if ((pSubIndexEntry_p
->m_Access
& kEplObdAccVar
) != 0) {
2462 Size
= sizeof(tEplObdVarEntry
);
2464 Size
= EplObdGetObjectSize(pSubIndexEntry_p
);
2466 pData
= ((BYTE
*) pData
) + (Size
* uiArrayIndex
);
2468 // check if VarEntry
2469 if ((pSubIndexEntry_p
->m_Access
& kEplObdAccVar
) != 0) {
2470 // The data pointer is stored in VarEntry->pData
2471 pData
= ((tEplObdVarEntry
*) pData
)->m_pData
;
2473 // the default pointer is stored for strings in tEplObdVString
2474 else if ((pSubIndexEntry_p
->m_Type
== kEplObdTypVString
) /* ||
2475 (pSubIndexEntry_p->m_Type == kEplObdTypUString) */
2477 pData
= (void *)((tEplObdVString
*)pData
)->m_pString
;
2478 } else if (pSubIndexEntry_p
->m_Type
== kEplObdTypOString
) {
2480 (void *)((tEplObdOString
*)pData
)->m_pString
;
2488 //---------------------------------------------------------------------------
2490 // Function: EplObdGetIndexIntern()
2492 // Description: gets a index entry from OD
2494 // Parameters: pInitParam_p
2498 // Return: tEplKernel
2502 //---------------------------------------------------------------------------
2504 static tEplKernel
EplObdGetIndexIntern(tEplObdInitParam
*pInitParam_p
,
2505 unsigned int uiIndex_p
,
2506 tEplObdEntryPtr
* ppObdEntry_p
)
2509 tEplObdEntryPtr pObdEntry
;
2511 unsigned int uiIndex
;
2513 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2517 // if user OD is used then objekts also has to be searched in user OD
2518 // there is less code need if we do this in a loop
2523 ASSERTMSG(ppObdEntry_p
!= NULL
,
2524 "EplObdGetIndexIntern(): pointer to index entry is NULL!\n");
2526 Ret
= kEplObdIndexNotExist
;
2528 // get start address of OD part
2529 // start address depends on object index because
2530 // object dictionary is divided in 3 parts
2531 if ((uiIndex_p
>= 0x1000) && (uiIndex_p
< 0x2000)) {
2532 pObdEntry
= pInitParam_p
->m_pPart
;
2533 } else if ((uiIndex_p
>= 0x2000) && (uiIndex_p
< 0x6000)) {
2534 pObdEntry
= pInitParam_p
->m_pManufacturerPart
;
2536 // index range 0xA000 to 0xFFFF is reserved for DSP-405
2537 // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3.
2538 // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE.
2539 // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000...
2540 // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE.
2542 #if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE)
2543 else if ((uiIndex_p
>= 0x6000) && (uiIndex_p
< 0x9FFF))
2545 else if ((uiIndex_p
>= 0x6000) && (uiIndex_p
< 0xFFFF))
2548 pObdEntry
= pInitParam_p
->m_pDevicePart
;
2551 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2553 // if index does not match in static OD then index only has to be searched in user OD
2555 // begin from first entry of user OD part
2556 pObdEntry
= pInitParam_p
->m_pUserPart
;
2558 // no user OD is available
2559 if (pObdEntry
== NULL
) {
2562 // loop must only run once
2570 // no user OD is available
2571 // so other object can be found in OD
2573 Ret
= kEplObdIllegalPart
;
2580 // The end of Index table is marked with m_uiIndex = 0xFFFF.
2581 // If this function will be called with wIndex_p = 0xFFFF, entry
2582 // should not be found. Therefor it is important to use
2583 // while{} instead of do{}while !!!
2585 // get first index of index table
2586 uiIndex
= pObdEntry
->m_uiIndex
;
2588 // search Index in OD part
2589 while (uiIndex
!= EPL_OBD_TABLE_INDEX_END
) {
2590 // go to the end of this function if index is found
2591 if (uiIndex_p
== uiIndex
) {
2592 // write address of OD entry to calling function
2593 *ppObdEntry_p
= pObdEntry
;
2594 Ret
= kEplSuccessful
;
2597 // objects are sorted in OD
2598 // if the current index in OD is greater than the index which is to search then break loop
2599 // in this case user OD has to be search too
2600 if (uiIndex_p
< uiIndex
) {
2603 // next entry in index table
2606 // get next index of index table
2607 uiIndex
= pObdEntry
->m_uiIndex
;
2610 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2612 // begin from first entry of user OD part
2613 pObdEntry
= pInitParam_p
->m_pUserPart
;
2615 // no user OD is available
2616 if (pObdEntry
== NULL
) {
2619 // switch next loop for user OD
2628 // in this line Index was not found
2636 //---------------------------------------------------------------------------
2638 // Function: EplObdGetSubindexIntern()
2640 // Description: gets a subindex entry from a index entry
2642 // Parameters: pObdEntry_p
2646 // Return: tEplKernel
2650 //---------------------------------------------------------------------------
2652 static tEplKernel
EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p
,
2653 unsigned int uiSubIndex_p
,
2654 tEplObdSubEntryPtr
* ppObdSubEntry_p
)
2657 tEplObdSubEntryPtr pSubEntry
;
2658 unsigned int nSubIndexCount
;
2661 ASSERTMSG(pObdEntry_p
!= NULL
,
2662 "EplObdGetSubindexIntern(): pointer to index is NULL!\n");
2663 ASSERTMSG(ppObdSubEntry_p
!= NULL
,
2664 "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n");
2666 Ret
= kEplObdSubindexNotExist
;
2668 // get start address of subindex table and count of subindices
2669 pSubEntry
= pObdEntry_p
->m_pSubIndex
;
2670 nSubIndexCount
= pObdEntry_p
->m_uiCount
;
2671 ASSERTMSG((pSubEntry
!= NULL
) && (nSubIndexCount
> 0), "ObdGetSubindexIntern(): invalid subindex table within index table!\n"); // should never be NULL
2673 // search subindex in subindex table
2674 while (nSubIndexCount
> 0) {
2675 // check if array is found
2676 if ((pSubEntry
->m_Access
& kEplObdAccArray
) != 0) {
2677 // check if subindex is in range
2678 if (uiSubIndex_p
< pObdEntry_p
->m_uiCount
) {
2679 // update subindex number (subindex entry of an array is always in RAM !!!)
2680 pSubEntry
->m_uiSubIndex
= uiSubIndex_p
;
2681 *ppObdSubEntry_p
= pSubEntry
;
2682 Ret
= kEplSuccessful
;
2686 // go to the end of this function if subindex is found
2687 else if (uiSubIndex_p
== pSubEntry
->m_uiSubIndex
) {
2688 *ppObdSubEntry_p
= pSubEntry
;
2689 Ret
= kEplSuccessful
;
2692 // objects are sorted in OD
2693 // if the current subindex in OD is greater than the subindex which is to search then break loop
2694 // in this case user OD has to be search too
2695 if (uiSubIndex_p
< pSubEntry
->m_uiSubIndex
) {
2703 // in this line SubIndex was not fount
2711 //---------------------------------------------------------------------------
2713 // Function: EplObdSetStoreLoadObjCallback()
2715 // Description: function set address to callbackfunction for command Store and Load
2717 // Parameters: fpCallback_p
2719 // Return: tEplKernel
2723 //---------------------------------------------------------------------------
2724 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2725 EPLDLLEXPORT tEplKernel
EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p
)
2728 EPL_MCO_CHECK_INSTANCE_STATE();
2730 // set new address of callback function
2731 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback
) = fpCallback_p
;
2733 return kEplSuccessful
;
2736 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2738 //---------------------------------------------------------------------------
2740 // Function: EplObdAccessOdPartIntern()
2742 // Description: runs through OD and executes a job
2744 // Parameters: CurrentOdPart_p
2746 // Direction_p = what is to do (load values from flash or EEPROM, store, ...)
2748 // Return: tEplKernel
2752 //---------------------------------------------------------------------------
2754 static tEplKernel
EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
2755 tEplObdPart CurrentOdPart_p
,
2756 tEplObdEntryPtr pObdEnty_p
,
2757 tEplObdDir Direction_p
)
2760 tEplObdSubEntryPtr pSubIndex
;
2761 unsigned int nSubIndexCount
;
2762 tEplObdAccess Access
;
2765 tEplObdSize ObjSize
;
2767 tEplObdCbStoreParam CbStore
;
2768 tEplObdVarEntry
*pVarEntry
;
2770 ASSERT(pObdEnty_p
!= NULL
);
2772 Ret
= kEplSuccessful
;
2774 // prepare structure for STORE RESTORE callback function
2775 CbStore
.m_bCurrentOdPart
= (BYTE
) CurrentOdPart_p
;
2776 CbStore
.m_pData
= NULL
;
2777 CbStore
.m_ObjSize
= 0;
2779 // command of first action depends on direction to access
2780 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2781 if (Direction_p
== kEplObdDirLoad
) {
2782 CbStore
.m_bCommand
= (BYTE
) kEplObdCommOpenRead
;
2784 // call callback function for previous command
2785 Ret
= EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_
& CbStore
);
2786 if (Ret
!= kEplSuccessful
) {
2789 // set command for index and subindex loop
2790 CbStore
.m_bCommand
= (BYTE
) kEplObdCommReadObj
;
2791 } else if (Direction_p
== kEplObdDirStore
) {
2792 CbStore
.m_bCommand
= (BYTE
) kEplObdCommOpenWrite
;
2794 // call callback function for previous command
2795 Ret
= EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_
& CbStore
);
2796 if (Ret
!= kEplSuccessful
) {
2799 // set command for index and subindex loop
2800 CbStore
.m_bCommand
= (BYTE
) kEplObdCommWriteObj
;
2802 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2804 // we should not restore the OD values here
2805 // the next NMT command "Reset Node" or "Reset Communication" resets the OD data
2806 if (Direction_p
!= kEplObdDirRestore
) {
2807 // walk through OD part till end is found
2808 while (pObdEnty_p
->m_uiIndex
!= EPL_OBD_TABLE_INDEX_END
) {
2809 // get address to subindex table and count of subindices
2810 pSubIndex
= pObdEnty_p
->m_pSubIndex
;
2811 nSubIndexCount
= pObdEnty_p
->m_uiCount
;
2812 ASSERT((pSubIndex
!= NULL
) && (nSubIndexCount
> 0)); // should never be NULL
2814 // walk through subindex table till all subinices were restored
2815 while (nSubIndexCount
!= 0) {
2816 Access
= (tEplObdAccess
) pSubIndex
->m_Access
;
2818 // get pointer to current and default data
2819 pDefault
= EplObdGetObjectDefaultPtr(pSubIndex
);
2820 pDstData
= EplObdGetObjectCurrentPtr(pSubIndex
);
2822 // NOTE (for kEplObdTypVString):
2823 // The function returnes the max. number of bytes for a
2825 // r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit).
2826 ObjSize
= EplObdGetObjectSize(pSubIndex
);
2828 // switch direction of OD access
2829 switch (Direction_p
) {
2830 // --------------------------------------------------------------------------
2831 // VarEntry structures has to be initialized
2832 case kEplObdDirInit
:
2834 // If VAR-Flag is set, m_pCurrent means not address of data
2835 // but address of tEplObdVarEntry. Address of data has to be get from
2837 if ((Access
& kEplObdAccVar
) != 0) {
2838 EplObdGetVarEntry(pSubIndex
,
2840 EplObdInitVarEntry(pVarEntry
,
2845 if ((Access & kEplObdAccArray) == 0)
2847 EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize);
2851 EplObdInitVarEntry ((tEplObdVarEntry *) (((BYTE *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
2852 pSubIndex->m_Type, ObjSize);
2855 // at this time no application variable is defined !!!
2856 // therefore data can not be copied.
2858 } else if (pSubIndex
->m_Type
==
2859 kEplObdTypVString
) {
2860 // If pointer m_pCurrent is not equal to NULL then the
2861 // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current
2862 // pointer points to struct tEplObdVString located in MEM.
2863 // The element size includes the max. number of
2864 // bytes. The element m_pString includes the pointer
2865 // to string in MEM. The memory location of default string
2866 // must be copied to memory location of current string.
2869 pSubIndex
->m_pCurrent
;
2870 if (pDstData
!= NULL
) {
2871 // 08-dec-2004: code optimization !!!
2872 // entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString
2873 // and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read
2874 // twice. thats not necessary!
2876 // For copying data we have to set the destination pointer to the real RAM string. This
2877 // pointer to RAM string is located in default string info structure. (translated r.d.)
2878 pDstData
= (void *)((tEplObdVStringDef
*) pSubIndex
->m_pDefault
)->m_pString
;
2879 ObjSize
= ((tEplObdVStringDef
*)pSubIndex
->m_pDefault
)->m_Size
;
2881 ((tEplObdVString
*)pSubIndex
->m_pCurrent
)->m_pString
= pDstData
;
2882 ((tEplObdVString
*)pSubIndex
->m_pCurrent
)->m_Size
= ObjSize
;
2885 } else if (pSubIndex
->m_Type
==
2886 kEplObdTypOString
) {
2888 pSubIndex
->m_pCurrent
;
2889 if (pDstData
!= NULL
) {
2890 // 08-dec-2004: code optimization !!!
2891 // entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString
2892 // and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read
2893 // twice. thats not necessary!
2895 // For copying data we have to set the destination pointer to the real RAM string. This
2896 // pointer to RAM string is located in default string info structure. (translated r.d.)
2897 pDstData
= (void *)((tEplObdOStringDef
*) pSubIndex
->m_pDefault
)->m_pString
;
2898 ObjSize
= ((tEplObdOStringDef
*)pSubIndex
->m_pDefault
)->m_Size
;
2900 ((tEplObdOString
*)pSubIndex
->m_pCurrent
)->m_pString
= pDstData
;
2901 ((tEplObdOString
*)pSubIndex
->m_pCurrent
)->m_Size
= ObjSize
;
2906 // no break !! because copy of data has to done too.
2908 // --------------------------------------------------------------------------
2909 // all objects has to be restored with default values
2910 case kEplObdDirRestore
:
2912 // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad
2913 // is replaced to function ObdCopyObjectData() with a new parameter.
2915 // restore object data for init phase
2916 EplObdCopyObjectData(pDstData
, pDefault
,
2921 // --------------------------------------------------------------------------
2922 // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file
2923 case kEplObdDirLoad
:
2925 // restore object data for init phase
2926 EplObdCopyObjectData(pDstData
, pDefault
,
2930 // no break !! because callback function has to be called too.
2932 // --------------------------------------------------------------------------
2933 // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file
2934 case kEplObdDirStore
:
2936 // when attribute kEplObdAccStore is set, then call callback function
2937 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2938 if ((Access
& kEplObdAccStore
) != 0) {
2939 // fill out data pointer and size of data
2940 CbStore
.m_pData
= pDstData
;
2941 CbStore
.m_ObjSize
= ObjSize
;
2943 // call callback function for read or write object
2945 ObdCallStoreCallback
2946 (EPL_MCO_INSTANCE_PTR_
&
2948 if (Ret
!= kEplSuccessful
) {
2952 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
2955 // --------------------------------------------------------------------------
2956 // if OD Builder key has to be checked no access to subindex and data should be made
2957 case kEplObdDirOBKCheck
:
2959 // no break !! because we want to break the second loop too.
2961 // --------------------------------------------------------------------------
2962 // unknown Direction
2965 // so we can break the second loop earler
2972 // next subindex entry
2973 if ((Access
& kEplObdAccArray
) == 0) {
2975 if ((nSubIndexCount
> 0)
2978 m_Access
& kEplObdAccArray
) !=
2980 // next subindex points to an array
2981 // reset subindex number
2982 pSubIndex
->m_uiSubIndex
= 1;
2985 if (nSubIndexCount
> 0) {
2986 // next subindex points to an array
2987 // increment subindex number
2988 pSubIndex
->m_uiSubIndex
++;
2997 // -----------------------------------------------------------------------------------------
2998 // command of last action depends on direction to access
2999 if (Direction_p
== kEplObdDirOBKCheck
) {
3003 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3005 if (Direction_p
== kEplObdDirLoad
) {
3006 CbStore
.m_bCommand
= (BYTE
) kEplObdCommCloseRead
;
3007 } else if (Direction_p
== kEplObdDirStore
) {
3008 CbStore
.m_bCommand
= (BYTE
) kEplObdCommCloseWrite
;
3009 } else if (Direction_p
== kEplObdDirRestore
) {
3010 CbStore
.m_bCommand
= (BYTE
) kEplObdCommClear
;
3015 // call callback function for last command
3016 Ret
= EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_
& CbStore
);
3018 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3028 // ----------------------------------------------------------------------------
3029 // Function: EplObdCopyObjectData()
3031 // Description: checks pointers to object data and copy them from source to destination
3033 // Parameters: pDstData_p = destination pointer
3034 // pSrcData_p = source pointer
3035 // ObjSize_p = size of object
3038 // Returns: tEplKernel = error code
3039 // ----------------------------------------------------------------------------
3041 static void EplObdCopyObjectData(void *pDstData_p
,
3043 tEplObdSize ObjSize_p
, tEplObdType ObjType_p
)
3046 tEplObdSize StrSize
= 0;
3048 // it is allowed to set default and current address to NULL (nothing to copy)
3049 if (pDstData_p
!= NULL
) {
3051 if (ObjType_p
== kEplObdTypVString
) {
3052 // The function calculates the really number of characters of string. The
3053 // object entry size can be bigger as string size of default string.
3054 // The '\0'-termination is included. A string with no characters has a
3057 EplObdGetStrLen((void *)pSrcData_p
, ObjSize_p
,
3060 // If the string length is greater than or equal to the entry size in OD then only copy
3061 // entry size - 1 and always set the '\0'-termination.
3062 if (StrSize
>= ObjSize_p
) {
3063 StrSize
= ObjSize_p
- 1;
3067 if (pSrcData_p
!= NULL
) {
3069 EPL_MEMCPY(pDstData_p
, pSrcData_p
, ObjSize_p
);
3071 if (ObjType_p
== kEplObdTypVString
) {
3072 ((char *)pDstData_p
)[StrSize
] = '\0';
3079 //---------------------------------------------------------------------------
3081 // Function: EplObdIsNumericalIntern()
3083 // Description: function checks if a entry is numerical or not
3086 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
3087 // uiIndex_p = Index
3088 // uiSubIndex_p = Subindex
3089 // pfEntryNumerical_p = pointer to BOOL for returnvalue
3090 // -> TRUE if entry a numerical value
3091 // -> FALSE if entry not a numerical value
3093 // Return: tEplKernel = Errorcode
3097 //---------------------------------------------------------------------------
3098 static tEplKernel
EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p
,
3099 BOOL
* pfEntryNumerical_p
)
3101 tEplKernel Ret
= kEplSuccessful
;
3104 if ((pObdSubEntry_p
->m_Type
== kEplObdTypVString
)
3105 || (pObdSubEntry_p
->m_Type
== kEplObdTypOString
)
3106 || (pObdSubEntry_p
->m_Type
== kEplObdTypDomain
)) { // not numerical types
3107 *pfEntryNumerical_p
= FALSE
;
3108 } else { // numerical types
3109 *pfEntryNumerical_p
= TRUE
;
3116 // -------------------------------------------------------------------------
3117 // function to classify object type (fixed/non fixed)
3118 // -------------------------------------------------------------------------
3120 // ----------------------------------------------------------------------------
3121 // Function: EplObdCallStoreCallback()
3123 // Description: checks address to callback function and calles it when unequal
3126 // Parameters: EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer)
3127 // pCbStoreParam_p = address to callback parameters
3129 // Returns: tEplKernel = error code
3130 // ----------------------------------------------------------------------------
3131 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3132 static tEplKernel
EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
3133 tEplObdCbStoreParam
*
3137 tEplKernel Ret
= kEplSuccessful
;
3139 ASSERT(pCbStoreParam_p
!= NULL
);
3141 // check if function pointer is NULL - if so, no callback should be called
3142 if (EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback
) != NULL
) {
3144 EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback
)
3145 (EPL_MCO_INSTANCE_PARAM_IDX_()
3152 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3153 //---------------------------------------------------------------------------
3155 // Function: EplObdGetObjectDataPtrIntern()
3157 // Description: Function gets the data pointer of an object.
3158 // It returnes the current data pointer. But if object is an
3159 // constant object it returnes the default pointer.
3161 // Parameters: pSubindexEntry_p = pointer to subindex entry
3163 // Return: void * = pointer to object data
3167 //---------------------------------------------------------------------------
3169 void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p
)
3173 tEplObdAccess Access
;
3175 ASSERTMSG(pSubindexEntry_p
!= NULL
,
3176 "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n");
3178 // there are are some objects whose data pointer has to get from other structure
3179 // get access type for this object
3180 Access
= pSubindexEntry_p
->m_Access
;
3182 // If object has access type = const,
3183 // for data only exists default values.
3184 if ((Access
& kEplObdAccConst
) != 0) {
3185 // The pointer to defualt value can be received from ObdGetObjectDefaultPtr()
3186 pData
= ((void *)EplObdGetObjectDefaultPtr(pSubindexEntry_p
));
3188 // The pointer to current value can be received from ObdGetObjectCurrentPtr()
3189 pData
= ((void *)EplObdGetObjectCurrentPtr(pSubindexEntry_p
));
3195 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)