source: rtems/testsuites/sptests/sp35/priinv.c @ a986c07

4.104.11
Last change on this file since a986c07 was a986c07, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 14, 2008 at 6:36:00 PM

2008-12-14 Joel Sherrill <joel.sherrill@…>

  • sp07/init.c, sp12/init.c, sp12/pridrv.c, sp12/pritask.c, sp12/system.h, sp16/system.h, sp25/system.h, sp26/task1.c, sp28/init.c, sp29/init.c, sp35/priinv.c, sp42/init.c: Run all tests successfully with maxixum number of priorities as 16 instead of 256. This was done by temporarily modifying the score priority.h maximum. This allowed testing of all API code to ensure that it worked properly with a reduced number of priorities. Most modifications were to switch from hard-coded maximum to using the API provided methods to determine maximum number of priority levels.
  • Property mode set to 100644
File size: 15.5 KB
RevLine 
[88e8cc4d]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
[496274b6]49#define CONFIGURE_INIT
50
[88e8cc4d]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",
[b5c6ecf]77      rtems_task_self(), _Thread_Executing->current_priority );
[88e8cc4d]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
[23a368d]87    TempName.u = (uint32_t) _Thread_Executing->Object.name.name_u32;
[88e8cc4d]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 */
[f0157b8]115volatile bool StartHw = false;
[88e8cc4d]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++) {
[a986c07]413#define MEDIUM_PRIORITY ((RTEMS_MAXIMUM_PRIORITY / 2) + 1)
[88e8cc4d]414    status = rtems_task_create(
415      rtems_build_name('M','E','D','0'+i),               /* Name */
[a986c07]416      MEDIUM_PRIORITY,                                   /* Priority */
[88e8cc4d]417      RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
418      RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
419      RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
420      &TaMedium[i]);                                     /* Assigned ID */
421    directive_failed( status, "rtems_task_create (MEDn)" );
422
423    printf( "TaMedium[%d] Id = 0x%08x\n", i, TaMedium[i] );
424    status = rtems_task_start(TaMedium[i], Medium_Exec, i);
425    directive_failed( status, "rtems_task_start (MEDn)" );
426  }
427
428  /* -- High-prio Test Task --- */
[a986c07]429#define HIGH_PRIORITY ((RTEMS_MAXIMUM_PRIORITY / 2))
[88e8cc4d]430  status = rtems_task_create(
431    rtems_build_name('H','I','G','H'),                 /* Name */
[a986c07]432    HIGH_PRIORITY,                                     /* Priority */
[88e8cc4d]433    RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
434    RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
435    RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
436    &TaHigh);                                          /* Assigned ID */
437  directive_failed( status, "rtems_task_create (HIGH)" );
438
439  printf( "TaHigh Id = 0x%08x\n", TaHigh );
440  status = rtems_task_start(TaHigh, High_Exec, 0);
441  directive_failed( status, "rtems_task_start (HIGH)" );
442
443  /* -- Low-prio Test Task --- */
[a986c07]444#define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 1)
[88e8cc4d]445  status = rtems_task_create(
446    rtems_build_name('L','O','W',' '),                 /* Name */
[a986c07]447    LOW_PRIORITY,                                      /* Priority */
[88e8cc4d]448    RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
449    RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
450    RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
451    &TaLow);                                           /* Assigned ID */
452  directive_failed( status, "rtems_task_create (LOW)" );
453
454  printf( "TaLow Id = 0x%08x\n", TaLow );
455  status = rtems_task_start(TaLow, Low_Exec, 0);
456  directive_failed( status, "rtems_task_start (LOW)" );
457
458  /* -- HW Simulator Task --- */
[a986c07]459#define HWTASK_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 2)
[88e8cc4d]460  status = rtems_task_create(
461    rtems_build_name('H','W','S','M'),                 /* Name */
[a986c07]462    HWTASK_PRIORITY,                                   /* Priority */
[88e8cc4d]463    RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
464    RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
465    RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
466    &TaHwSim);                                         /* Assigned ID */
467  directive_failed( status, "rtems_task_create (HWSM)" );
468
469  printf( "TaHwSim Id = 0x%08x\n", TaHwSim );
470
471  status = rtems_task_start(TaHwSim, LocalHwSim_Exec, 0);
472  directive_failed( status, "rtems_task_start (HWSM)" );
473
474  /* Destroy the Init task (and let the ready tasks start running) */
475  rtems_task_delete(RTEMS_SELF);
476}
477
478/* configuration information */
479
[67293f6]480#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
481#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
[88e8cc4d]482
483#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
484
[2ff6ada3]485#define CONFIGURE_EXTRA_TASK_STACKS (RTEMS_MINIMUM_STACK_SIZE * 3)
[88e8cc4d]486
487#define CONFIGURE_MAXIMUM_TASKS 10
488#define CONFIGURE_MAXIMUM_SEMAPHORES 10
489
490#include <rtems/confdefs.h>
491
492/* end of file */
Note: See TracBrowser for help on using the repository browser.