]> rtime.felk.cvut.cz Git - arc.git/blob - communication/PduR/PduR.c
Merged with dem-dev
[arc.git] / communication / PduR / PduR.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
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>.
9  *
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
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16
17
18
19
20
21
22
23 \r
24 #include <stdlib.h>\r
25 #include <string.h>\r
26 \r
27 \r
28 #include "Det.h"
29 #if defined(USE_DEM)
30 #include "Dem.h"\r
31 #endif
32 #include "PduR.h"\r
33 #include "PduR_Com.h"\r
34 #include "PduR_CanIf.h"\r
35 #include "PduR_LinIf.h"\r
36 #include "PduR_Ipdum.h"\r
37 #include "Mcu.h"\r
38 #include "Trace.h"\r
39 \r
40 /*\r
41  * The state of the PDU router.
42  */\r
43 PduR_StateType PduRState = PDUR_UNINIT;\r
44 \r
45 const PduR_PBConfigType * PduRConfig;\r
46 \r
47 \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
52 \r
53 /*\r
54  * Initializes the PDU Router.
55  */\r
56 void PduR_Init (const PduR_PBConfigType* ConfigPtr) {\r
57 \r
58         //Enter(0);\r
59 \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
65                 return;\r
66         }\r
67 \r
68         if (ConfigPtr == NULL) {\r
69                 DET_REPORTERROR(PDUR_MODULE_ID, PDUR_INSTANCE_ID, 0x00, PDUR_E_CONFIG_PTR_INVALID);\r
70                 return;\r
71         } else {\r
72                 PduRConfig = ConfigPtr;\r
73         }\r
74 \r
75         // Start initialization!\r
76         DEBUG(DEBUG_LOW,"--Initialization of PDU router--\n");\r
77 \r
78         uint8 failed = 0;\r
79 \r
80         // TODO Initialize DestPduIds!!!!!\r
81 \r
82         // TODO Initialize NRoutingPaths.\r
83 \r
84         // Initialize buffers.\r
85         int bufferNr = 0;\r
86         int i = 0;\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
91 \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
95 \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
98                                 failed = 1;\r
99                                 break;\r
100                         }\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
103                                 failed = 1;\r
104                                 break;\r
105                         }\r
106 \r
107                         buffer->First = buffer->Buffer;\r
108                         buffer->Last = buffer->Buffer;\r
109 \r
110 \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
115 \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
119                         }\r
120 \r
121                         // Save pointer to the new buffer.\r
122                         //PduR_RTable_LoIf.RoutingTable[i].TxBufferRef = &PduRBuffers[bufferNr];\r
123 \r
124                         DEBUG(DEBUG_LOW,"Initialized buffer %d. Id: %d, Type: %d, Depth: %d\n", bufferNr, buffer->BufferId, buffer->BufferType, buffer->Depth);\r
125                         bufferNr++;\r
126                 }\r
127         }\r
128 \r
129         if (failed) {\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
133 \r
134 \r
135         } else {\r
136                 // The initialization succeeded!\r
137                 PduRState = PDUR_ONLINE;\r
138                 DEBUG(DEBUG_LOW,"--Initialization of PDU router completed --\n");\r
139 \r
140         }\r
141 }\r
142 \r
143 void PduR_BufferInc(PduRTxBuffer_type *Buffer, uint8 **ptr) {\r
144         (*ptr) = (*ptr) + Buffer->Length;\r
145 \r
146         // TODO make more efficient without multiplication.\r
147         if (*ptr >= Buffer->Buffer + Buffer->Depth * Buffer->Length) {\r
148                 *ptr = Buffer->Buffer;\r
149         }\r
150         //*val = (*val + 1) % Buffer->Depth;\r
151 }\r
152 \r
153 void PduR_BufferQueue(PduRTxBuffer_type *Buffer, const uint8 * SduPtr) {\r
154         imask_t state = McuE_EnterCriticalSection();\r
155 \r
156         if (PduR_BufferIsFull(Buffer)) { // Buffer is full\r
157                 PduR_BufferFlush(Buffer);\r
158 #if defined(USE_DEM)
159                 Dem_ReportErrorStatus(PDUR_E_PDU_INSTANCE_LOST, DEM_EVENT_STATUS_FAILED);\r
160 #endif\r
161 \r
162         } else {\r
163                 // Copy data to last place in buffer\r
164                 memcpy(Buffer->Last, SduPtr, sizeof(uint8) * Buffer->Length);\r
165 \r
166                 PduR_BufferInc(Buffer, &Buffer->Last);\r
167                 Buffer->NrItems++;\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
169 \r
170         }\r
171         McuE_ExitCriticalSection(state);\r
172 }\r
173 \r
174 void PduR_BufferDeQueue(PduRTxBuffer_type *Buffer, uint8 *SduPtr) {\r
175         imask_t state = McuE_EnterCriticalSection();\r
176 \r
177         if (Buffer->NrItems > 0) {\r
178                 memcpy(SduPtr, Buffer->First, sizeof(uint8) * Buffer->Length);\r
179                 PduR_BufferInc(Buffer, &Buffer->First);\r
180                 Buffer->NrItems--;\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
182         } else {\r
183                 DEBUG(DEBUG_LOW,"\tBuffer %d: Buffer is empty, nothing to dequeue!\n", Buffer->BufferId);\r
184         }\r
185         McuE_ExitCriticalSection(state);\r
186 }\r
187 \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
196 }\r
197 \r
198 uint8 PduR_BufferIsFull(PduRTxBuffer_type *Buffer) {\r
199         imask_t state = McuE_EnterCriticalSection();\r
200         if (Buffer->NrItems < Buffer->Depth) {\r
201                 return 0;\r
202         } else {\r
203                 return 1;\r
204         }\r
205         McuE_ExitCriticalSection(state);\r
206 }\r
207 \r
208 \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
213 \r
214         // TODO Add vendor specific version numbers.\r
215 }\r
216 #endif\r
217 \r
218 uint32 PduR_GetConfigurationId () {\r
219         //DevCheck(0,1,0x18,E_NOT_OK);\r
220         return PduRConfig->PduRConfigurationId;\r
221 }\r
222 #endif // End of not Zero Cost Operation Mode\r
223 \r
224 Std_ReturnType PduR_CancelTransmitRequest(PduR_CancelReasonType PduCancelReason, PduIdType PduId) {\r
225         Enter(PduId,E_NOT_OK);\r
226         // TODO Implement!\r
227 \r
228         Exit();\r
229         return E_NOT_OK;\r
230 }\r
231 \r
232 void PduR_ChangeParameterRequest(PduR_ParameterValueType PduParameterValue, PduIdType PduId) {\r
233         Enter(0);\r
234         // TODO Implement!\r
235 \r
236 }\r
237 \r
238 \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
243         // Just a stub\r
244         return E_OK;\r
245 }\r
246 \r
247 // If CAN are available we include these functions directly\r
248 #else\r
249 #include "CanIf.h"\r
250 #endif\r
251 \r
252 \r
253 #if !defined(USE_LINIF)\r
254 Std_ReturnType LinIf_Transmit(PduIdType LinTxPduId,const PduInfoType* PduInfoPtr) {\r
255         // Just a stub\r
256         return E_OK;\r
257 }\r
258 \r
259 // If LIN are available we include these functions directly\r
260 #else\r
261 #include "LinIf.h"\r
262 #endif\r
263 \r
264 \r
265 \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
271 };\r
272 \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
278 };\r
279 \r