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 ------------------------------*/
33 #include "PduR_Com.h"
\r
34 #include "PduR_CanIf.h"
\r
35 #include "PduR_LinIf.h"
\r
36 #include "PduR_Ipdum.h"
\r
41 * The state of the PDU router.
43 PduR_StateType PduRState = PDUR_UNINIT;
\r
45 const PduR_PBConfigType * PduRConfig;
\r
48 /* ############### Zero Cost Operation Mode ############# */
\r
49 /* Only define the following functions if zero cost operation
\r
50 * mode is not used! They are defined as macros in PduR.h otherwise. */
\r
51 #ifndef PDUR_ZERO_COST_OPERATION
\r
54 * Initializes the PDU Router.
56 void PduR_Init (const PduR_PBConfigType* ConfigPtr) {
\r
60 // Make sure the PDU Router is uninitialized.
\r
61 // Otherwise raise an error.
\r
62 if (PduRState != PDUR_UNINIT) {
\r
63 // Raise error and return.
\r
64 DET_REPORTERROR(PDUR_MODULE_ID, PDUR_INSTANCE_ID, 0x00, PDUR_E_INVALID_REQUEST);
\r
68 if (ConfigPtr == NULL) {
\r
69 DET_REPORTERROR(PDUR_MODULE_ID, PDUR_INSTANCE_ID, 0x00, PDUR_E_CONFIG_PTR_INVALID);
\r
72 PduRConfig = ConfigPtr;
\r
75 // Start initialization!
\r
76 DEBUG(DEBUG_LOW,"--Initialization of PDU router--\n");
\r
80 // TODO Initialize DestPduIds!!!!!
\r
82 // TODO Initialize NRoutingPaths.
\r
84 // Initialize buffers.
\r
87 PduRRoutingPath_type *path;
\r
88 for (i = 0; !PduRConfig->PduRRoutingTable->PduRRoutingPath[i].PduR_Arc_EOL && !failed; i++) {
\r
89 PduRConfig->PduRRoutingTable->NRoutingPaths++;
\r
90 path = &PduRConfig->PduRRoutingTable->PduRRoutingPath[i];
\r
92 if (path->PduRDestPdu.DataProvision != PDUR_NO_PROVISION) {
\r
93 // Allocate memory for new buffer.
\r
94 PduRTxBuffer_type *buffer = path->PduRDestPdu.TxBufferRef;
\r
96 if (bufferNr >= PDUR_MAX_TX_BUFFER_NUMBER) {
\r
97 DEBUG(DEBUG_LOW,"PduR_Init: Initialization of buffer failed due to erroneous configuration.\nThe number of buffer exceeded the maximum number of allowed buffers.\n");
\r
101 if ((buffer->Buffer = (uint8 *)malloc(buffer->Depth * sizeof(uint8) * path->SduLength)) == 0) {
\r
102 DEBUG(DEBUG_LOW,"PduR_Init: Initialization of buffer failed. Buffer space could not be allocated for buffer number %d\n", bufferNr);
\r
107 buffer->First = buffer->Buffer;
\r
108 buffer->Last = buffer->Buffer;
\r
111 // Initialize the new buffer.
\r
112 buffer->BufferId = i; // Set buffer id.
\r
113 buffer->BufferType = path->PduRDestPdu.DataProvision; // Set buffer data provision mode.
\r
114 buffer->Length = path->SduLength; // Set buffer sdu length.
\r
116 if (path->PduRDestPdu.DataProvision == PDUR_TRIGGER_TRANSMIT) {
\r
117 //memcpy(buffer->First, path->PduRDefaultValue.PduRDefaultValueElement->DefaultValueElement,path->SduLength);
\r
118 PduR_BufferQueue(buffer, path->PduRDefaultValue.PduRDefaultValueElement->DefaultValueElement);
\r
121 // Save pointer to the new buffer.
\r
122 //PduR_RTable_LoIf.RoutingTable[i].TxBufferRef = &PduRBuffers[bufferNr];
\r
124 DEBUG(DEBUG_LOW,"Initialized buffer %d. Id: %d, Type: %d, Depth: %d\n", bufferNr, buffer->BufferId, buffer->BufferType, buffer->Depth);
\r
130 // TODO Report PDUR_E_INIT_FAILED to Dem.
\r
131 PduRState = PDUR_REDUCED;
\r
132 DEBUG(DEBUG_LOW,"--Initialization of PDU router failed--\n");
\r
136 // The initialization succeeded!
\r
137 PduRState = PDUR_ONLINE;
\r
138 DEBUG(DEBUG_LOW,"--Initialization of PDU router completed --\n");
\r
143 void PduR_BufferInc(PduRTxBuffer_type *Buffer, uint8 **ptr) {
\r
144 (*ptr) = (*ptr) + Buffer->Length;
\r
146 // TODO make more efficient without multiplication.
\r
147 if (*ptr >= Buffer->Buffer + Buffer->Depth * Buffer->Length) {
\r
148 *ptr = Buffer->Buffer;
\r
150 //*val = (*val + 1) % Buffer->Depth;
\r
153 void PduR_BufferQueue(PduRTxBuffer_type *Buffer, const uint8 * SduPtr) {
\r
154 imask_t state = McuE_EnterCriticalSection();
\r
156 if (PduR_BufferIsFull(Buffer)) { // Buffer is full
\r
157 PduR_BufferFlush(Buffer);
\r
159 Dem_ReportErrorStatus(PDUR_E_PDU_INSTANCE_LOST, DEM_EVENT_STATUS_FAILED);
\r
163 // Copy data to last place in buffer
\r
164 memcpy(Buffer->Last, SduPtr, sizeof(uint8) * Buffer->Length);
\r
166 PduR_BufferInc(Buffer, &Buffer->Last);
\r
168 DEBUG(DEBUG_LOW,"\tBuffer %d: Queued data %d. Status: NrItems %d, First %d, Last %d\n", Buffer->BufferId, *SduPtr, Buffer->NrItems, *Buffer->First, *Buffer->Last);
\r
171 McuE_ExitCriticalSection(state);
\r
174 void PduR_BufferDeQueue(PduRTxBuffer_type *Buffer, uint8 *SduPtr) {
\r
175 imask_t state = McuE_EnterCriticalSection();
\r
177 if (Buffer->NrItems > 0) {
\r
178 memcpy(SduPtr, Buffer->First, sizeof(uint8) * Buffer->Length);
\r
179 PduR_BufferInc(Buffer, &Buffer->First);
\r
181 DEBUG(DEBUG_LOW,"\tBuffer %d: DeQueueing data. Status: NrItems %d, First %d, Last %d\n", Buffer->BufferId, Buffer->NrItems, *Buffer->First, *Buffer->Last);
\r
183 DEBUG(DEBUG_LOW,"\tBuffer %d: Buffer is empty, nothing to dequeue!\n", Buffer->BufferId);
\r
185 McuE_ExitCriticalSection(state);
\r
188 void PduR_BufferFlush(PduRTxBuffer_type *Buffer) {
\r
189 DEBUG(DEBUG_LOW,"\tBuffer %d: Flushing!\n", Buffer->BufferId);
\r
190 imask_t state = McuE_EnterCriticalSection();
\r
191 Buffer->NrItems = 0;
\r
192 Buffer->First = Buffer->Buffer;
\r
193 Buffer->Last = Buffer->Buffer;
\r
194 Buffer->TxConfP = 0;
\r
195 McuE_ExitCriticalSection(state);
\r
198 uint8 PduR_BufferIsFull(PduRTxBuffer_type *Buffer) {
\r
199 imask_t state = McuE_EnterCriticalSection();
\r
200 if (Buffer->NrItems < Buffer->Depth) {
\r
205 McuE_ExitCriticalSection(state);
\r
209 #ifdef PDUR_VERSION_INFO_API
\r
210 void PduR_GetVersionInfo (Std_VersionInfoType* versionInfo){
\r
211 versionInfo->moduleID = (uint16)PDUR_MODULE_ID;
\r
212 versionInfo->vendorID = (uint16)1;
\r
214 // TODO Add vendor specific version numbers.
\r
218 uint32 PduR_GetConfigurationId () {
\r
219 //DevCheck(0,1,0x18,E_NOT_OK);
\r
220 return PduRConfig->PduRConfigurationId;
\r
222 #endif // End of not Zero Cost Operation Mode
\r
224 Std_ReturnType PduR_CancelTransmitRequest(PduR_CancelReasonType PduCancelReason, PduIdType PduId) {
\r
225 Enter(PduId,E_NOT_OK);
\r
232 void PduR_ChangeParameterRequest(PduR_ParameterValueType PduParameterValue, PduIdType PduId) {
\r
239 // If we are using the simulator CANIF and LINIF are not available.
\r
240 // Therefore the functions needed by the functions pointer tables below needs to be stubbed.
\r
241 #if !defined(USE_CANIF)
\r
242 Std_ReturnType CanIf_Transmit(PduIdType CanTxPduId, const PduInfoType *PduInfoPtr) {
\r
247 // If CAN are available we include these functions directly
\r
253 #if !defined(USE_LINIF)
\r
254 Std_ReturnType LinIf_Transmit(PduIdType LinTxPduId,const PduInfoType* PduInfoPtr) {
\r
259 // If LIN are available we include these functions directly
\r
266 PduR_FctPtrType PduR_StdLinFctPtrs = {
\r
267 .TargetIndicationFctPtr = Com_RxIndication,
\r
268 .TargetTransmitFctPtr = LinIf_Transmit,
\r
269 .TargetConfirmationFctPtr = Com_TxConfirmation,
\r
270 .TargetTriggerTransmitFctPtr = Com_TriggerTransmit,
\r
273 PduR_FctPtrType PduR_StdCanFctPtrs = {
\r
274 .TargetIndicationFctPtr = Com_RxIndication,
\r
275 .TargetTransmitFctPtr = CanIf_Transmit,
\r
276 .TargetConfirmationFctPtr = Com_TxConfirmation,
\r
277 .TargetTriggerTransmitFctPtr = Com_TriggerTransmit,
\r