1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
25 //#include "SchM_Dem.h"
33 typedef uint16 ChecksumType;
37 Dem_EventStatusExtendedType dtcStatusMask;
38 Dem_DTCKindType dtcKind;
39 Dem_DTCOriginType dtcOrigin;
40 Dem_FilterWithSeverityType filterWithSeverity;
41 Dem_DTCSeverityType dtcSeverityMask;
42 Dem_FilterForFDCType filterForFaultDetectionCounter;
46 // DisableDtcStorageType
48 boolean storageDisabled;
49 Dem_DTCGroupType dtcGroup;
50 Dem_DTCKindType dtcKind;
51 } DisableDtcStorageType;
53 // For keeping track of the events status
55 Dem_EventIdType eventId;
56 const Dem_EventParameterType *eventParamRef;
58 Dem_EventStatusType eventStatus;
59 boolean eventStatusChanged;
60 Dem_EventStatusExtendedType eventStatusExtended;
64 // Types for storing different event data on event memory
66 Dem_EventIdType eventId;
68 ChecksumType checksum;
72 Dem_EventIdType eventId;
75 sint8 data[DEM_MAX_SIZE_FF_DATA];
76 ChecksumType checksum;
80 Dem_EventIdType eventId;
82 uint8 data[DEM_MAX_SIZE_EXT_DATA];
83 ChecksumType checksum;
90 DEM_UNINITIALIZED = 0,
95 static Dem_StateType demState = DEM_UNINITIALIZED;
97 // Help pointer to configuration set
98 static const Dem_ConfigSetType *configSet;
100 #if (DEM_VERSION_INFO_API == STD_ON)
101 static Std_VersionInfoType _Dem_VersionInfo =
103 .vendorID = (uint16)1,
104 .moduleID = (uint16)1,
105 .instanceID = (uint8)1,
106 .sw_major_version = (uint8)DEM_SW_MAJOR_VERSION,
107 .sw_minor_version = (uint8)DEM_SW_MINOR_VERSION,
108 .sw_patch_version = (uint8)DEM_SW_PATCH_VERSION,
109 .ar_major_version = (uint8)DEM_AR_MAJOR_VERSION,
110 .ar_minor_version = (uint8)DEM_AR_MINOR_VERSION,
111 .ar_patch_version = (uint8)DEM_AR_PATCH_VERSION,
113 #endif /* DEM_VERSION_INFO_API */
116 * Allocation of DTC filter parameters
118 static DtcFilterType dtcFilter;
121 * Allocation of Disable/Enable DTC storage parameters
123 static DisableDtcStorageType disableDtcStorage;
126 * Allocation of operation cycle state list
128 static Dem_OperationCycleStateType operationCycleStateList[DEM_OPERATION_CYCLE_ID_ENDMARK];
131 * Allocation of local event status buffer
133 static EventStatusRecType eventStatusBuffer[DEM_MAX_NUMBER_EVENT];
136 * Allocation of pre-init event memory (used between pre-init and init)
138 static FreezeFrameRecType preInitFreezeFrameBuffer[DEM_MAX_NUMBER_FF_DATA_PRE_INIT];
139 static ExtDataRecType preInitExtDataBuffer[DEM_MAX_NUMBER_EXT_DATA_PRE_INIT];
142 * Allocation of primary event memory ramlog (after init) in uninitialized memory
144 static EventRecType priMemEventBuffer[DEM_MAX_NUMBER_EVENT_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));
145 static FreezeFrameRecType priMemFreezeFrameBuffer[DEM_MAX_NUMBER_FF_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));
146 static ExtDataRecType priMemExtDataBuffer[DEM_MAX_NUMBER_EXT_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));
150 * Procedure: zeroPriMemBuffers
151 * Description: Fill the primary buffers with zeroes
153 void zeroPriMemBuffers(void)
155 memset(priMemEventBuffer, 0, sizeof(priMemEventBuffer));
156 memset(priMemFreezeFrameBuffer, 0, sizeof(priMemFreezeFrameBuffer));
157 memset(priMemExtDataBuffer, 0, sizeof(priMemExtDataBuffer));
162 * Procedure: calcChecksum
163 * Description: Calculate checksum over *data to *(data+nrOfBytes-1) area
165 ChecksumType calcChecksum(void *data, uint16 nrOfBytes)
168 uint8 *ptr = (uint8*)data;
169 ChecksumType sum = 0;
171 for (i = 0; i < nrOfBytes; i++)
179 * Procedure: checkDtcKind
180 * Description: Return TRUE if "dtcKind" match the events DTCKind or "dtcKind"
181 * is "DEM_DTC_KIND_ALL_DTCS" otherwise FALSE.
183 boolean checkDtcKind(Dem_DTCKindType dtcKind, const Dem_EventParameterType *eventParam)
185 boolean result = FALSE;
187 if (dtcKind == DEM_DTC_KIND_ALL_DTCS) {
191 if (eventParam->DTCClassRef != NULL) {
192 if (eventParam->DTCClassRef->DTCKind == dtcKind) {
202 * Procedure: checkDtcGroup
203 * Description: Return TRUE if "dtc" match the events DTC or "dtc" is
204 * "DEM_DTC_GROUP_ALL_DTCS" otherwise FALSE.
206 boolean checkDtcGroup(uint32 dtc, const Dem_EventParameterType *eventParam)
208 boolean result = FALSE;
210 if (dtc == DEM_DTC_GROUP_ALL_DTCS) {
214 if (eventParam->DTCClassRef != NULL) {
215 if (eventParam->DTCClassRef->DTC == dtc) {
225 * Procedure: checkDtcOrigin
226 * Description: Return TRUE if "dtcOrigin" match any of the events DTCOrigin otherwise FALSE.
228 boolean checkDtcOrigin(Dem_DTCOriginType dtcOrigin, const Dem_EventParameterType *eventParam)
230 boolean result = FALSE;
233 for (i = 0; (eventParam->EventClass->EventDestination[i] != dtcOrigin) && (i < DEM_MAX_NR_OF_EVENT_DESTINATION); i++);
235 if (i < DEM_MAX_NR_OF_EVENT_DESTINATION) {
244 * Procedure: checkDtcSeverityMask
245 * Description: Return TRUE if "dtcSeverityMask" match any of the events DTC severity otherwise FALSE.
247 boolean checkDtcSeverityMask(Dem_DTCSeverityType dtcSeverityMask, const Dem_EventParameterType *eventParam)
249 boolean result = TRUE;
251 // TODO: This function is optional, may be implemented here.
258 * Procedure: checkDtcFaultDetectionCounterMask
261 boolean checkDtcFaultDetectionCounter(const Dem_EventParameterType *eventParam)
263 boolean result = TRUE;
265 // TODO: Not implemented yet.
272 * Procedure: lookupEventStatusRec
273 * Description: Returns the pointer to event id parameters of "eventId" in "*eventStatusBuffer",
274 * if not found NULL is returned.
276 void lookupEventStatusRec(Dem_EventIdType eventId, EventStatusRecType **const eventStatusRec)
278 EventStatusRecType *eventStatusRecPtr = eventStatusBuffer;
280 while ((eventStatusRecPtr->eventId != eventId) && (eventStatusRecPtr < &eventStatusBuffer[DEM_MAX_NUMBER_EVENT])) {
284 if (eventStatusRecPtr < &eventStatusBuffer[DEM_MAX_NUMBER_EVENT]) {
285 *eventStatusRec = eventStatusRecPtr;
287 *eventStatusRec = NULL;
293 * Procedure: lookupEventIdParameter
294 * Description: Returns the pointer to event id parameters of "eventId" in "*eventIdParam",
295 * if not found NULL is returned.
297 void lookupEventIdParameter(Dem_EventIdType eventId, const Dem_EventParameterType **const eventIdParam)
299 const Dem_EventParameterType *EventIdParamPtr = configSet->EventParameter;
301 // Lookup the correct event id parameters
302 while ((EventIdParamPtr->EventID != eventId) && !EventIdParamPtr->Arc_EOL) {
306 if (!EventIdParamPtr->Arc_EOL) {
307 *eventIdParam = EventIdParamPtr;
309 *eventIdParam = NULL;
314 * Procedure: updateEventStatusRec
315 * Description: Update the status of "eventId", if not exist and "createIfNotExist" is
316 * true a new record is created
318 void updateEventStatusRec(const Dem_EventParameterType *eventParam, Dem_EventStatusType eventStatus, boolean createIfNotExist, EventStatusRecType *eventStatusRec)
320 EventStatusRecType *eventStatusRecPtr;
321 imask_t state = McuE_EnterCriticalSection();
324 lookupEventStatusRec(eventParam->EventID, &eventStatusRecPtr);
326 if ((eventStatusRecPtr == NULL) && (createIfNotExist)) {
327 // Search for free position
328 lookupEventStatusRec(DEM_EVENT_ID_NULL, &eventStatusRecPtr);
330 if (eventStatusRecPtr != NULL) {
331 // Create new event record
332 eventStatusRecPtr->eventId = eventParam->EventID;
333 eventStatusRecPtr->eventParamRef = eventParam;
334 eventStatusRecPtr->occurrence = 0;
335 eventStatusRecPtr->eventStatus = DEM_EVENT_STATUS_PASSED;
336 eventStatusRecPtr->eventStatusChanged = FALSE;
337 eventStatusRecPtr->eventStatusExtended = DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE;
340 // Error: Event status buffer full
341 #if (DEM_DEV_ERROR_DETECT == STD_ON)
342 Det_ReportError(MODULE_ID_DEM, 0, DEM_UPDATE_EVENT_STATUS_ID, DEM_E_EVENT_STATUS_BUFF_FULL);
347 if (eventStatusRecPtr != NULL) {
348 // Update event record
349 eventStatusRecPtr->eventStatusExtended &= ~(DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE);
351 if (eventStatus == DEM_EVENT_STATUS_FAILED) {
352 eventStatusRecPtr->eventStatusExtended |= (DEM_TEST_FAILED | DEM_TEST_FAILED_THIS_OPERATION_CYCLE | DEM_TEST_FAILED_SINCE_LAST_CLEAR | DEM_PENDING_DTC);
353 if (eventStatusRecPtr->eventStatus != eventStatus) {
354 eventStatusRecPtr->occurrence++;
358 if (eventStatus == DEM_EVENT_STATUS_PASSED) {
359 eventStatusRecPtr->eventStatusExtended &= ~DEM_TEST_FAILED;
362 if (eventStatusRecPtr->eventStatus != eventStatus) {
363 eventStatusRecPtr->eventStatus = eventStatus;
364 eventStatusRecPtr->eventStatusChanged = TRUE;
367 eventStatusRecPtr->eventStatusChanged = FALSE;
371 memcpy(eventStatusRec, eventStatusRecPtr, sizeof(EventStatusRecType));
374 // Copy an empty record to return data
375 eventStatusRec->eventId = DEM_EVENT_ID_NULL;
376 eventStatusRec->eventStatus = DEM_EVENT_STATUS_PASSED;
377 eventStatusRec->occurrence = 0;
378 eventStatusRec->eventStatusChanged = FALSE;
379 eventStatusRec->eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
382 McuE_ExitCriticalSection(state);
387 * Procedure: mergeEventStatusRec
388 * Description: Update the occurrence counter of status, if not exist a new record is created
390 void mergeEventStatusRec(EventRecType *eventRec)
392 EventStatusRecType *eventStatusRecPtr;
393 imask_t state = McuE_EnterCriticalSection();
396 lookupEventStatusRec(eventRec->eventId, &eventStatusRecPtr);
398 if (eventStatusRecPtr != NULL) {
399 // Update occurrence counter, rest of pre init state is kept.
400 eventStatusRecPtr->occurrence += eventRec->occurrence;
404 // Search for free position
405 lookupEventStatusRec(DEM_EVENT_ID_NULL, &eventStatusRecPtr);
407 if (eventStatusRecPtr != NULL) {
408 // Create new event, from stored event
409 eventStatusRecPtr->eventId = eventRec->eventId;
410 lookupEventIdParameter(eventRec->eventId, &eventStatusRecPtr->eventParamRef);
411 eventStatusRecPtr->occurrence = eventRec->occurrence;
412 eventStatusRecPtr->eventStatus = DEM_EVENT_STATUS_PASSED;
413 eventStatusRecPtr->eventStatusChanged = FALSE;
414 eventStatusRecPtr->eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
417 // Error: Event status buffer full
418 #if (DEM_DEV_ERROR_DETECT == STD_ON)
419 Det_ReportError(MODULE_ID_DEM, 0, DEM_MERGE_EVENT_STATUS_ID, DEM_E_EVENT_STATUS_BUFF_FULL);
424 McuE_ExitCriticalSection(state);
429 * Procedure: deleteEventStatusRec
430 * Description: Delete the status record of "eventParam->eventId" from "eventStatusBuffer".
432 void deleteEventStatusRec(const Dem_EventParameterType *eventParam)
434 EventStatusRecType *eventStatusRecPtr;
435 imask_t state = McuE_EnterCriticalSection();
438 lookupEventStatusRec(eventParam->EventID, &eventStatusRecPtr);
440 if (eventStatusRecPtr != NULL) {
441 // Delete event record
442 memset(eventStatusRecPtr, 0, sizeof(EventStatusRecType));
445 McuE_ExitCriticalSection(state);
450 * Procedure: getEventStatusRec
451 * Description: Returns the status record of "eventId" in "eventStatusRec"
453 void getEventStatusRec(Dem_EventIdType eventId, EventStatusRecType *eventStatusRec)
455 EventStatusRecType *eventStatusRecPtr;
458 lookupEventStatusRec(eventId, &eventStatusRecPtr);
460 if (eventStatusRecPtr != NULL) {
462 memcpy(eventStatusRec, eventStatusRecPtr, sizeof(EventStatusRecType));
465 eventStatusRec->eventId = DEM_EVENT_ID_NULL;
466 eventStatusRec->eventStatus = DEM_EVENT_STATUS_PASSED;
467 eventStatusRec->occurrence = 0;
473 * Procedure: lookupDtcEvent
474 * Description: Returns TRUE if the DTC was found and "eventStatusRec" points
475 * to the event record found.
477 boolean lookupDtcEvent(uint32 dtc, EventStatusRecType **eventStatusRec)
479 boolean dtcFound = FALSE;
482 *eventStatusRec = NULL;
484 for (i = 0; (i < DEM_MAX_NUMBER_EVENT) && !dtcFound; i++) {
485 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {
486 if (eventStatusBuffer[i].eventParamRef->DTCClassRef != NULL) {
489 if (eventStatusBuffer[i].eventParamRef->DTCClassRef->DTC == dtc) {
490 *eventStatusRec = &eventStatusBuffer[i];
502 * Procedure: matchEventWithDtcFilter
503 * Description: Returns TRUE if the event pointed by "event" fulfill
504 * the "dtcFilter" global filter settings.
506 boolean matchEventWithDtcFilter(const EventStatusRecType *eventRec)
508 boolean dtcMatch = FALSE;
511 if ((dtcFilter.dtcStatusMask == DEM_DTC_STATUS_MASK_ALL) || (eventRec->eventStatusExtended & dtcFilter.dtcStatusMask)) {
512 if (eventRec->eventParamRef != NULL) {
515 if (checkDtcKind(dtcFilter.dtcKind, eventRec->eventParamRef)) {
518 if (checkDtcOrigin(dtcFilter.dtcOrigin, eventRec->eventParamRef)) {
521 if ((dtcFilter.filterWithSeverity == DEM_FILTER_WITH_SEVERITY_NO)
522 || ((dtcFilter.filterWithSeverity == DEM_FILTER_WITH_SEVERITY_YES) && checkDtcSeverityMask(dtcFilter.dtcSeverityMask, eventRec->eventParamRef))) {
524 // Check fault detection counter
525 if ((dtcFilter.filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_NO)
526 || ((dtcFilter.filterWithSeverity == DEM_FILTER_FOR_FDC_YES) && checkDtcFaultDetectionCounter(eventRec->eventParamRef))) {
539 void getFreezeFrameData(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
542 freezeFrame->eventId = DEM_EVENT_ID_NULL; // Not supported yet
546 void storeFreezeFrameDataPreInit(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
552 void updateFreezeFrameOccurrencePreInit(EventRecType *EventBuffer)
559 * Procedure: getExtendedData
560 * Description: Collects the extended data according to "eventParam" and return it in "extData",
561 * if not found eventId is set to DEM_EVENT_ID_NULL.
563 void getExtendedData(const Dem_EventParameterType *eventParam, ExtDataRecType *extData)
565 Std_ReturnType callbackReturnCode;
567 uint16 storeIndex = 0;
570 // Clear ext data record
571 memset(extData, 0, sizeof(ExtDataRecType));
573 // Check if any pointer to extended data class
574 if (eventParam->ExtendedDataClassRef != NULL) {
575 // Request extended data and copy it to the buffer
576 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_EXTENDED_DATA) && (eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i] != NULL); i++) {
577 recordSize = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->DataSize;
578 if ((storeIndex + recordSize) <= DEM_MAX_SIZE_EXT_DATA) {
579 callbackReturnCode = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->CallbackGetExtDataRecord(&extData->data[storeIndex]);
580 if (callbackReturnCode != E_OK) {
581 // Callback data currently not available, clear space.
582 memset(&extData->data[storeIndex], 0xFF, recordSize);
584 storeIndex += recordSize;
587 // Error: Size of extended data record is bigger than reserved space.
588 #if (DEM_DEV_ERROR_DETECT == STD_ON)
589 Det_ReportError(MODULE_ID_DEM, 0, DEM_GET_EXTENDED_DATA_ID, DEM_E_EXT_DATA_TO_BIG);
591 break; // Break the loop
596 // Check if any data has been stored
597 if (storeIndex != 0) {
598 extData->eventId = eventParam->EventID;
599 extData->dataSize = storeIndex;
600 extData->checksum = calcChecksum(extData, sizeof(ExtDataRecType)-sizeof(ChecksumType));
603 extData->eventId = DEM_EVENT_ID_NULL;
604 extData->dataSize = storeIndex;
605 extData->checksum = 0;
611 * Procedure: storeExtendedDataPreInit
612 * Description: Store the extended data pointed by "extendedData" to the "preInitExtDataBuffer",
613 * if non existent a new entry is created.
615 void storeExtendedDataPreInit(const Dem_EventParameterType *eventParam, ExtDataRecType *extendedData)
618 imask_t state = McuE_EnterCriticalSection();
620 // Check if already stored
621 for (i = 0; (preInitExtDataBuffer[i].eventId != eventParam->EventID) && (i<DEM_MAX_NUMBER_EXT_DATA_PRE_INIT); i++);
623 if (i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT) {
624 // Yes, overwrite existing
625 memcpy(&preInitExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
628 // No, lookup first free position
629 for (i = 0; (preInitExtDataBuffer[i].eventId !=0) && (i<DEM_MAX_NUMBER_EXT_DATA_PRE_INIT); i++);
631 if (i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT) {
632 memcpy(&preInitExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
635 // Error: Pre init extended data buffer full
636 #if (DEM_DEV_ERROR_DETECT == STD_ON)
637 Det_ReportError(MODULE_ID_DEM, 0, DEM_STORE_EXT_DATA_PRE_INIT_ID, DEM_E_PRE_INIT_EXT_DATA_BUFF_FULL);
642 McuE_ExitCriticalSection(state);
647 * Procedure: storeEventPriMem
648 * Description: Store the event data of "eventStatus->eventId" in "priMemEventBuffer",
649 * if non existent a new entry is created.
651 void storeEventPriMem(const Dem_EventParameterType *eventParam, EventStatusRecType *eventStatus)
654 imask_t state = McuE_EnterCriticalSection();
658 for (i = 0; (priMemEventBuffer[i].eventId != eventStatus->eventId) && (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI); i++);
660 if (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) {
661 // Update event found
662 priMemEventBuffer[i].occurrence = eventStatus->occurrence;
663 priMemEventBuffer[i].checksum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));
666 // Search for free position
667 for (i=0; (priMemEventBuffer[i].eventId != DEM_EVENT_ID_NULL) && (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI); i++);
669 if (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) {
670 priMemEventBuffer[i].eventId = eventStatus->eventId;
671 priMemEventBuffer[i].occurrence = eventStatus->occurrence;
672 priMemEventBuffer[i].checksum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));
675 // Error: Pri mem event buffer full
676 #if (DEM_DEV_ERROR_DETECT == STD_ON)
677 Det_ReportError(MODULE_ID_DEM, 0, DEM_STORE_EVENT_PRI_MEM_ID, DEM_E_PRI_MEM_EVENT_BUFF_FULL);
682 McuE_ExitCriticalSection(state);
687 * Procedure: deleteEventPriMem
688 * Description: Delete the event data of "eventParam->eventId" from "priMemEventBuffer".
690 void deleteEventPriMem(const Dem_EventParameterType *eventParam)
693 imask_t state = McuE_EnterCriticalSection();
697 for (i = 0; (priMemEventBuffer[i].eventId != eventParam->EventID) && (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI); i++);
699 if (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) {
700 // Delete event found
701 memset(&priMemEventBuffer[i], 0, sizeof(EventRecType));
704 McuE_ExitCriticalSection(state);
709 * Procedure: storeEventEvtMem
710 * Description: Store the event data of "eventStatus->eventId" in event memory according to
711 * "eventParam" destination option.
713 void storeEventEvtMem(const Dem_EventParameterType *eventParam, EventStatusRecType *eventStatus)
717 for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != NULL); i++) {
718 switch (eventParam->EventClass->EventDestination[i])
720 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
721 storeEventPriMem(eventParam, eventStatus);
724 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
725 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
726 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
728 #if (DEM_DEV_ERROR_DETECT == STD_ON)
729 Det_ReportError(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);
740 * Procedure: storeExtendedDataPriMem
741 * Description: Store the extended data pointed by "extendedData" to the "priMemExtDataBuffer",
742 * if non existent a new entry is created.
744 void storeExtendedDataPriMem(const Dem_EventParameterType *eventParam, ExtDataRecType *extendedData)
747 imask_t state = McuE_EnterCriticalSection();
749 // Check if already stored
750 for (i = 0; (priMemExtDataBuffer[i].eventId != eventParam->EventID) && (i<DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
752 if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
753 // Yes, overwrite existing
754 memcpy(&priMemExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
757 // No, lookup first free position
758 for (i = 0; (priMemExtDataBuffer[i].eventId != DEM_EVENT_ID_NULL) && (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
759 if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
760 memcpy(&priMemExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
763 // Error: Pri mem extended data buffer full
764 #if (DEM_DEV_ERROR_DETECT == STD_ON)
765 Det_ReportError(MODULE_ID_DEM, 0, DEM_STORE_EXT_DATA_PRI_MEM_ID, DEM_E_PRI_MEM_EXT_DATA_BUFF_FULL);
770 McuE_ExitCriticalSection(state);
775 * Procedure: deleteExtendedDataPriMem
776 * Description: Delete the extended data of "eventParam->eventId" from "priMemExtDataBuffer".
778 void deleteExtendedDataPriMem(const Dem_EventParameterType *eventParam)
781 imask_t state = McuE_EnterCriticalSection();
783 // Check if already stored
784 for (i = 0; (priMemExtDataBuffer[i].eventId != eventParam->EventID) && (i<DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
786 if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
788 memset(&priMemExtDataBuffer[i], 0, sizeof(ExtDataRecType));
791 McuE_ExitCriticalSection(state);
796 * Procedure: storeExtendedDataEvtMem
797 * Description: Store the extended data in event memory according to
798 * "eventParam" destination option
800 void storeExtendedDataEvtMem(const Dem_EventParameterType *eventParam, ExtDataRecType *extendedData)
804 for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != NULL); i++) {
805 switch (eventParam->EventClass->EventDestination[i])
807 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
808 storeExtendedDataPriMem(eventParam, extendedData);
811 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
812 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
813 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
815 #if (DEM_DEV_ERROR_DETECT == STD_ON)
816 Det_ReportError(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);
828 * Procedure: lookupExtendedDataRecNumParam
829 * Description: Returns TRUE if the requested extended data number was found among the configured records for the event.
830 * "extDataRecClassPtr" returns a pointer to the record class, "posInExtData" returns the position in stored extended data.
832 boolean lookupExtendedDataRecNumParam(uint8 extendedDataNumber, const Dem_EventParameterType *eventParam, Dem_ExtendedDataRecordClassType const **extDataRecClassPtr, uint8 *posInExtData)
834 boolean recNumFound = FALSE;
836 if (eventParam->ExtendedDataClassRef != NULL) {
837 Dem_ExtendedDataRecordClassType const* const* extDataRecClassRefList = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef;
841 // Request extended data and copy it to the buffer
842 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_EXTENDED_DATA) && (extDataRecClassRefList[i] != NULL) && !recNumFound; i++) {
843 if (extDataRecClassRefList[i]->RecordNumber == extendedDataNumber) {
844 *extDataRecClassPtr = extDataRecClassRefList[i];
845 *posInExtData = byteCnt;
848 byteCnt += extDataRecClassRefList[i]->DataSize;
857 * Procedure: lookupExtendedDataPriMem
858 * Description: Returns TRUE if the requested event id is found, "extData" points to the found data.
860 boolean lookupExtendedDataPriMem(Dem_EventIdType eventId, ExtDataRecType **extData)
862 boolean eventIdFound = FALSE;
865 // Lookup corresponding extended data
866 for (i = 0; (priMemExtDataBuffer[i].eventId != eventId) && (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
868 if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
869 // Yes, return pointer
870 *extData = &priMemExtDataBuffer[i];
878 void storeFreezeFrameDataPriMem(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
884 void deleteFreezeFrameDataPriMem(const Dem_EventParameterType *eventParam)
891 * Procedure: storeFreezeFrameDataEvtMem
892 * Description: Store the freeze frame data in event memory according to
893 * "eventParam" destination option
895 void storeFreezeFrameDataEvtMem(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
899 for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != NULL); i++) {
900 switch (eventParam->EventClass->EventDestination[i])
902 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
903 storeFreezeFrameDataPriMem(eventParam, freezeFrame);
906 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
907 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
908 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
910 #if (DEM_DEV_ERROR_DETECT == STD_ON)
911 Det_ReportError(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);
922 * Procedure: handlePreInitEvent
923 * Description: Handle the updating of event status and storing of
924 * event related data in preInit buffers.
926 void handlePreInitEvent(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)
928 const Dem_EventParameterType *eventParam;
929 EventStatusRecType eventStatusLocal;
930 FreezeFrameRecType freezeFrameLocal;
931 ExtDataRecType extendedDataLocal;
933 // Find configuration for this event
934 lookupEventIdParameter(eventId, &eventParam);
935 if (eventParam != NULL) {
936 if (eventParam->EventClass->OperationCycleRef < DEM_OPERATION_CYCLE_ID_ENDMARK) {
937 if (operationCycleStateList[eventParam->EventClass->OperationCycleRef] == DEM_CYCLE_STATE_START) {
938 if (eventStatus == DEM_EVENT_STATUS_PASSED) {
939 updateEventStatusRec(eventParam, eventStatus, FALSE, &eventStatusLocal);
942 updateEventStatusRec(eventParam, eventStatus, TRUE, &eventStatusLocal);
945 if (eventStatusLocal.eventStatusChanged) {
947 if (eventStatusLocal.eventStatus == DEM_EVENT_STATUS_FAILED) {
948 // Collect freeze frame data
949 getFreezeFrameData(eventParam, &freezeFrameLocal);
950 if (freezeFrameLocal.eventId != DEM_EVENT_ID_NULL) {
951 storeFreezeFrameDataPreInit(eventParam, &freezeFrameLocal);
954 // Collect extended data
955 getExtendedData(eventParam, &extendedDataLocal);
956 if (extendedDataLocal.eventId != DEM_EVENT_ID_NULL) {
957 storeExtendedDataPreInit(eventParam, &extendedDataLocal);
963 // Operation cycle not started
964 // TODO: Report error?
968 // Operation cycle not set
969 // TODO: Report error?
973 // Event ID not configured
974 // TODO: Report error?
980 * Procedure: handleEvent
981 * Description: Handle the updating of event status and storing of
982 * event related data in event memory.
984 Std_ReturnType handleEvent(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)
986 Std_ReturnType returnCode = E_OK;
987 const Dem_EventParameterType *eventParam;
988 EventStatusRecType eventStatusLocal;
989 FreezeFrameRecType freezeFrameLocal;
990 ExtDataRecType extendedDataLocal;
992 // Find configuration for this event
993 lookupEventIdParameter(eventId, &eventParam);
994 if (eventParam != NULL) {
995 if (eventParam->EventClass->OperationCycleRef < DEM_OPERATION_CYCLE_ID_ENDMARK) {
996 if (operationCycleStateList[eventParam->EventClass->OperationCycleRef] == DEM_CYCLE_STATE_START) {
997 if (!(disableDtcStorage.storageDisabled && checkDtcGroup(disableDtcStorage.dtcGroup, eventParam) && checkDtcKind(disableDtcStorage.dtcKind, eventParam))) {
998 updateEventStatusRec(eventParam, eventStatus, TRUE, &eventStatusLocal);
999 if (eventStatusLocal.eventStatusChanged) {
1000 if (eventStatusLocal.eventStatus == DEM_EVENT_STATUS_FAILED) {
1001 storeEventEvtMem(eventParam, &eventStatusLocal);
1002 // Collect freeze frame data
1003 getFreezeFrameData(eventParam, &freezeFrameLocal);
1004 if (freezeFrameLocal.eventId != DEM_EVENT_ID_NULL) {
1005 storeFreezeFrameDataEvtMem(eventParam, &freezeFrameLocal);
1008 // Collect extended data
1009 getExtendedData(eventParam, &extendedDataLocal);
1010 if (extendedDataLocal.eventId != DEM_EVENT_ID_NULL)
1012 storeExtendedDataEvtMem(eventParam, &extendedDataLocal);
1019 // Operation cycle not started
1020 returnCode = E_NOT_OK;
1024 // Operation cycle not set
1025 returnCode = E_NOT_OK;
1029 // Event ID not configured
1030 returnCode = E_NOT_OK;
1038 * Procedure: getEventStatus
1039 * Description: Returns the extended event status bitmask of eventId in "eventStatusExtended".
1041 void getEventStatus(Dem_EventIdType eventId, Dem_EventStatusExtendedType *eventStatusExtended)
1043 EventStatusRecType eventStatusLocal;
1045 // Get recorded status
1046 getEventStatusRec(eventId, &eventStatusLocal);
1047 if (eventStatusLocal.eventId == eventId) {
1048 *eventStatusExtended = eventStatusLocal.eventStatusExtended;
1051 // Event Id not found, no report received.
1052 *eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
1058 * Procedure: getEventFailed
1059 * Description: Returns the TRUE or FALSE of "eventId" in "eventFailed" depending on current status.
1061 void getEventFailed(Dem_EventIdType eventId, boolean *eventFailed)
1063 EventStatusRecType eventStatusLocal;
1065 // Get recorded status
1066 getEventStatusRec(eventId, &eventStatusLocal);
1067 if (eventStatusLocal.eventId == eventId) {
1068 if (eventStatusLocal.eventStatusExtended & DEM_TEST_FAILED) {
1069 *eventFailed = TRUE;
1072 *eventFailed = FALSE;
1076 // Event Id not found, assume ok.
1077 *eventFailed = FALSE;
1083 * Procedure: getEventTested
1084 * Description: Returns the TRUE or FALSE of "eventId" in "eventTested" depending on
1085 * current status the "test not completed this operation cycle" bit.
1087 void getEventTested(Dem_EventIdType eventId, boolean *eventTested)
1089 EventStatusRecType eventStatusLocal;
1091 // Get recorded status
1092 getEventStatusRec(eventId, &eventStatusLocal);
1093 if (eventStatusLocal.eventId == eventId) {
1094 if ( !(eventStatusLocal.eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE)) {
1095 *eventTested = TRUE;
1098 *eventTested = FALSE;
1102 // Event Id not found, not tested.
1103 *eventTested = FALSE;
1109 * Procedure: getFaultDetectionCounter
1110 * Description: Returns pre debounce counter of "eventId" in "counter" and return value E_OK if
1111 * the counter was available else E_NOT_OK.
1113 Std_ReturnType getFaultDetectionCounter(Dem_EventIdType eventId, sint8 *counter)
1115 Std_ReturnType returnCode = E_NOT_OK;
1116 const Dem_EventParameterType *eventParam;
1118 lookupEventIdParameter(eventId, &eventParam);
1119 if (eventParam != NULL) {
1120 if (eventParam->EventClass->PreDebounceAlgorithmClass != NULL) {
1121 switch (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceName)
1123 case DEM_NO_PRE_DEBOUNCE:
1124 if (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal != NULL) {
1125 returnCode = eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal->CallbackGetFDCntFnc(counter);
1129 case DEM_PRE_DEBOUNCE_COUNTER_BASED:
1130 case DEM_PRE_DEBOUNCE_FREQUENCY_BASED:
1131 case DEM_PRE_DEBOUNCE_TIME_BASED:
1132 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1133 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_NOT_IMPLEMENTED_YET);
1138 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1139 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_PARAM_DATA);
1151 * Procedure: setOperationCycleState
1152 * Description: Change the operation state of "operationCycleId" to "cycleState" and updates stored
1153 * event connected to this cycle id.
1154 * Returns E_OK if operation was successful else E_NOT_OK.
1156 Std_ReturnType setOperationCycleState(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState)
1159 Std_ReturnType returnCode = E_OK;
1161 if (operationCycleId < DEM_OPERATION_CYCLE_ID_ENDMARK) {
1164 case DEM_CYCLE_STATE_START:
1165 operationCycleStateList[operationCycleId] = cycleState;
1167 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1168 if ((eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (eventStatusBuffer[i].eventParamRef->EventClass->OperationCycleRef == operationCycleId)) {
1169 eventStatusBuffer[i].eventStatusExtended &= ~DEM_TEST_FAILED_THIS_OPERATION_CYCLE;
1170 eventStatusBuffer[i].eventStatusExtended |= DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE;
1175 case DEM_CYCLE_STATE_END:
1176 operationCycleStateList[operationCycleId] = cycleState;
1178 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1179 if ((eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (eventStatusBuffer[i].eventParamRef->EventClass->OperationCycleRef == operationCycleId)) {
1180 if (!(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_FAILED_THIS_OPERATION_CYCLE) && !(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE)) {
1181 eventStatusBuffer[i].eventStatusExtended &= ~DEM_PENDING_DTC; // Clear pendingDTC bit
1187 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1188 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);
1190 returnCode = E_NOT_OK;
1195 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1196 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);
1198 returnCode = E_NOT_OK;
1205 //==============================================================================//
1207 // E X T E R N A L F U N C T I O N S //
1209 //==============================================================================//
1211 /*********************************************
1212 * Interface for upper layer modules (8.3.1) *
1213 *********************************************/
1216 * Procedure: Dem_GetVersionInfo
1219 #if (DEM_VERSION_INFO_API == STD_ON)
1220 void Dem_GetVersionInfo(Std_VersionInfoType *versionInfo) {
1221 memcpy(versionInfo, &_Dem_VersionInfo, sizeof(Std_VersionInfoType));
1223 #endif /* DEM_VERSION_INFO_API */
1226 /***********************************************
1227 * Interface ECU State Manager <-> DEM (8.3.2) *
1228 ***********************************************/
1231 * Procedure: Dem_PreInit
1234 void Dem_PreInit(void)
1238 if (DEM_Config.ConfigSet == NULL) {
1239 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1240 Det_ReportError(MODULE_ID_DEM, 0, DEM_PREINIT_ID, DEM_E_CONFIG_PTR_INVALID);
1244 configSet = DEM_Config.ConfigSet;
1247 // Initializion of operation cycle states.
1248 for (i = 0; i < DEM_OPERATION_CYCLE_ID_ENDMARK; i++) {
1249 operationCycleStateList[i] = DEM_CYCLE_STATE_END;
1252 // Initialize the event status buffer
1253 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1254 eventStatusBuffer[i].eventId = DEM_EVENT_ID_NULL;
1255 eventStatusBuffer[i].occurrence = 0;
1256 eventStatusBuffer[i].eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
1257 eventStatusBuffer[i].eventStatus = DEM_EVENT_STATUS_PASSED;
1258 eventStatusBuffer[i].eventStatusChanged = FALSE;
1261 // Initialize the pre init buffers
1262 for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++) {
1263 preInitFreezeFrameBuffer[i].checksum = 0;
1264 preInitFreezeFrameBuffer[i].eventId = DEM_EVENT_ID_NULL;
1265 preInitFreezeFrameBuffer[i].occurrence = 0;
1266 preInitFreezeFrameBuffer[i].dataSize = 0;
1267 for (j = 0; j < DEM_MAX_SIZE_FF_DATA;j++)
1268 preInitFreezeFrameBuffer[i].data[j] = 0;
1271 for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT; i++) {
1272 preInitExtDataBuffer[i].checksum = 0;
1273 preInitExtDataBuffer[i].eventId = DEM_EVENT_ID_NULL;
1274 preInitExtDataBuffer[i].dataSize = 0;
1275 for (j = 0; j < DEM_MAX_SIZE_EXT_DATA;j++)
1276 preInitExtDataBuffer[i].data[j] = 0;
1279 disableDtcStorage.storageDisabled = FALSE;
1281 setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_START);
1283 demState = DEM_PREINITIALIZED;
1288 * Procedure: Dem_Init
1295 const Dem_EventParameterType *eventParam;
1298 * Validate and read out saved error log from non volatile memory
1301 // Validate event records stored in primary memory
1302 for (i = 0; i < DEM_MAX_NUMBER_EVENT_PRI_MEM; i++) {
1303 cSum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));
1304 if ((cSum != priMemEventBuffer[i].checksum) || priMemEventBuffer[i].eventId == DEM_EVENT_ID_NULL) {
1305 // Unlegal record, clear the record
1306 memset(&priMemEventBuffer[i], 0, sizeof(EventRecType));
1309 // Valid, update current status
1310 mergeEventStatusRec(&priMemEventBuffer[i]);
1312 // Update occurrence counter on pre init stored freeze frames
1313 updateFreezeFrameOccurrencePreInit(&priMemEventBuffer[i]);
1317 // Validate extended data records stored in primary memory
1318 for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM; i++) {
1319 cSum = calcChecksum(&priMemExtDataBuffer[i], sizeof(ExtDataRecType)-sizeof(ChecksumType));
1320 if ((cSum != priMemExtDataBuffer[i].checksum) || priMemExtDataBuffer[i].eventId == DEM_EVENT_ID_NULL) {
1321 // Unlegal record, clear the record
1322 memset(&priMemExtDataBuffer[i], 0, sizeof(ExtDataRecType));
1326 // Validate freeze frame records stored in primary memory
1327 for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++) {
1328 cSum = calcChecksum(&priMemFreezeFrameBuffer[i], sizeof(FreezeFrameRecType)-sizeof(ChecksumType));
1329 if ((cSum != priMemFreezeFrameBuffer[i].checksum) || (priMemFreezeFrameBuffer[i].eventId == DEM_EVENT_ID_NULL)) {
1330 // Unlegal record, clear the record
1331 memset(&priMemFreezeFrameBuffer[i], 0, sizeof(FreezeFrameRecType));
1336 * Handle errors stored in temporary buffer (if any)
1339 // Transfer updated event data to event memory
1340 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1341 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1342 // Update the event memory
1343 lookupEventIdParameter(eventStatusBuffer[i].eventId, &eventParam);
1344 storeEventEvtMem(eventParam, &eventStatusBuffer[i]);
1348 // Transfer extended data to event memory if necessary
1349 for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT; i++) {
1350 if (preInitExtDataBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1351 lookupEventIdParameter(preInitExtDataBuffer[i].eventId, &eventParam);
1352 storeExtendedDataEvtMem(eventParam, &preInitExtDataBuffer[i]);
1356 // Transfer freeze frames to event memory
1357 for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++) {
1358 if (preInitFreezeFrameBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1359 lookupEventIdParameter(preInitFreezeFrameBuffer[i].eventId, &eventParam);
1360 storeFreezeFrameDataEvtMem(eventParam, &preInitFreezeFrameBuffer[i]);
1364 // Init the dtc filter
1365 dtcFilter.dtcStatusMask = DEM_DTC_STATUS_MASK_ALL; // All allowed
1366 dtcFilter.dtcKind = DEM_DTC_KIND_ALL_DTCS; // All kinds of DTCs
1367 dtcFilter.dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY; // Primary memory
1368 dtcFilter.filterWithSeverity = DEM_FILTER_WITH_SEVERITY_NO; // No Severity filtering
1369 dtcFilter.dtcSeverityMask = DEM_SEVERITY_NO_SEVERITY; // Not used when filterWithSeverity is FALSE
1370 dtcFilter.filterForFaultDetectionCounter = DEM_FILTER_FOR_FDC_NO; // No fault detection counter filtering
1372 dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;
1374 disableDtcStorage.storageDisabled = FALSE;
1376 demState = DEM_INITIALIZED;
1381 * Procedure: Dem_shutdown
1384 void Dem_Shutdown(void)
1386 setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_END);
1388 demState = DEM_UNINITIALIZED;
1393 * Interface for basic software scheduler
1395 void Dem_MainFunction(void)
1401 /***************************************************
1402 * Interface SW-Components via RTE <-> DEM (8.3.3) *
1403 ***************************************************/
1406 * Procedure: Dem_SetEventStatus
1409 Std_ReturnType Dem_SetEventStatus(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)
1411 Std_ReturnType returnCode = E_OK;
1413 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1415 returnCode = handleEvent(eventId, eventStatus);
1419 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1420 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETEVENTSTATUS_ID, DEM_E_UNINIT);
1421 returnCode = E_NOT_OK;
1430 * Procedure: Dem_ResetEventStatus
1433 Std_ReturnType Dem_ResetEventStatus(Dem_EventIdType eventId)
1435 const Dem_EventParameterType *eventParam;
1436 EventStatusRecType eventStatusLocal;
1437 Std_ReturnType returnCode = E_OK;
1439 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1441 lookupEventIdParameter(eventId, &eventParam);
1442 if (eventParam != NULL) {
1443 updateEventStatusRec(eventParam, DEM_EVENT_STATUS_PASSED, FALSE, &eventStatusLocal);
1448 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1449 Det_ReportError(MODULE_ID_DEM, 0, DEM_RESETEVENTSTATUS_ID, DEM_E_UNINIT);
1451 returnCode = E_NOT_OK;
1459 * Procedure: Dem_GetEventStatus
1462 Std_ReturnType Dem_GetEventStatus(Dem_EventIdType eventId, Dem_EventStatusExtendedType *eventStatusExtended)
1464 Std_ReturnType returnCode = E_OK;
1466 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1468 getEventStatus(eventId, eventStatusExtended);
1472 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1473 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEVENTSTATUS_ID, DEM_E_UNINIT);
1475 returnCode = E_NOT_OK;
1483 * Procedure: Dem_GetEventFailed
1486 Std_ReturnType Dem_GetEventFailed(Dem_EventIdType eventId, boolean *eventFailed)
1488 Std_ReturnType returnCode = E_OK;
1490 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1492 getEventFailed(eventId, eventFailed);
1496 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1497 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEVENTFAILED_ID, DEM_E_UNINIT);
1499 returnCode = E_NOT_OK;
1507 * Procedure: Dem_GetEventTested
1510 Std_ReturnType Dem_GetEventTested(Dem_EventIdType eventId, boolean *eventTested)
1512 Std_ReturnType returnCode = E_OK;
1514 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1516 getEventTested(eventId, eventTested);
1520 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1521 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEVENTTESTED_ID, DEM_E_UNINIT);
1523 returnCode = E_NOT_OK;
1531 * Procedure: Dem_GetFaultDetectionCounter
1534 Std_ReturnType Dem_GetFaultDetectionCounter(Dem_EventIdType eventId, sint8 *counter)
1536 Std_ReturnType returnCode = E_OK;
1538 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1540 returnCode = getFaultDetectionCounter(eventId, counter);
1544 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1545 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_UNINIT);
1547 returnCode = E_NOT_OK;
1555 * Procedure: Dem_SetOperationCycleState
1558 Std_ReturnType Dem_SetOperationCycleState(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState)
1560 Std_ReturnType returnCode = E_OK;
1562 if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1564 returnCode = setOperationCycleState(operationCycleId, cycleState);
1569 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1570 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_UNINIT);
1572 returnCode = E_NOT_OK;
1580 * Procedure: Dem_GetDTCOfEvent
1583 Std_ReturnType Dem_GetDTCOfEvent(Dem_EventIdType eventId, Dem_DTCKindType dtcKind, uint32* dtcOfEvent)
1585 Std_ReturnType returnCode = E_NO_DTC_AVAILABLE;
1586 const Dem_EventParameterType *eventParam;
1588 lookupEventIdParameter(eventId, &eventParam);
1590 if (eventParam != NULL) {
1591 if (checkDtcKind(dtcKind, eventParam)) {
1592 if (eventParam->DTCClassRef != NULL) {
1593 *dtcOfEvent = eventParam->DTCClassRef->DTC;
1599 // Event Id not found
1600 returnCode = E_NOT_OK;
1607 /********************************************
1608 * Interface BSW-Components <-> DEM (8.3.4) *
1609 ********************************************/
1612 * Procedure: Dem_ReportErrorStatus
1615 void Dem_ReportErrorStatus( Dem_EventIdType eventId, Dem_EventStatusType eventStatus )
1619 case DEM_PREINITIALIZED:
1620 // Update status and check if is to be stored
1621 if ((eventStatus == DEM_EVENT_STATUS_PASSED) || (eventStatus == DEM_EVENT_STATUS_FAILED)) {
1622 handlePreInitEvent(eventId, eventStatus);
1626 case DEM_INITIALIZED:
1628 if ((eventStatus == DEM_EVENT_STATUS_PASSED) || (eventStatus == DEM_EVENT_STATUS_FAILED)) {
1629 (void)handleEvent(eventId, eventStatus);
1633 case DEM_UNINITIALIZED:
1635 // Uninitialized can not do anything
1636 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1637 Det_ReportError(MODULE_ID_DEM, 0, DEM_REPORTERRORSTATUS_ID, DEM_E_UNINIT);
1641 } // switch (demState)
1644 /*********************************
1645 * Interface DCM <-> DEM (8.3.5) *
1646 *********************************/
1648 * Procedure: Dem_GetDTCStatusAvailabilityMask
1651 Std_ReturnType Dem_GetDTCStatusAvailabilityMask(uint8 *dtcStatusMask)
1653 *dtcStatusMask = DEM_DTC_STATUS_AVAILABILITY_MASK; // User configuration mask
1654 *dtcStatusMask &= DEM_TEST_FAILED // Mask with supported bits
1655 | DEM_TEST_FAILED_THIS_OPERATION_CYCLE
1657 // | DEM_CONFIRMED_DTC TODO: Add support for this bit
1658 | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR
1659 | DEM_TEST_FAILED_SINCE_LAST_CLEAR
1660 | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE
1661 // | DEM_WARNING_INDICATOR_REQUESTED TODO: Add support for this bit
1669 * Procedure: Dem_SetDTCFilter
1672 Dem_ReturnSetDTCFilterType Dem_SetDTCFilter(uint8 dtcStatusMask,
1673 Dem_DTCKindType dtcKind,
1674 Dem_DTCOriginType dtcOrigin,
1675 Dem_FilterWithSeverityType filterWithSeverity,
1676 Dem_DTCSeverityType dtcSeverityMask,
1677 Dem_FilterForFDCType filterForFaultDetectionCounter) {
1679 Dem_ReturnSetDTCFilterType returnCode = DEM_WRONG_FILTER;
1681 // Check dtcKind parameter
1682 if ((dtcKind == DEM_DTC_KIND_ALL_DTCS) || (dtcKind == DEM_DTC_KIND_EMISSION_REL_DTCS)) {
1684 // Check dtcOrigin parameter
1685 if ((dtcOrigin == DEM_DTC_ORIGIN_SECONDARY_MEMORY) || (dtcOrigin == DEM_DTC_ORIGIN_PRIMARY_MEMORY)
1686 || (dtcOrigin == DEM_DTC_ORIGIN_PERMANENT_MEMORY) || (dtcOrigin == DEM_DTC_ORIGIN_MIRROR_MEMORY)) {
1688 // Check filterWithSeverity and dtcSeverityMask parameter
1689 if ((filterWithSeverity == DEM_FILTER_WITH_SEVERITY_NO)
1690 || ((filterWithSeverity == DEM_FILTER_WITH_SEVERITY_YES) && !(dtcSeverityMask & ~(DEM_SEVERITY_MAINTENANCE_ONLY | DEM_SEVERITY_CHECK_AT_NEXT_FALT | DEM_SEVERITY_CHECK_IMMEDIATELY)))){
1692 // Check filterForFaultDetectionCounter parameter
1693 if ((filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_YES) || (filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_NO)) {
1694 // Yes all parameters correct, set the new filters.
1695 dtcFilter.dtcStatusMask = dtcStatusMask;
1696 dtcFilter.dtcKind = dtcKind;
1697 dtcFilter.dtcOrigin = dtcOrigin;
1698 dtcFilter.filterWithSeverity = filterWithSeverity;
1699 dtcFilter.dtcSeverityMask = dtcSeverityMask;
1700 dtcFilter.filterForFaultDetectionCounter = filterForFaultDetectionCounter;
1701 dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;
1702 returnCode = DEM_FILTER_ACCEPTED;
1713 * Procedure: Dem_GetStatusOfDTC
1716 Dem_ReturnGetStatusOfDTCType Dem_GetStatusOfDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, Dem_EventStatusExtendedType* status) {
1717 Dem_ReturnGetStatusOfDTCType returnCode = DEM_STATUS_FAILED;
1718 EventStatusRecType *eventRec;
1720 if (lookupDtcEvent(dtc, &eventRec)) {
1721 if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {
1722 if (checkDtcOrigin(dtcOrigin,eventRec->eventParamRef)) {
1723 *status = eventRec->eventStatusExtended;
1724 returnCode = DEM_STATUS_OK;
1727 returnCode = DEM_STATUS_WRONG_DTCORIGIN;
1731 returnCode = DEM_STATUS_WRONG_DTCKIND;
1735 returnCode = DEM_STATUS_WRONG_DTC;
1743 * Procedure: Dem_GetNumberOfFilteredDtc
1746 Dem_ReturnGetNumberOfFilteredDTCType Dem_GetNumberOfFilteredDtc(uint16 *numberOfFilteredDTC) {
1748 uint16 numberOfFaults = 0;
1750 //Dem_DisableEventStatusUpdate();
1752 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1753 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1754 if (matchEventWithDtcFilter(&eventStatusBuffer[i])) {
1755 if (eventStatusBuffer[i].eventParamRef->DTCClassRef != NULL) {
1762 //Dem_EnableEventStatusUpdate();
1764 *numberOfFilteredDTC = numberOfFaults;
1766 return DEM_NUMBER_OK;
1771 * Procedure: Dem_GetNextFilteredDTC
1774 Dem_ReturnGetNextFilteredDTCType Dem_GetNextFilteredDTC(uint32 *dtc, Dem_EventStatusExtendedType *dtcStatus)
1776 Dem_ReturnGetNextFilteredDTCType returnCode = DEM_FILTERED_OK;
1777 boolean dtcFound = FALSE;
1779 // TODO: This job should be done in an more advanced way according to Dem288
1780 while (!dtcFound && (dtcFilter.faultIndex != 0)) {
1781 dtcFilter.faultIndex--;
1782 if (eventStatusBuffer[dtcFilter.faultIndex].eventId != DEM_EVENT_ID_NULL) {
1783 if (matchEventWithDtcFilter(&eventStatusBuffer[dtcFilter.faultIndex])) {
1784 if (eventStatusBuffer[dtcFilter.faultIndex].eventParamRef->DTCClassRef != NULL) {
1785 *dtc = eventStatusBuffer[dtcFilter.faultIndex].eventParamRef->DTCClassRef->DTC;
1786 *dtcStatus = eventStatusBuffer[dtcFilter.faultIndex].eventStatusExtended;
1794 dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;
1795 returnCode = DEM_FILTERED_NO_MATCHING_DTC;
1803 * Procedure: Dem_GetTranslationType
1806 Dem_ReturnTypeOfDtcSupportedType Dem_GetTranslationType(void)
1808 return DEM_TYPE_OF_DTC_SUPPORTED;
1813 * Procedure: Dem_ClearDTC
1816 Dem_ReturnClearDTCType Dem_ClearDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin)
1818 Dem_ReturnClearDTCType returnCode = DEM_CLEAR_OK;
1819 Dem_EventIdType eventId;
1820 const Dem_EventParameterType *eventParam;
1823 // Loop through the event buffer
1824 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1825 eventId = eventStatusBuffer[i].eventId;
1826 if (eventId != DEM_EVENT_ID_NULL) {
1827 eventParam = eventStatusBuffer[i].eventParamRef;
1828 if (eventParam != NULL) {
1829 if (DEM_CLEAR_ALL_EVENTS | (eventParam->DTCClassRef != NULL)) {
1830 if (checkDtcKind(dtcKind, eventParam)) {
1831 if (checkDtcGroup(dtc, eventParam)) {
1832 for (j = 0; (j < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[j] != dtcOrigin); j++);
1833 if (j < DEM_MAX_NR_OF_EVENT_DESTINATION) {
1834 // Yes! All conditions met.
1837 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
1838 deleteEventPriMem(eventParam);
1839 deleteFreezeFrameDataPriMem(eventParam);
1840 deleteExtendedDataPriMem(eventParam);
1841 deleteEventStatusRec(eventParam); // TODO: Shall this be done or just resetting the status?
1844 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
1845 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
1846 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
1847 // Not yet supported
1848 returnCode = DEM_CLEAR_WRONG_DTCORIGIN;
1849 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1850 Det_ReportError(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);
1854 returnCode = DEM_CLEAR_WRONG_DTCORIGIN;
1863 // Fatal error, no event parameters found for the stored event!
1864 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1865 Det_ReportError(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_UNEXPECTED_EXECUTION);
1876 * Procedure: Dem_DisableDTCStorage
1879 Dem_ReturnControlDTCStorageType Dem_DisableDTCStorage(Dem_DTCGroupType dtcGroup, Dem_DTCKindType dtcKind)
1881 Dem_ReturnControlDTCStorageType returnCode = DEM_CONTROL_DTC_STORAGE_N_OK;
1883 // Check dtcGroup parameter
1884 if (dtcGroup == DEM_DTC_GROUP_ALL_DTCS) {
1885 // Check dtcKind parameter
1886 if ((dtcKind == DEM_DTC_KIND_ALL_DTCS) || (dtcKind == DEM_DTC_KIND_EMISSION_REL_DTCS)) {
1887 disableDtcStorage.dtcGroup = dtcGroup;
1888 disableDtcStorage.dtcKind = dtcKind;
1889 disableDtcStorage.storageDisabled = TRUE;
1891 returnCode = DEM_CONTROL_DTC_STORAGE_OK;
1895 returnCode = DEM_CONTROL_DTC_WRONG_DTCGROUP;
1903 * Procedure: Dem_EnableDTCStorage
1906 Dem_ReturnControlDTCStorageType Dem_EnableDTCStorage(Dem_DTCGroupType dtcGroup, Dem_DTCKindType dtcKind)
1908 // TODO: Behavior is not defined if group or kind do not match active settings, therefore the filter is just switched off.
1909 disableDtcStorage.storageDisabled = FALSE;
1911 return DEM_CONTROL_DTC_STORAGE_OK;
1915 * Procedure: Dem_GetExtendedDataRecordByDTC
1918 Dem_ReturnGetExtendedDataRecordByDTCType Dem_GetExtendedDataRecordByDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, uint8 extendedDataNumber, uint8 *destBuffer, uint8 *bufSize)
1920 Dem_ReturnGetExtendedDataRecordByDTCType returnCode = DEM_RECORD_WRONG_DTC;
1921 EventStatusRecType *eventRec;
1922 Dem_ExtendedDataRecordClassType const *extendedDataRecordClass = NULL;
1923 ExtDataRecType *extData;
1924 uint8 posInExtData = 0;
1926 if (lookupDtcEvent(dtc, &eventRec)) {
1927 if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {
1928 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {
1929 if (lookupExtendedDataRecNumParam(extendedDataNumber, eventRec->eventParamRef, &extendedDataRecordClass, &posInExtData)) {
1930 if (*bufSize >= extendedDataRecordClass->DataSize) {
1933 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
1934 if (lookupExtendedDataPriMem(eventRec->eventId, &extData)) {
1935 // Yes all conditions met, copy the extended data record to destination buffer.
1936 memcpy(destBuffer, &extData->data[posInExtData], extendedDataRecordClass->DataSize);
1937 *bufSize = extendedDataRecordClass->DataSize;
1938 returnCode = DEM_RECORD_OK;
1941 // The record number is legal but no record was found for the DTC
1943 returnCode = DEM_RECORD_OK;
1947 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
1948 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
1949 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
1950 // Not yet supported
1951 returnCode = DEM_RECORD_WRONG_DTCORIGIN;
1952 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1953 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEXTENDEDDATARECORDBYDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);
1957 returnCode = DEM_RECORD_WRONG_DTCORIGIN;
1962 returnCode = DEM_RECORD_BUFFERSIZE;
1966 returnCode = DEM_RECORD_NUMBER;
1970 returnCode = DEM_RECORD_WRONG_DTCORIGIN;
1974 returnCode = DEM_RECORD_DTCKIND;
1983 * Procedure: Dem_GetSizeOfExtendedDataRecordByDTC
1986 Dem_ReturnGetSizeOfExtendedDataRecordByDTCType Dem_GetSizeOfExtendedDataRecordByDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, uint8 extendedDataNumber, uint16 *sizeOfExtendedDataRecord)
1988 Dem_ReturnGetExtendedDataRecordByDTCType returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTC;
1989 EventStatusRecType *eventRec;
1990 Dem_ExtendedDataRecordClassType const *extendedDataRecordClass = NULL;
1993 if (lookupDtcEvent(dtc, &eventRec)) {
1994 if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {
1995 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {
1996 if (lookupExtendedDataRecNumParam(extendedDataNumber, eventRec->eventParamRef, &extendedDataRecordClass, &posInExtData)) {
1997 *sizeOfExtendedDataRecord = extendedDataRecordClass->DataSize;
1998 returnCode = DEM_GET_SIZEOFEDRBYDTC_OK;
2001 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_RNUM;
2005 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTCOR;
2009 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTCKI;
2016 /***********************************
2017 * OBD-specific Interfaces (8.3.6) *
2018 ***********************************/