*/ /* Get frame_index from event message queue and copy 24 frames */ /* from temp_memory to protected_memory... We will not implement the overwrite rules in the case when protected mem
Trang 1/**** Entry function definition of thread event_recorder ****/
/************************************************************/
void event_recorder_process(ULONG thread_input)
{
ULONG frame, event_priority, event_time, index, frame_data[2];
while (1)
{
/* Copy an event from temporary memory to protected memory */
/* Get frame_index from event message queue and copy 24 frames */
/* from temp_memory to protected_memory */
tx_queue_receive (&event_notice, frame_data, TX_NO_WAIT);
/* Store event time and event priority in protected memory */
frame = frame_data[0];
event_priority = frame_data[1];
event_time = temp_memory[frame][0];
printf("**Event** Time: %5lu Count: %2lu Pri: %lu",
event_time, event_count, event_priority);
if (event_count < MAX_EVENTS)
{
tx_mutex_get (&memory_mutex, TX_WAIT_FOREVER);
protected_memory[event_count][0] = event_time;
protected_memory[event_count][1] = event_priority;
if (frame < 11)
frame = (MAX_TEMP_MEMORY-1) - (frame_index+1);
for (index=0; index<24; index++)
{
protected_memory[event_count][index+2] = temp_memory[frame][1]; frame = (frame+1) % MAX_TEMP_MEMORY;
}
tx_mutex_put (&memory_mutex);
event_count++;
}
else printf(" **not processed**");
printf ("\n");
tx_thread_suspend(&event_recorder);
}
}
Figure 14.28: Function defi nitions Part 4 — event_recorder entry function
a Get the mutex
b Store the event time and priority in the next available position in protected memory
c Store the 24 seconds of frame data from temporary memory to protected memory
d Increment the event counter
e Release the mutex
Trang 2We will not implement the overwrite rules in the case when protected memory is full These rules depend on the actual fi le system used, and are left as an exercise for the
reader When protected memory is full, we will display a message to that effect, but will not copy the event
Figure 14.29 contains the defi nition for the print_stats expiration function, which is part
of the timer called stats_timer This timer expires every 1,000 timer-ticks and the function displays a statistical summary of the system
We have now discussed most of the components of the VAM system The next section contains a complete listing of the system, which also appears on the CD at the back of the book
/************************************************************/
/*********** print statistics at specified times ************/
/************************************************************/
void print_stats (ULONG invalue)
{
UINT row, col;
printf("\n\n**** VAM System Periodic Event Summary\n\n");
printf(" Current Time: %lu\n", tx_time_get()); printf(" Number of Crashes: %lu\n", num_crashes);
printf(" Number of Unsafe Events: %lu\n", num_unsafe);
printf(" Number of Warnings: %lu\n", num_warning);
printf(" Number of Manual Events: %lu\n", num_manual);
if (event_count > 0)
{
printf("\n\n**** Portion of Protected Memory Contents\n\n");
printf("%6s%6s%6s\n", "Time", "Pri", "Data");
for (row = 0; row < event_count; row++)
{
for (col = 0; col < 8; col++)
printf("%6lu", protected_memory[row][col]);
printf(" (etc.)\n");
}
}
if (event_count >= MAX_EVENTS)
printf(" Warning: Protected Memory is full \n\n");
}
Figure 14.29: Function defi nitions Part 5 — print_stats expiration function
Trang 314.6 Listing of VAM System
001 /* 14_case_study.c
002
003 Implement a simplifi ed version of a real-time, video/audio/
004 recording system
005
event_recorder
my_byte_pool
009 Create one message queue to store event notices:
event_notice
unsafe_interrupt,
013
014 For this system, assume that each timer-tick represents
one second */
015
019
020 #include “ tx_api.h ”
021 #include stdio.h
022
023 #defi ne STACK_SIZE 1024
024 #defi ne BYTE_POOL_SIZE 9120
025 #defi ne MAX_EVENTS 16
026 #defi ne MAX_TEMP_MEMORY 200
027
028
029 /* Defi ne the ThreadX object control blocks */
030
031 TX_THREAD initializer;
032 TX_THREAD data_capture;
Trang 4033 TX_THREAD event_recorder;
034
035 TX_QUEUE event_notice;
036
037 TX_MUTEX memory_mutex;
038 TX_BYTE_POOL my_byte_pool;
039
040 TX_TIMER crash_interrupt;
041 TX_TIMER unsafe_interrupt;
042 TX_TIMER warning_interrupt;
043 TX_TIMER manual_interrupt;
044
045 TX_TIMER crash_copy_scheduler;
046 TX_TIMER unsafe_copy_scheduler;
047 TX_TIMER warning_copy_scheduler;
048 TX_TIMER manual_copy_scheduler;
049 TX_TIMER stats_timer;
050
051
053
054 ULONG num_crashes 0, num_unsafe 0, num_warning 0,
num_manual 0;
056
063
065 protected_memory[MAX_EVENTS][26];
066
067 /* Defi ne thread and function prototypes */
068
069 void initializer_process(ULONG);
070 void data_capture_process(ULONG);
071 void event_recorder_process(ULONG);
Trang 5072 void crash_ISR(ULONG);
073 void unsafe_ISR(ULONG);
074 void warning_ISR(ULONG);
075 void manual_ISR(ULONG);
076 void crash_copy_activate(ULONG);
077 void unsafe_copy_activate(ULONG);
078 void warning_copy_activate(ULONG);
079 void manual_copy_activate(ULONG);
080 void print_stats(ULONG);
081
082
086
087 /* Defi ne main entry point */
088
089 int main()
090 {
091
092 /* Enter the ThreadX kernel */
094 }
095
096
097
101
102
103 /* Defi ne what the initial system looks like */
104
105 void tx_application_defi ne(void *fi rst_unused_memory)
106 {
107
108 CHAR *byte_pointer;
109
Trang 6112
114 the thread stacks */
115 tx_byte_pool_create( & my_byte_pool, “ my_byte_pool ”
116 fi rst_unused_memory, BYTE_POOL_SIZE);
117
119 tx_byte_allocate( & my_byte_pool, (VOID **) & byte_pointer,
120 STACK_SIZE, TX_NO_WAIT);
121
123 tx_thread_create( & initializer, “ initializer ”
124 initializer_process, 0,
127
129 tx_byte_allocate( & my_byte_pool, (VOID **) & byte_pointer,
130 STACK_SIZE, TX_NO_WAIT);
131
132 /* Create the data_capture thread */
133 tx_thread_create( & data_capture, “ data_capture ”
137
139 tx_byte_allocate( & my_byte_pool, (VOID **) & byte_pointer,
140 STACK_SIZE, TX_NO_WAIT);
141
143 tx_thread_create( & event_recorder, “ event_recorder ”
147
149 tx_timer_create ( & crash_interrupt, “ crash_interrupt ”
crash_ISR,
150 0 1234, 1444, 1444, TX_AUTO_ACTIVATE);
Trang 7151 tx_timer_create ( & unsafe_interrupt, “ unsafe_interrupt ”
unsafe_ISR,
152 0 1234, 760, 760, TX_AUTO_ACTIVATE);
153 tx_timer_create ( & warning_interrupt, “ warning_interrupt ” warning_ISR,
154 0 1234, 410, 410, TX_AUTO_ACTIVATE);
155 tx_timer_create ( & manual_interrupt, “ manual_interrupt ”
manual_ISR,
156 0 1234, 888, 888, TX_AUTO_ACTIVATE);
157
copying */
159 tx_timer_create ( & crash_copy_scheduler,
“ crash_copy_scheduler ”
160 crash_copy_activate, 0 1234, 12, 12,
TX_NO_ACTIVATE);
161 tx_timer_create ( & unsafe_copy_scheduler,
“ unsafe_copy_scheduler ”
162 unsafe_copy_activate, 0 1234, 12, 12,
TX_NO_ACTIVATE);
163 tx_timer_create ( & warning_copy_scheduler,
“ warning_copy_scheduler ”
164 warning_copy_activate, 0 1234, 12, 12, TX_NO_ACTIVATE);
165 tx_timer_create ( & manual_copy_scheduler,
“ manual_copy_scheduler ”
166 manual_copy_activate, 0 1234, 12, 12,
TX_NO_ACTIVATE);
167
periodically */
169 tx_timer_create ( & stats_timer, “ stats_timer ” , print_stats,
170 0 1234, 1000, 1000, TX_AUTO_ACTIVATE);
171
for all events */
array */
current frame_index */
Trang 8175 /* and event priority to the queue for storing crash event information */
the queue */
177 tx_byte_allocate( & my_byte_pool, (VOID **) & byte_pointer,
179 tx_queue_create ( & event_notice, “ event_notice ” , TX_2_ULONG,
181
182 }
183
184
188
189
191
193 {
194 /* Perform initialization tasks */
198 printf( “ VAM System-Trace of Event Activities Begins … \n\n ” );
199 frame_index 0;
200 event_count 0;
201 }
202
205
207 {
memory */
writing */
Trang 9211 /* simplicity, we will write to the array once every tick */
212 while (1) {
213 temp_memory[frame_index][0] tx_time_get();
214 temp_memory[frame_index][1] 0 1234;
215 frame_index (frame_index 1) % MAX_TEMP_MEMORY;
216 tx_thread_sleep(1);
217 }
218 }
219
220
224
begin */
228
229 void crash_ISR (ULONG timer_input)
230 {
231 ULONG frame_data[2];
232 frame_data[0] frame_index;
233 frame_data[1] 1;
234 num_crashes ;
237 tx_queue_send ( & event_notice, frame_data, TX_NO_WAIT);
238 tx_timer_activate ( & crash_copy_scheduler);
239 }
243
245 {
247 tx_thread_resume( & event_recorder);
248 tx_timer_deactivate ( & crash_copy_scheduler);
249 }
Trang 10250
254
256 {
257 ULONG frame, event_priority, event_time, index,
frame_data[2];
258 while (1)
259 {
frames */
263 tx_queue_receive ( &event_notice, frame_data, TX_NO_WAIT);
264 /* Store event time and event priority in protected
memory */
265 frame frame_data[0];
266 event_priority frame_data[1];
267 event_time temp_memory[frame][0];
268 printf( “ **Event** Time: %5lu Count: %2lu Pri: %lu ”
270 if (event_count MAX_EVENTS)
271 {
272 tx_mutex_get ( & memory_mutex, TX_WAIT_FOREVER);
273 protected_memory[event_count][0] event_time;
274 protected_memory[event_count][1] event_priority;
275 if (frame 11)
276 frame (MAX_TEMP_MEMORY-1)-(frame_index 1);
277 for (index 0; index 24; index )
278 {
279 protected_memory[event_count][index 2] temp_
memory[frame][1];
280 frame (frame 1) % MAX_TEMP_MEMORY;
281 }
282 tx_mutex_put ( & memory_mutex);
283 event_count ;
284 }
285 else printf( “ **not processed** ” );
Trang 11286 printf ( “ \n ” );
287 tx_thread_suspend( & event_recorder);
288 }
289 }
290
294
begin */
298
299 void unsafe_ISR (ULONG timer_input)
300 {
301 ULONG frame_data[2];
302 frame_data[0] frame_index;
303 frame_data[1] 2;
304 num_unsafe ;
307 tx_queue_send ( & event_notice, frame_data, TX_NO_WAIT);
308 tx_timer_activate ( & unsafe_copy_scheduler);
309 }
data */
313
315 {
316 /* resume event_recorder thread to initiate data
recording */
317 tx_thread_resume( & event_recorder);
318 tx_timer_deactivate ( & unsafe_copy_scheduler);
319 }
320
321
Trang 12322 /***********************************************************/
325
begin */
329
330 void warning_ISR (ULONG timer_input)
331 {
332 ULONG frame_data[2];
333 frame_data[0] frame_index;
334 frame_data[1] 3;
335 num_warning ;
338 tx_queue_send ( & event_notice, frame_data, TX_NO_WAIT);
339 tx_timer_activate ( & warning_copy_scheduler);
340 }
data */
344
346 {
348 tx_thread_resume( & event_recorder);
349 tx_timer_deactivate ( & warning_copy_scheduler);
350 }
351
352
356
begin */
Trang 13359 /* with a context save and would end with a context restore */
360
361 void manual_ISR (ULONG timer_input)
362 {
363 ULONG frame_data[2];
364 frame_data[0] frame_index;
365 frame_data[1] 4;
366 num_manual ;
369 tx_queue_send ( & event_notice, frame_data, TX_NO_WAIT);
370 tx_timer_activate ( & manual_copy_scheduler);
371 }
data */
375
377 {
379 tx_thread_resume( & event_recorder);
380 tx_timer_deactivate ( & manual_copy_scheduler);
381 }
382
383
387
388 void print_stats (ULONG invalue)
389 {
390 UINT row, col;
391 printf( “ \n\n**** VAM System Periodic Event Summary\n\n ” );
392 printf( “ Current Time: %lu\n ” , tx_time_get());
393 printf( “ Number of Crashes: %lu\n ” , num_crashes);
394 printf( “ Number of Unsafe Events: %lu\n ” , num_unsafe);
395 printf( “ Number of Warnings: %lu\n ” , num_warning);
396 printf( “ Number of Manual Events: %lu\n ” , num_manual);
Trang 14397
398 if (event_count 0)
399 {
400 printf( “ \n\n**** Portion of Protected Memory
Contents\n\n ” );
401 printf( “ %6s%6s%6s\n ” , “ Time ” , “ Pri ” , “ Data ” );
402 for (row 0; row event_count; row )
403 {
404 for (col 0; col 8; col )
405 printf( “ %6lu ” , protected_memory[row][col]);
406 printf( “ (etc.)\n ” );
407 }
408 }
409 if (event_count MAX_EVENTS)
410 printf( “ Warning: Protected Memory is full … \n\n ” );
411 }
14.7 Overview
This case study provides an excellent overview of developing a system with ThreadX We used a variety of ThreadX services, including the following:
● application timers
● threads
● message queue
● mutex
● memory byte pool
This case study depends heavily on the use of application timers One reason for using
so many timers is because we need to schedule the copying of data from the temporary memory to the protected memory whenever any one of four events occurs Our design provides the ability to record several events within each 24-second time frame, rather than just one Application timers play a major role in providing this feature We also used application timers to simulate interrupts that signify the occurrence of events, and we used one timer to display periodic system statistics