source: rtems/testsuites/sptests/sp35/priinv.c @ 496274b6

4.104.114.84.95
Last change on this file since 496274b6 was 496274b6, checked in by Joel Sherrill <joel.sherrill@…>, on 06/20/07 at 21:43:28

2007-06-20 Joel Sherrill <joel.sherrill@…>

  • sp20/task1.c, sp34/changepri.c, sp35/priinv.c: Build when using buffered test IO.
  • Property mode set to 100644
File size: 15.3 KB
Line 
1/*
2 *  Simple test program to demonstrate priority inversion when blocking
3 *
4   -Ulf Ivraeus ------------- --- -- -  -   -
5 *  Saab Ericsson Space AB
6 *  phone:  +46 (0)31 735 4542
7 *  e-mail: ulf.ivraeus@space.se
8 *  ----------------------------- --- -- -  -   -
9 *
10 *  $Id$
11 */
12
13/********************************************************************
14
15  Semaphore Ids:
16    Sync Mutex Id   = 0x18010009
17    Local Mutex Id  = 0x1801000a
18    Remote Mutex Id = 0x1801000b
19
20  Task Ids:
21    TaMedium[0] Id  = 0x08010002
22    TaMedium[1] Id  = 0x08010003
23    TaMedium[2] Id  = 0x08010004
24    TaHigh Id       = 0x08010005
25    TaLow Id        = 0x08010006
26    TaHwSim Id      = 0x08010007
27
28********************************************************************/
29
30/********************************************************************/
31/* define this to use the RTEMS 4.5 scheme for object names */
32/* #define TEST_ON_RTEMS_45 */
33
34/* define this to print the Id of the calling task */
35/* #define TEST_ON_TASK_ID */
36
37/* define this to print statistics when acquiring the mutex */
38/* #define TEST_PRINT_STATISTICS */
39
40/* define this if you are (1) on a ERC32 and (2) want a SW ISR trigger */
41#if defined(__sparc__)
42/* #define TEST_USE_ISR */
43#endif
44
45/* define this if you want the test to exit */
46#define TEST_EXIT_AFTER_ITERATIONS 10
47/********************************************************************/
48
49#define CONFIGURE_INIT
50
51#include <bsp.h>
52#include <stdio.h>
53#include "tmacros.h"
54
55#if defined(TEST_EXIT_AFTER_ITERATIONS)
56volatile uint32_t Iterations = 0;
57#endif
58
59/* Task entry point prototypes */
60rtems_task Medium_Exec(rtems_task_argument TaskArg);
61rtems_task Low_Exec(rtems_task_argument TaskArg);
62rtems_task High_Exec(rtems_task_argument TaskArg);
63rtems_task LocalHwSim_Exec(rtems_task_argument TaskArg);
64
65/* ISR that signals that HW has completed */
66rtems_isr  LocalHwIsr(/*in*/ rtems_vector_number   Vector);
67
68/* Test driver functions */
69void AccessLocalHw(void);
70void AccessRemoteHw(void);
71
72const char *CallerName()
73{
74  static char buffer[32];
75#if defined(TEST_PRINT_TASK_ID)
76  sprintf( buffer, "0x%08x -- %d",
77      _Thread_Executing->Object.id, _Thread_Executing->current_priority );
78#else
79  union {
80    uint32_t u;
81    unsigned char c[4];
82  } TempName;
83
84  #if defined(TEST_ON_RTEMS_45)
85    TempName.u = *(uint32_t *)_Thread_Executing->Object.name;
86  #else
87    TempName.u = (uint32_t) _Thread_Executing->Object.name;
88  #endif
89  sprintf( buffer, "%c%c%c%c -- %d",
90      TempName.c[0], TempName.c[1], TempName.c[2], TempName.c[3],
91      _Thread_Executing->current_priority
92  );
93#endif
94  return buffer;
95}
96
97#define NofMediumTask_C 3
98
99/* RTEMS identifiers */                                               
100rtems_id  TaMedium[NofMediumTask_C]; /* Medium-prio tasks accessing */
101                                     /*    the common local HW */
102rtems_id  TaHwSim;                   /* HW simulator */
103rtems_id  TaLow;                     /* Low-prio task accessing common */
104                                     /*    remote HW */
105rtems_id  TaHigh;                    /* High-prio task accessing common */
106                                     /*    remote HW */
107
108
109rtems_id  LocalHwSync_S;             /* Syncrhonize task to local HW */
110rtems_id  LocalHwAccess_R;           /* Execlusive access to the local HW */
111rtems_id  RemoteHwAccess_R;          /* Execlusive access to the remote HW */
112
113
114/* The following variable triggers simulated HW activity */
115volatile boolean StartHw = FALSE;
116
117rtems_task Medium_Exec(rtems_task_argument TaskArg)
118{
119  printf("Medium_Exec (%d) begins...\n", TaskArg);
120
121  rtems_task_wake_after(50);
122
123  while(1) {
124    AccessLocalHw();
125  }
126
127  /* JRS - task does not get here */
128
129  printf("Medium_Exec (%d) ends...\n", TaskArg);
130  while(1) {
131    rtems_task_wake_after(10000);
132  }
133}
134
135rtems_task High_Exec(rtems_task_argument TaskArg)
136{
137  printf("High_Exec (%d) begins...\n", TaskArg);
138
139  /* Delay more than the Low-prio task so that Remote HW access resource is
140   * taken before call to AccesRemoteHw.
141   */
142  rtems_task_wake_after(250);
143
144  while(1) {
145    AccessRemoteHw();
146  }
147
148  /* JRS - task does not get here */
149
150  printf("High_Exec (%d) ends...\n", TaskArg);
151  while(1) {
152    rtems_task_wake_after(10000);
153  }
154  /* task does not get here */
155}
156
157rtems_task Low_Exec(rtems_task_argument TaskArg)
158{
159  printf("Low_Exec (%d) begins...\n", TaskArg);
160
161  /* Delay less than High-prio task so that we take the remote HW access
162   * resource before it does it. However, delay longer than the mid-prio
163   * tasks so that we know for certain that they have taken control over
164   * the local HW access.
165   */
166  rtems_task_wake_after(100);
167
168  while(1) {
169    AccessRemoteHw();
170  }
171
172  /* JRS - task does not get here */
173
174  printf("Low_Exec (%d) ends...\n", TaskArg);
175  while(1) {
176    rtems_task_wake_after(10000);
177  }
178}
179
180
181rtems_task LocalHwSim_Exec(rtems_task_argument TaskArg)
182{
183  int ISRCount = 0;
184  printf("LocalHwSim_Exec begins...\n");
185 
186  while(1) {
187    if (StartHw) {
188      /* A test task has activated the HW, wait for a while and then
189       * generate an interrupt
190       */
191      rtems_task_wake_after(100);
192
193      StartHw = FALSE;
194#if 0
195      fprintf( stderr, "StartHw -- fire ISR (%d)\n", ++ISRCount );
196#endif
197#if defined(TEST_USE_ISR)
198      __asm__ volatile ("ta 5");
199      __asm__ volatile ("nop");
200      __asm__ volatile ("nop");
201#else
202      LocalHwIsr( 0x85 );
203#endif
204    }
205
206  }
207
208  printf("LocalHwSim_Exec ends...\n");
209  while(1) {
210    rtems_task_wake_after(10000);
211  }
212}
213
214
215rtems_isr  LocalHwIsr(/*in*/ rtems_vector_number   Vector)
216{
217  rtems_status_code status;
218
219  /* Signal synchroniztion semaphore to invoke waiting task */
220  status = rtems_semaphore_release(LocalHwSync_S);
221  if (status != RTEMS_SUCCESSFUL) {
222    fprintf( stderr, "LocalHwISR release %d\n", status );
223    while(1); /* Error */
224  }
225
226  return;
227}
228
229void AccessLocalHw(void)
230{
231  rtems_status_code     Sts;
232   
233  rtems_task_priority   EnterPrio;   /* Statistics log */
234  rtems_task_priority   AccessPrio;  /*      :         */
235  rtems_task_priority   LeavePrio;   /*      :         */
236  uint32_t              EnterCnt;    /*      :         */
237  uint32_t              AccessCnt;   /*      :         */
238  uint32_t              LeaveCnt;    /*      :         */
239
240  /* Store information about the current situation */
241  EnterPrio = _Thread_Executing->current_priority;
242  EnterCnt  = _Thread_Executing->resource_count;
243
244
245  printf("  AccessLocalHw called by %s\n", CallerName());
246
247  /* Obtain exclusive access to local HW, Start HW, Wait for completion,
248   * Release access
249   */
250
251  Sts = rtems_semaphore_obtain(LocalHwAccess_R, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
252  directive_failed( Sts, "rtems_semaphore_obtain(LocalHwAccess_R...)" );
253
254  StartHw = TRUE;
255
256  Sts = rtems_semaphore_obtain(LocalHwSync_S, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
257  directive_failed( Sts, "rtems_semaphore_obtain(LocalHwAccess_R...)" );
258
259  /* Store information about the current situation */
260  AccessPrio = _Thread_Executing->current_priority;
261  AccessCnt  = _Thread_Executing->resource_count;
262
263  Sts = rtems_semaphore_release(LocalHwAccess_R);
264  directive_failed( Sts, "rtems_semaphore_release(LocalHwAccess_R)" );
265
266  /* Store information about the current situation */
267  LeavePrio = _Thread_Executing->current_priority;
268  LeaveCnt  = _Thread_Executing->resource_count;
269
270#if defined(TEST_PRINT_STATISTICS)
271  printf(
272    "  AccessLocalHw from %s statistics:\n"
273    " - Prio: %d -> %d -> %d\n - Cnt: %d -> %d -> %d\n",
274    CallerName(),
275    EnterPrio, AccessPrio, LeavePrio,
276    EnterCnt, AccessCnt, LeaveCnt
277  );
278#endif
279
280  printf("  AccessLocalHw returns to %s\n", CallerName());
281  #if defined(TEST_EXIT_AFTER_ITERATIONS)
282    if ( ++Iterations == 10 ) {
283      puts( "*** END OF TEST 35 ***" );
284      exit(0);
285    }
286  #endif
287  return;
288}
289
290void AccessRemoteHw(void)
291{
292  rtems_status_code     Sts;
293   
294  rtems_task_priority   EnterPrio;   /* Statistics log */
295  rtems_task_priority   AccessPrio;  /*      :         */
296  rtems_task_priority   LeavePrio;   /*      :         */
297  uint32_t              EnterCnt;    /*      :         */
298  uint32_t              AccessCnt;   /*      :         */
299  uint32_t              LeaveCnt;    /*      :         */
300
301  /* Store information about the current situation */
302  EnterPrio = _Thread_Executing->current_priority;
303  EnterCnt  = _Thread_Executing->resource_count;
304
305
306  printf("AccessRemoteHw called by %s\n", CallerName());
307
308  /* Obtain exclusive access to remote HW, Start HW, Wait for completion,
309   * Release access
310   */
311
312  Sts = rtems_semaphore_obtain(RemoteHwAccess_R, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
313  directive_failed( Sts, "rtems_semaphore_obtain(RemoteHwAccess_R...)" );
314
315  /* Carry out the remote access via the Local HW interface */
316  printf("AccessRemoteHw access local %s\n", CallerName());
317  AccessLocalHw();
318
319  /* Store information about the current situation */
320  AccessPrio = _Thread_Executing->current_priority;
321  AccessCnt  = _Thread_Executing->resource_count;
322
323  Sts = rtems_semaphore_release(RemoteHwAccess_R);
324  directive_failed( Sts, "rtems_semaphore_release(RemoreHwAccess_R" );
325
326  /* Store information about the current situation */
327  LeavePrio = _Thread_Executing->current_priority;
328  LeaveCnt  = _Thread_Executing->resource_count;
329
330#if defined(TEST_PRINT_STATISTICS)
331  printf(
332    "\nAccessRemoteHw from %s statistics:\n"
333    " - Prio: %d -> %d -> %d\n - Cnt: %d -> %d -> %d\n",
334    CallerName(),
335    EnterPrio, AccessPrio, LeavePrio,
336    EnterCnt, AccessCnt, LeaveCnt);
337#endif
338
339  printf("AccessRemoteHw returns to %s\n", CallerName());
340  return;
341}
342
343/*************************************************************************/
344/**********************        INITIALIZATION        *********************/
345/*************************************************************************/
346
347/* The Init operation (the Init-task) */
348rtems_task Init(rtems_task_argument ignored)
349{
350  rtems_status_code status;   
351#if defined(TEST_USE_ISR)
352  rtems_isr_entry   DummyIsr;
353#endif
354  int i;
355 
356  puts( "\n\n*** TEST 35 ***" );
357
358  /* Create synchronisation semaphore for LocalHwIsr -> Test Tasks */
359  status = rtems_semaphore_create(
360    rtems_build_name ('S', 'Y', 'N', 'C'),           /* name */
361    0,                                               /* initial count = 0 */
362    RTEMS_LOCAL                   |
363    RTEMS_SIMPLE_BINARY_SEMAPHORE |
364    RTEMS_NO_INHERIT_PRIORITY     |
365    RTEMS_NO_PRIORITY_CEILING     |
366    RTEMS_FIFO,
367    0,
368    &LocalHwSync_S);                                 /* *id */
369  directive_failed( status, "rtems_semaphore_create (SYNC)" );
370 
371  printf( "Sync Mutex Id = 0x%08x\n", LocalHwSync_S );
372 
373  /* Create resource semaphore for exclusive access to the local HW */
374  status = rtems_semaphore_create(
375    rtems_build_name ('R', 'E', 'S', '1'), /* name             */
376    1,                                     /* count            */
377    RTEMS_PRIORITY         |
378    RTEMS_BINARY_SEMAPHORE |
379    RTEMS_INHERIT_PRIORITY |
380    RTEMS_LOCAL,                           /* attribute_set    */
381    1, /* insignificant */                 /* priority_ceiling */
382    &LocalHwAccess_R);                     /* *id              */
383  directive_failed( status, "rtems_semaphore_create (RES1)" );
384
385  printf( "Local Mutex Id = 0x%08x\n", LocalHwAccess_R );
386
387  /* Create resource semaphore for exclusive access to the remote HW */
388  status = rtems_semaphore_create(
389    rtems_build_name ('R', 'E', 'S', '2'), /* name             */
390    1,                                     /* count            */
391    RTEMS_PRIORITY         |
392    RTEMS_BINARY_SEMAPHORE |
393    RTEMS_INHERIT_PRIORITY |
394    RTEMS_LOCAL,                           /* attribute_set    */
395    1, /* insignificant */                 /* priority_ceiling */
396    &RemoteHwAccess_R);                    /* *id              */
397  directive_failed( status, "rtems_semaphore_create (RES2)" );
398
399  printf( "Remote Mutex Id = 0x%08x\n", RemoteHwAccess_R );
400 
401#if defined(TEST_USE_ISR)
402  /* Install ISR for HW/SW synchronization, use ta 0x85 which is synchronous */
403  status = rtems_interrupt_catch(LocalHwIsr, 0x85 + 0x100, &DummyIsr);
404  directive_failed( status, "rtems_interrupt_catch" );
405#endif
406
407 
408  printf("Ending Init-task\n");
409  /* Create and start all tasks in the test */
410
411  /* -- Medium-prio Test Tasks --- */
412  for (i = 0; i < NofMediumTask_C; i++) {
413    status = rtems_task_create(
414      rtems_build_name('M','E','D','0'+i),               /* Name */
415      100,                                               /* Priority */
416      RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
417      RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
418      RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
419      &TaMedium[i]);                                     /* Assigned ID */
420    directive_failed( status, "rtems_task_create (MEDn)" );
421
422    printf( "TaMedium[%d] Id = 0x%08x\n", i, TaMedium[i] );
423    status = rtems_task_start(TaMedium[i], Medium_Exec, i);
424    directive_failed( status, "rtems_task_start (MEDn)" );
425  }
426
427  /* -- High-prio Test Task --- */
428  status = rtems_task_create(
429    rtems_build_name('H','I','G','H'),                 /* Name */
430    10,                                                /* Priority */
431    RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
432    RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
433    RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
434    &TaHigh);                                          /* Assigned ID */
435  directive_failed( status, "rtems_task_create (HIGH)" );
436
437  printf( "TaHigh Id = 0x%08x\n", TaHigh );
438  status = rtems_task_start(TaHigh, High_Exec, 0);
439  directive_failed( status, "rtems_task_start (HIGH)" );
440
441  /* -- Low-prio Test Task --- */
442  status = rtems_task_create(
443    rtems_build_name('L','O','W',' '),                 /* Name */
444    200,                                               /* Priority */
445    RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
446    RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
447    RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
448    &TaLow);                                           /* Assigned ID */
449  directive_failed( status, "rtems_task_create (LOW)" );
450
451  printf( "TaLow Id = 0x%08x\n", TaLow );
452  status = rtems_task_start(TaLow, Low_Exec, 0);
453  directive_failed( status, "rtems_task_start (LOW)" );
454
455  /* -- HW Simulator Task --- */
456  status = rtems_task_create(
457    rtems_build_name('H','W','S','M'),                 /* Name */
458    240,                                               /* Priority */
459    RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
460    RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
461    RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
462    &TaHwSim);                                         /* Assigned ID */
463  directive_failed( status, "rtems_task_create (HWSM)" );
464
465  printf( "TaHwSim Id = 0x%08x\n", TaHwSim );
466
467  status = rtems_task_start(TaHwSim, LocalHwSim_Exec, 0);
468  directive_failed( status, "rtems_task_start (HWSM)" );
469
470  /* Destroy the Init task (and let the ready tasks start running) */
471  rtems_task_delete(RTEMS_SELF);
472}
473
474/* configuration information */
475
476#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
477#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
478
479#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
480
481#define CONFIGURE_EXTRA_TASK_STACKS (RTEMS_MINIMUM_STACK_SIZE * 3)
482
483#define CONFIGURE_MAXIMUM_TASKS 10
484#define CONFIGURE_MAXIMUM_SEMAPHORES 10
485
486#include <rtems/confdefs.h>
487
488/* end of file */
Note: See TracBrowser for help on using the repository browser.