File indexing completed on 2025-05-11 08:24:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038
0039 #define CONFIGURE_INIT
0040 #include "system.h"
0041
0042 #include <bsp.h>
0043 #include <rtems/btimer.h>
0044 #include <rtems/score/schedulerpriorityimpl.h>
0045
0046 #define _RTEMS_TMTEST27
0047 #include <tm27.h>
0048
0049 const char rtems_test_name[] = "TIME TEST 27";
0050
0051 rtems_task Task_1(
0052 rtems_task_argument argument
0053 );
0054
0055 rtems_task Task_2(
0056 rtems_task_argument argument
0057 );
0058
0059 volatile uint32_t Interrupt_occurred;
0060 volatile uint32_t Interrupt_enter_time, Interrupt_enter_nested_time;
0061 volatile uint32_t Interrupt_return_time, Interrupt_return_nested_time;
0062 uint32_t Interrupt_nest;
0063 uint32_t timer_overhead;
0064
0065 static void set_thread_executing( Thread_Control *thread )
0066 {
0067 _Per_CPU_Get_snapshot()->executing = thread;
0068 }
0069
0070 rtems_task Init(
0071 rtems_task_argument argument
0072 )
0073 {
0074 rtems_status_code status;
0075
0076 Print_Warning();
0077
0078 TEST_BEGIN();
0079
0080 if (
0081 _Scheduler_Table[ 0 ].Operations.initialize
0082 != _Scheduler_priority_Initialize
0083 ) {
0084 puts(" Error ==> " );
0085 puts("Test only supported for deterministic priority scheduler\n" );
0086 TEST_END();
0087 rtems_test_exit( 0 );
0088 }
0089
0090 #define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 1u)
0091 status = rtems_task_create(
0092 rtems_build_name( 'T', 'A', '1', ' ' ),
0093 LOW_PRIORITY,
0094 RTEMS_MINIMUM_STACK_SIZE,
0095 RTEMS_DEFAULT_MODES,
0096 RTEMS_DEFAULT_ATTRIBUTES,
0097 &Task_id[ 1 ]
0098 );
0099 directive_failed( status, "rtems_task_create Task_1" );
0100
0101 status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
0102 directive_failed( status, "rtems_task_start Task_1" );
0103
0104 status = rtems_task_create(
0105 rtems_build_name( 'T', 'A', '2', ' ' ),
0106 LOW_PRIORITY,
0107 RTEMS_MINIMUM_STACK_SIZE,
0108 RTEMS_DEFAULT_MODES,
0109 RTEMS_DEFAULT_ATTRIBUTES,
0110 &Task_id[ 2 ]
0111 );
0112 directive_failed( status, "rtems_task_create of Task_2" );
0113
0114 status = rtems_task_start( Task_id[ 2 ], Task_2, 0 );
0115 directive_failed( status, "rtems_task_start of Task_2" );
0116
0117 benchmark_timer_initialize();
0118 benchmark_timer_read();
0119 benchmark_timer_initialize();
0120 timer_overhead = benchmark_timer_read();
0121
0122 rtems_task_exit();
0123 }
0124
0125
0126
0127
0128
0129
0130 static void Isr_handler_inner( void )
0131 {
0132
0133
0134 Clear_tm27_intr();
0135 switch ( Interrupt_nest ) {
0136 case 0:
0137 Interrupt_enter_time = end_time;
0138 break;
0139 case 1:
0140 Interrupt_enter_time = end_time;
0141 Interrupt_nest = 2;
0142 Interrupt_occurred = 0;
0143 Lower_tm27_intr();
0144 benchmark_timer_initialize();
0145 Cause_tm27_intr();
0146
0147 #if (MUST_WAIT_FOR_INTERRUPT == 1)
0148 while ( Interrupt_occurred == 0 );
0149 #endif
0150 Interrupt_return_nested_time = benchmark_timer_read();
0151 break;
0152 case 2:
0153 Interrupt_enter_nested_time = end_time;
0154 break;
0155 }
0156
0157 benchmark_timer_initialize();
0158 }
0159
0160 #ifdef TM27_USE_VECTOR_HANDLER
0161 static rtems_isr Isr_handler( rtems_vector_number arg )
0162 #else
0163 static void Isr_handler( void *arg )
0164 #endif
0165 {
0166 (void) arg;
0167
0168 end_time = benchmark_timer_read();
0169
0170 Interrupt_occurred = 1;
0171 Isr_handler_inner();
0172 }
0173
0174 rtems_task Task_1(
0175 rtems_task_argument argument
0176 )
0177 {
0178 Scheduler_priority_Context *scheduler_context =
0179 _Scheduler_priority_Get_context( _Thread_Scheduler_get_home( _Thread_Get_executing() ) );
0180 #if defined(RTEMS_SMP)
0181 rtems_interrupt_level level;
0182 #endif
0183
0184 Install_tm27_vector( Isr_handler );
0185
0186
0187
0188
0189
0190 Interrupt_nest = 0;
0191
0192 Interrupt_occurred = 0;
0193
0194 benchmark_timer_initialize();
0195 Cause_tm27_intr();
0196
0197
0198 #if (MUST_WAIT_FOR_INTERRUPT == 1)
0199 while ( Interrupt_occurred == 0 );
0200 #endif
0201 Interrupt_return_time = benchmark_timer_read();
0202
0203 put_time(
0204 "rtems interrupt: entry overhead returns to interrupted task",
0205 Interrupt_enter_time,
0206 1,
0207 0,
0208 timer_overhead
0209 );
0210
0211 put_time(
0212 "rtems interrupt: exit overhead returns to interrupted task",
0213 Interrupt_return_time,
0214 1,
0215 0,
0216 timer_overhead
0217 );
0218
0219
0220
0221
0222
0223 _Thread_Dispatch_disable();
0224
0225 Interrupt_nest = 1;
0226
0227 Interrupt_occurred = 0;
0228 benchmark_timer_initialize();
0229 Cause_tm27_intr();
0230
0231
0232 #if (MUST_WAIT_FOR_INTERRUPT == 1)
0233 while ( Interrupt_occurred == 0 );
0234 #endif
0235 Interrupt_return_time = benchmark_timer_read();
0236
0237 _Thread_Dispatch_enable( _Per_CPU_Get() );
0238
0239 put_time(
0240 "rtems interrupt: entry overhead returns to nested interrupt",
0241 Interrupt_enter_nested_time,
0242 1,
0243 0,
0244 0
0245 );
0246
0247 put_time(
0248 "rtems interrupt: exit overhead returns to nested interrupt",
0249 Interrupt_return_nested_time,
0250 1,
0251 0,
0252 0
0253 );
0254
0255
0256
0257
0258
0259 #if defined(RTEMS_SMP)
0260 _ISR_Local_disable(level);
0261 #endif
0262
0263 set_thread_executing(
0264 (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
0265 );
0266
0267 _Thread_Dispatch_necessary = 1;
0268
0269 #if defined(RTEMS_SMP)
0270 _ISR_Local_enable(level);
0271 #endif
0272
0273 Interrupt_occurred = 0;
0274 benchmark_timer_initialize();
0275 Cause_tm27_intr();
0276
0277
0278
0279
0280
0281 TEST_END();
0282 rtems_test_exit( 0 );
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 rtems_task Task_2(
0294 rtems_task_argument argument
0295 )
0296 {
0297 Thread_Control *executing = _Thread_Get_executing();
0298 const Scheduler_Control *scheduler;
0299 Scheduler_priority_Context *scheduler_context;
0300 ISR_lock_Context state_lock_context;
0301 ISR_lock_Context scheduler_lock_context;
0302
0303 _Thread_State_acquire( executing, &state_lock_context );
0304 scheduler = _Thread_Scheduler_get_home( executing );
0305 scheduler_context = _Scheduler_priority_Get_context( scheduler );
0306 _Thread_State_release( executing, &state_lock_context );
0307
0308 #if (MUST_WAIT_FOR_INTERRUPT == 1)
0309 while ( Interrupt_occurred == 0 );
0310 #endif
0311 end_time = benchmark_timer_read();
0312
0313 put_time(
0314 "rtems interrupt: entry overhead returns to preempting task",
0315 Interrupt_enter_time,
0316 1,
0317 0,
0318 timer_overhead
0319 );
0320
0321 put_time(
0322 "rtems interrupt: exit overhead returns to preempting task",
0323 end_time,
0324 1,
0325 0,
0326 0
0327 );
0328
0329 fflush( stdout );
0330
0331
0332
0333
0334
0335 _Thread_State_acquire( executing, &state_lock_context );
0336 _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
0337
0338 set_thread_executing(
0339 (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
0340 );
0341
0342 _Thread_Dispatch_necessary = 1;
0343
0344 _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
0345 _Thread_State_release( executing, &state_lock_context );
0346
0347 _Thread_Dispatch();
0348
0349 }