📄 sci_ds.lst
字号:
C51 COMPILER V6.10 SCI_DS 04/18/2001 16:48:39 PAGE 1
C51 COMPILER V6.10, COMPILATION OF MODULE SCI_DS
OBJECT MODULE PLACED IN .\SCI_DS.OBJ
COMPILER INVOKED BY: C:\KEIL\C51\BIN\C51.EXE .\SCI_DS.C OPTIMIZE(6,SIZE) BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*------------------------------------------------------------------*-
2
3 SCI_Ds.c (v1.00)
4
5 ------------------------------------------------------------------
6
7 This is an implementation of SCI SCHEDULER (DATA) for 8051/52.
8
9 --- See Chapter 26 ---
10
11 *** SLAVE NODE ***
12
13 *** Uses 1232 watchdog timer ***
14
15 *** Both Master and Slave share the same tick rate (1 ms) ***
16 *** - See Master code for details ***
17
18
19 COPYRIGHT
20 ---------
21
22 This code is from the book:
23
24 PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont
25 [Pearson Education, 2001; ISBN: 0-201-33138-1].
26
27 This code is copyright (c) 2001 by Michael J. Pont.
28
29 See book for copyright details and other information.
30
31 -*------------------------------------------------------------------*/
32
33 #include "Main.h"
34 #include "Port.h"
35
36 #include "SCI_Ds.h"
37 #include "TLight_B.h"
38
39 // ------ Public variable definitions ------------------------------
40
41 // Data sent from the master to this slave
42 tByte Tick_message_data_G = RETURN_NORMAL;
43
44 // Data sent from this slave to the master
45 // - data may be sent on, by the master, to another slave
46 tByte Ack_message_data_G = RETURN_NORMAL;
47
48 // ------ Public variable declarations -----------------------------
49
50 // The array of tasks (see Sch51.c)
51 extern sTask SCH_tasks_G[SCH_MAX_TASKS];
52
53 // The error code variable (see Sch51.c)
54 extern tByte Error_code_G;
55
C51 COMPILER V6.10 SCI_DS 04/18/2001 16:48:39 PAGE 2
56 // ------ Private function prototypes ------------------------------
57
58 static void SCI_D_SLAVE_Enter_Safe_State(void);
59
60 static void SCI_D_SLAVE_Send_Ack_Message_To_Master(void);
61 static void SCI_D_SLAVE_Process_Tick_Message(void);
62
63 static void SCI_D_SLAVE_Watchdog_Init(void);
64 static void SCI_D_SLAVE_Watchdog_Refresh(void) reentrant;
65
66 /*------------------------------------------------------------------*-
67
68 SCI_D_SLAVE_Init()
69
70 Scheduler initialisation function. Prepares scheduler
71 data structures and sets up timer interrupts at required rate.
72
73 Must call this function before using the scheduler.
74
75 -*------------------------------------------------------------------*/
76 void SCI_D_SLAVE_Init(void)
77 {
78 1 tByte i;
79 1
80 1 // Sort out the tasks
81 1 for (i = 0; i < SCH_MAX_TASKS; i++)
82 1 {
83 2 SCH_Delete_Task(i);
84 2 }
85 1
86 1 // Reset the global error variable
87 1 // - SCH_Delete_Task() will generate an error code,
88 1 // (because the task array is empty)
89 1 Error_code_G = 0;
90 1
91 1 // ---------- External interrupt 0 ----------
92 1 // The slave is driven by an interrupt input
93 1 // The interrupt is enabled
94 1 // It is triggered by a falling edge at pin P3.2
95 1 IT0 = 1;
96 1 EX0 = 1;
97 1
98 1 // Start the watchdog
99 1 SCI_D_SLAVE_Watchdog_Init();
100 1 }
101
102 /*------------------------------------------------------------------*-
103
104 SCI_D_SLAVE_Start()
105
106 Starts the slave scheduler, by enabling interrupts.
107
108 NOTE: Usually called after all regular tasks are added,
109 to keep the tasks synchronised.
110
111 NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!!
112
113 -*------------------------------------------------------------------*/
114 void SCI_D_SLAVE_Start(void)
115 {
116 1 // Place system in a safe state
117 1 // - slave will keep returning here if master does not start
C51 COMPILER V6.10 SCI_DS 04/18/2001 16:48:39 PAGE 3
118 1 // - or otherwise fails.
119 1 SCI_D_SLAVE_Enter_Safe_State();
120 1
121 1 // Now in a safe state
122 1 // Wait here - indefinitely - for the first tick
123 1 // (Refresh the watchdog to avoid constant watchdog restarts)
124 1 while (IE0 == 0)
125 1 {
126 2 SCI_D_SLAVE_Watchdog_Refresh();
127 2 }
128 1
129 1 // Clear the flag
130 1 IE0 = 0;
131 1
132 1 // Start the scheduler
133 1 EA = 1;
134 1 }
135
136 /*------------------------------------------------------------------*-
137
138 SCI_D_SLAVE_Update
139
140 This is the scheduler ISR. It is called at a rate
141 determined by the timer settings in SCI_D_SLAVE_Init().
142
143 This Slave is triggered by external interrupts.
144
145 -*------------------------------------------------------------------*/
146 void SCI_D_SLAVE_Update(void) interrupt INTERRUPT_EXTERNAL_0
147 {
148 1 tByte Index;
149 1
150 1 // Extract the tick-message data
151 1 SCI_D_SLAVE_Process_Tick_Message();
152 1
153 1 // Send data back to Master
154 1 SCI_D_SLAVE_Send_Ack_Message_To_Master();
155 1
156 1 // Feed the watchdog
157 1 SCI_D_SLAVE_Watchdog_Refresh();
158 1
159 1 // Now do 'standard' scheduler updates
160 1
161 1 // NOTE: calculations are in *TICKS* (not milliseconds)
162 1 for (Index = 0; Index < SCH_MAX_TASKS; Index++)
163 1 {
164 2 // Check if there is a task at this location
165 2 if (SCH_tasks_G[Index].pTask)
166 2 {
167 3 if (SCH_tasks_G[Index].Delay == 0)
168 3 {
169 4 // The task is due to run
170 4 SCH_tasks_G[Index].RunMe += 1; // Incr. the run flag
171 4
172 4 if (SCH_tasks_G[Index].Period)
173 4 {
174 5 // Schedule this periodic task to run again
175 5 SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
176 5 }
177 4 }
178 3 else
179 3 {
C51 COMPILER V6.10 SCI_DS 04/18/2001 16:48:39 PAGE 4
180 4 // Not yet ready to run: just decrement the delay
181 4 SCH_tasks_G[Index].Delay -= 1;
182 4 }
183 3 }
184 2 }
185 1 }
186
187 /*------------------------------------------------------------------*-
188
189 SCI_D_SLAVE_Send_Ack_Message_To_Master()
190
191 Slave must send and 'Acknowledge' message to the master, after
192 tick messages are received.
193
194 The acknowledge message serves two purposes:
195 [1] It confirms to the master that the slave is alive & well.
196 [2] It provides a means of sending data to the master.
197
198 -*------------------------------------------------------------------*/
199 void SCI_D_SLAVE_Send_Ack_Message_To_Master(void)
200 {
201 1 SCI_Transfer_Port = Ack_message_data_G;
202 1 }
203
204 /*------------------------------------------------------------------*-
205
206 SCI_D_SLAVE_Process_Tick_Message()
207
208 The ticks messages are crucial to the operation of this S-C
209 scheduler: the arrival of a tick message (at regular intervals)
210 invokes the 'Update' ISR, that drives the scheduler.
211
212 The tick messages themselves may contain data. These data are
213 extracted in this function.
214
215 -*------------------------------------------------------------------*/
216 void SCI_D_SLAVE_Process_Tick_Message(void)
217 {
218 1 // Set up port for reading
219 1 SCI_Transfer_Port = 0xFF;
220 1
221 1 // Read the data
222 1 Tick_message_data_G = SCI_Transfer_Port;
223 1 }
224
225
226 /*------------------------------------------------------------------*-
227
228 SCI_D_SLAVE_Watchdog_Init()
229
230 This function sets up the watchdog timer.
231
232 If the Master fails (or other error develop),
233 no tick messages will arrive, and the scheduler
234 will stop.
235
236 To detect this situation, we have a (hardware) watchdog
237 running in the slave. This watchdog - which should be set to
238 overflow at around 100ms - is used to set the system into a
239 known (safe) state. The slave will then wait (indefinitely)
240 for the problem to be resolved.
241
C51 COMPILER V6.10 SCI_DS 04/18/2001 16:48:39 PAGE 5
242 NOTE: The slave will not be generating Ack messages in these
243 circumstances. The Master (if running) will therefore be aware
244 that there is a problem.
245
246 -*------------------------------------------------------------------*/
247 void SCI_D_SLAVE_Watchdog_Init(void)
248 {
249 1 // INIT NOT REQUIRED FOR 1232 EXTERNAL WATCHDOG
250 1 // - May be required wwith different watchdog hardware
251 1 //
252 1 // Edit as required
253 1 }
254
255
256 /*------------------------------------------------------------------*-
257
258 SCI_D_SLAVE_Watchdog_Refresh()
259
260 Feed the external (1232) watchdog.
261
262 Timeout is between ~60 and 250 ms (hardware dependent)
263
264 HARDWARE: Assumes external 1232 watchdog
265
266 -*------------------------------------------------------------------*/
267 void SCI_D_SLAVE_Watchdog_Refresh(void) reentrant
268 {
269 1 static bit WATCHDOG_state;
270 1
271 1 // Change the state of the watchdog pin
272 1 if (WATCHDOG_state == 1)
273 1 {
274 2 WATCHDOG_state = 0;
275 2 WATCHDOG_pin = 0;
276 2 }
277 1 else
278 1 {
279 2 WATCHDOG_state = 1;
280 2 WATCHDOG_pin = 1;
281 2 }
282 1 }
283
284 /*------------------------------------------------------------------*-
285
286 SCI_D_SLAVE_Enter_Safe_State()
287
288 This is the state enterted by the system when:
289 (1) The node is powered up or reset
290 (2) The Master node fails
291 (3) The network has an error
292 (4) Tick messages are delayed for any other reason
293
294 Try to ensure that the system is in a 'safe' state in these
295 circumstances.
296
297 -*------------------------------------------------------------------*/
298 void SCI_D_SLAVE_Enter_Safe_State(void)
299 {
300 1 // USER DEFINED - Edit as required
301 1 TRAFFIC_LIGHTS_Display_Safe_Output();
302 1 }
303
C51 COMPILER V6.10 SCI_DS 04/18/2001 16:48:39 PAGE 6
304 /*------------------------------------------------------------------*-
305 ---- END OF FILE -------------------------------------------------
306 -*------------------------------------------------------------------*/
307
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 229 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 2 1
IDATA SIZE = ---- ----
BIT SIZE = 1 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -