]> rtime.felk.cvut.cz Git - arc.git/blob - communication/Com/Com_Sched.c
e8df03f2c1cefe3de740675b8d9705ad5e4123fc
[arc.git] / communication / Com / Com_Sched.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 \r
18 \r
19 \r
20 \r
21 #include "Com_Arc_Types.h"\r
22 #include "Com.h"\r
23 #include "Com_Internal.h"\r
24 #include "Com_misc.h"\r
25 #include <string.h>\r
26 #include "debug.h"\r
27 #include "Cpu.h"\r
28 \r
29 #define timerDec(timer) \\r
30         if (timer > 0) { \\r
31                 timer = timer - 1; \\r
32         } \\r
33 \r
34 \r
35 \r
36 void Com_MainFunctionRx(void) {\r
37         //DEBUG(DEBUG_MEDIUM, "Com_MainFunctionRx() excecuting\n");\r
38         for (uint16 pduId = 0; !ComConfig->ComIPdu[pduId].Com_Arc_EOL; pduId++) {\r
39                 boolean pduUpdated = false;\r
40                 const ComIPdu_type *IPdu = GET_IPdu(pduId);\r
41                 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(pduId);\r
42                 imask_t irq_state;\r
43                 Irq_Save(irq_state);\r
44                 for (uint16 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
45                         const ComSignal_type *signal = IPdu->ComIPduSignalRef[i];\r
46                         Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(signal->ComHandleId);\r
47                         // Monitor signal reception deadline\r
48                         if ( (Arc_IPdu->Com_Arc_IpduStarted) && (signal->ComTimeoutFactor > 0) ) {\r
49 \r
50                                 // Decrease deadline monitoring timer.\r
51                                 timerDec(Arc_Signal->Com_Arc_DeadlineCounter);\r
52 \r
53                                 // Check if a timeout has occurred.\r
54                                 if (Arc_Signal->Com_Arc_DeadlineCounter == 0) {\r
55                                         if (signal->ComRxDataTimeoutAction == COM_TIMEOUT_DATA_ACTION_REPLACE) {\r
56                                                 // Replace signal data.\r
57                                                 Com_WriteSignalDataToPdu(signal->ComHandleId, signal->ComSignalInitValue);\r
58 \r
59                                         }\r
60 \r
61                                         // A timeout has occurred.\r
62                                         if (signal->ComTimeoutNotification != NULL) {\r
63                                                 signal->ComTimeoutNotification();\r
64                                         }\r
65 \r
66                                         // Restart timer\r
67                                         Arc_Signal->Com_Arc_DeadlineCounter = signal->ComTimeoutFactor;\r
68                                 }\r
69                         }\r
70 \r
71                         if (Arc_Signal->ComSignalUpdated) {\r
72                                 pduUpdated = true;\r
73                         }\r
74                 }\r
75                 if (pduUpdated && IPdu->ComIPduSignalProcessing == DEFERRED && IPdu->ComIPduDirection == RECEIVE) {\r
76                         UnlockTpBuffer(getPduId(IPdu));\r
77                         memcpy(IPdu->ComIPduDeferredDataPtr,IPdu->ComIPduDataPtr,IPdu->ComIPduSize);\r
78                         for (uint16 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
79                                 const ComSignal_type *signal = IPdu->ComIPduSignalRef[i];\r
80                                 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(signal->ComHandleId);\r
81                                 if (Arc_Signal->ComSignalUpdated) {\r
82                                         if (signal->ComNotification != NULL) {\r
83                                                 signal->ComNotification();\r
84                                         }\r
85                                         Arc_Signal->ComSignalUpdated = 0;\r
86                                 }\r
87                         }\r
88                 }\r
89                 Irq_Restore(irq_state);\r
90         }\r
91 }\r
92 \r
93 \r
94 void Com_MainFunctionTx(void) {\r
95         imask_t irq_state;\r
96 \r
97         //DEBUG(DEBUG_MEDIUM, "Com_MainFunctionTx() excecuting\n");\r
98         // Decrease timers.\r
99         const ComIPdu_type *IPdu;\r
100         for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {\r
101                 IPdu = &ComConfig->ComIPdu[i];\r
102                 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);\r
103 \r
104                 Irq_Save(irq_state);\r
105 \r
106                 // Is this a IPdu that should be transmitted?\r
107                 if ( (IPdu->ComIPduDirection == SEND) && (Arc_IPdu->Com_Arc_IpduStarted) ) {\r
108                         // Decrease minimum delay timer\r
109                         timerDec(Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer);\r
110 \r
111                         // If IPDU has periodic or mixed transmission mode.\r
112                         if ( (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == PERIODIC)\r
113                                 || (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == MIXED) ) {\r
114 \r
115                                 timerDec(Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer);\r
116 \r
117                                 // Is it time for a direct transmission?\r
118                                 if ( (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == MIXED)\r
119                                         && (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft > 0) ) {\r
120 \r
121                                         timerDec(Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeRepetitionPeriodTimer);\r
122 \r
123                                         // Is it time for a transmission?\r
124                                         if ( (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeRepetitionPeriodTimer == 0)\r
125                                                 && (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) ) {\r
126 \r
127                                                 Com_TriggerIPduSend(i);\r
128 \r
129                                                 // Reset periodic timer\r
130                                                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeRepetitionPeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeRepetitionPeriodFactor;\r
131 \r
132                                                 // Register this nth-transmission.\r
133                                                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft--;\r
134                                         }\r
135                                 }\r
136 \r
137                                 // Is it time for a cyclic transmission?\r
138                                 if ( (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer == 0) && (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) ) {\r
139 \r
140                                         Com_TriggerIPduSend(i);\r
141 \r
142                                         // Reset periodic timer.\r
143                                         Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimePeriodFactor;\r
144                                 }\r
145 \r
146                         // If IPDU has direct transmission mode.\r
147                         } else if (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == DIRECT) {\r
148                                 // Do we need to transmit anything?\r
149                                 if (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft > 0) {\r
150                                         timerDec(Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeRepetitionPeriodTimer);\r
151 \r
152                                         // Is it time for a transmission?\r
153                                         if ( (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeRepetitionPeriodTimer == 0) && (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) ) {\r
154                                                 Com_TriggerIPduSend(i);\r
155 \r
156                                                 // Reset periodic timer\r
157                                                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeRepetitionPeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeRepetitionPeriodFactor;\r
158 \r
159                                                 // Register this nth-transmission.\r
160                                                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft--;\r
161                                         }\r
162                                 }\r
163 \r
164                         // The IDPU has NONE transmission mode.\r
165                         } else {\r
166                                 // Don't send!\r
167                         }\r
168                 }\r
169 \r
170                 Irq_Restore(irq_state);\r
171         }\r
172 }\r