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

Last change on this file was 51b3cbca, checked in by Sebastian Huber <sebastian.huber@…>, on 10/04/18 at 13:23:25

tests: Use rtems_task_exit()

Update #3533.

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