/* test bodies */ void test_interrupt_inline(void) { rtems_interrupt_level level; rtems_attribute level_attribute, level_attribute_macro; bool in_isr; puts( "interrupt is in progress (use body)" ); in_isr = rtems_interrupt_is_in_progress(); if ( in_isr ) { puts( "interrupt reported to be is in progress (body)" ); rtems_test_exit( 0 ); } puts( "interrupt disable (use inline)" ); rtems_interrupt_disable( level ); puts( "interrupt flash (use inline)" ); rtems_interrupt_flash( level ); puts( "interrupt enable (use inline)" ); rtems_interrupt_enable( level ); puts( "interrupt level attribute (use inline)" ); level_attribute = rtems_interrupt_level_attribute( level ); level_attribute_macro = RTEMS_INTERRUPT_LEVEL(level); if ( level_attribute_macro == level_attribute ) { puts( "test case working.." ); } }
rtems_task High_task( rtems_task_argument argument ) { rtems_interrupt_level level; benchmark_timer_initialize(); rtems_interrupt_disable( level ); isr_disable_time = benchmark_timer_read(); benchmark_timer_initialize(); rtems_interrupt_flash( level ); isr_flash_time = benchmark_timer_read(); benchmark_timer_initialize(); rtems_interrupt_enable( level ); isr_enable_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Disable_dispatch(); thread_disable_dispatch_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Enable_dispatch(); thread_enable_dispatch_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Set_state( _Thread_Executing, STATES_SUSPENDED ); thread_set_state_time = benchmark_timer_read(); _Context_Switch_necessary = true; benchmark_timer_initialize(); _Thread_Dispatch(); /* dispatches Middle_task */ }
/* * Read time from chip */ int mc146818a_get_time( int minor, rtems_time_of_day *time ) { uint32_t mc146818a; getRegister_f getReg; uint32_t value; rtems_interrupt_level level; mc146818a = RTC_Table[ minor ].ulCtrlPort1; getReg = RTC_Table[ minor ].getRegister; /* * No time if power failed */ if (((*getReg)( mc146818a, MC146818A_STATUSD ) & MC146818ASD_PWR) == 0) return -1; /* * Wait for time update to complete */ rtems_interrupt_disable( level ); while (((*getReg)( mc146818a, MC146818A_STATUSA ) & MC146818ASA_TUP) != 0) { rtems_interrupt_flash( level ); } /* * Read the time (we have at least 244 usec to do this) */ value = (*getReg)( mc146818a, MC146818A_YEAR ); value = From_BCD( value ); if ( value < 88 ) time->year = 2000 + value; else time->year = 1900 + value; value = (*getReg)( mc146818a, MC146818A_MONTH ); time->month = From_BCD( value ); value = (*getReg)( mc146818a, MC146818A_DAY ); time->day = From_BCD( value ); value = (*getReg)( mc146818a, MC146818A_HRS ); time->hour = From_BCD( value ); value = (*getReg)( mc146818a, MC146818A_MIN ); time->minute = From_BCD( value ); value = (*getReg)( mc146818a, MC146818A_SEC ); rtems_interrupt_enable( level ); time->second = From_BCD( value ); time->ticks = 0; return 0; }
rtems_status_code lpc24xx_gpio_config( unsigned pin, lpc24xx_gpio_settings settings ) { if (pin <= LPC24XX_IO_INDEX_MAX) { rtems_interrupt_level level; unsigned port = LPC24XX_IO_PORT(pin); unsigned bit = LPC24XX_IO_PORT_BIT(pin); unsigned select = LPC24XX_IO_SELECT(pin); unsigned shift = LPC24XX_IO_SELECT_SHIFT(pin); unsigned resistor = settings & LPC24XX_GPIO_RESISTOR_MASK; unsigned output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U; /* Get resistor flags */ switch (resistor) { case LPC24XX_GPIO_RESISTOR_PULL_UP: case LPC24XX_GPIO_RESISTOR_DEFAULT: resistor = 0x0U; break; case LPC24XX_GPIO_RESISTOR_NONE: resistor = 0x2U; break; case LPC24XX_GPIO_RESISTOR_PULL_DOWN: resistor = 0x3U; break; default: return RTEMS_INVALID_NUMBER; } rtems_interrupt_disable(level); /* Resistor */ LPC24XX_PINMODE [select] = (LPC24XX_PINMODE [select] & ~(LPC24XX_IO_SELECT_MASK << shift)) | ((resistor & LPC24XX_IO_SELECT_MASK) << shift); rtems_interrupt_flash(level); /* Input or output */ LPC24XX_FIO [port].dir = (LPC24XX_FIO [port].dir & ~(1U << bit)) | (output << bit); rtems_interrupt_enable(level); } else { return RTEMS_INVALID_ID; } return RTEMS_SUCCESSFUL; }
static void lpc24xx_io_do_config(unsigned pin, unsigned function) { rtems_interrupt_level level; unsigned select = LPC24XX_IO_SELECT(pin); unsigned shift = LPC24XX_IO_SELECT_SHIFT(pin); rtems_interrupt_disable(level); LPC24XX_PINSEL [select] = (LPC24XX_PINSEL [select] & ~(LPC24XX_IO_SELECT_MASK << shift)) | ((function & LPC24XX_IO_SELECT_MASK) << shift); rtems_interrupt_flash(level); LPC24XX_PINMODE [select] &= ~(LPC24XX_IO_SELECT_MASK << shift); rtems_interrupt_enable(level); }
rtems_task High_task( rtems_task_argument argument ) { rtems_interrupt_level level; _Thread_Dispatch_disable(); benchmark_timer_initialize(); rtems_interrupt_local_disable( level ); isr_disable_time = benchmark_timer_read(); benchmark_timer_initialize(); #if defined(RTEMS_SMP) rtems_interrupt_local_enable( level ); rtems_interrupt_local_disable( level ); #else rtems_interrupt_flash( level ); #endif isr_flash_time = benchmark_timer_read(); benchmark_timer_initialize(); rtems_interrupt_local_enable( level ); isr_enable_time = benchmark_timer_read(); _Thread_Dispatch_enable( _Per_CPU_Get() ); benchmark_timer_initialize(); _Thread_Dispatch_disable(); thread_disable_dispatch_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Dispatch_enable( _Per_CPU_Get() ); thread_enable_dispatch_time = benchmark_timer_read(); benchmark_timer_initialize(); _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED ); thread_set_state_time = benchmark_timer_read(); set_thread_dispatch_necessary( true ); benchmark_timer_initialize(); _Thread_Dispatch(); /* dispatches Middle_task */ }
void test_interrupt_inline(void) { rtems_interrupt_level level; rtems_mode level_mode_body; rtems_mode level_mode_macro; bool in_isr; puts( "interrupt is in progress (use body)" ); in_isr = rtems_interrupt_is_in_progress(); if ( in_isr ) { puts( "interrupt reported to be is in progress (body)" ); rtems_test_exit( 0 ); } puts( "interrupt disable (use inline)" ); _Thread_Disable_dispatch(); rtems_interrupt_disable( level ); _Thread_Enable_dispatch(); puts( "interrupt flash (use inline)" ); _Thread_Disable_dispatch(); rtems_interrupt_flash( level ); _Thread_Enable_dispatch(); puts( "interrupt enable (use inline)" ); _Thread_Disable_dispatch(); rtems_interrupt_enable( level ); _Thread_Enable_dispatch(); puts( "interrupt level mode (use inline)" ); level_mode_body = rtems_interrupt_level_body( level ); level_mode_macro = RTEMS_INTERRUPT_LEVEL(level); if ( level_mode_macro == level_mode_body ) { puts( "test case working.." ); } }
rtems_task Init( rtems_task_argument argument ) { rtems_time_of_day time; rtems_status_code status; rtems_interrupt_level level; rtems_mode level_mode_body; rtems_mode level_mode_macro; bool in_isr; rtems_id timer; int i; puts( "\n\n*** TEST 37 ***" ); test_isr_level(); test_isr_locks(); test_interrupt_locks(); build_time( &time, 12, 31, 1988, 9, 0, 0, 0 ); status = rtems_clock_set( &time ); directive_failed( status, "rtems_clock_set" ); /* * Timer used in multiple ways */ status = rtems_timer_create( 1, &timer ); directive_failed( status, "rtems_timer_create" ); /* * Test clock tick from outside ISR */ status = rtems_clock_tick(); directive_failed( status, "rtems_clock_tick" ); puts( "clock_tick from task level" ); /* * Now do a dispatch directly out of a clock tick that is * called from a task. We need to create a task that will * block so we have one to unblock. Then we schedule a TSR * to run in the clock tick but it has to be careful to * make sure it is not called from an ISR and that the * dispatching critical section is managed properly to * make the dispatch happen. */ blocked_task_status = -1; status = rtems_task_create( rtems_build_name( 'T', 'A', '1', ' ' ), 1, RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &blocked_task_id ); directive_failed( status, "rtems_task_create" ); status = rtems_task_start( blocked_task_id, blocked_task, 0 ); directive_failed( status, "rtems_task_start" ); status = rtems_task_wake_after( 10 ); directive_failed( status, "rtems_task_wake_after" ); status = rtems_timer_fire_after( timer, 1, test_unblock_task, NULL ); directive_failed( status, "timer_fire_after failed" ); /* we expect to be preempted from this call */ for ( i=0 ; i<100 && blocked_task_status != 3 ; i++ ) { status = rtems_clock_tick(); directive_failed( status, "rtems_clock_tick" ); } switch ( blocked_task_status ) { case -1: puts( "clock_tick with task preempt -- task blocked, timer did not fire" ); rtems_test_exit(0); break; case 1: puts( "clock_tick with task preempt -- timer fired case 1" ); rtems_test_exit(0); break; case 2: puts( "clock_tick with task preempt -- timer fired case 2" ); rtems_test_exit(0); break; case 3: puts( "clock_tick from task level with preempt -- OK" ); break; } /* * Test interrupt inline versions */ test_interrupt_inline(); /* * Test interrupt bodies */ puts( "interrupt is in progress (use body)" ); in_isr = rtems_interrupt_is_in_progress(); if ( in_isr ) { puts( "interrupt reported to be is in progress (body)" ); rtems_test_exit( 0 ); } puts( "interrupt disable (use body)" ); _Thread_Disable_dispatch(); level = rtems_interrupt_disable(); _Thread_Enable_dispatch(); puts( "interrupt disable (use body)" ); _Thread_Disable_dispatch(); level = rtems_interrupt_disable(); _Thread_Enable_dispatch(); puts( "interrupt flash (use body)" ); _Thread_Disable_dispatch(); rtems_interrupt_flash( level ); _Thread_Enable_dispatch(); puts( "interrupt enable (use body)" ); _Thread_Disable_dispatch(); rtems_interrupt_enable( level ); _Thread_Enable_dispatch(); puts( "interrupt level mode (use body)" ); level_mode_body = rtems_interrupt_level_body( level ); level_mode_macro = RTEMS_INTERRUPT_LEVEL(level); if ( level_mode_macro == level_mode_body ) { puts("test seems to work"); } /* * Test ISR in progress from actual ISR */ isr_in_progress_body = -1; isr_in_progress_inline = -1; status = rtems_timer_fire_after( timer, 10, test_isr_in_progress, NULL ); directive_failed( status, "timer_fire_after failed" ); status = rtems_task_wake_after( 100 ); directive_failed( status, "wake_after failed" ); check_isr_worked( "inline", isr_in_progress_body ); check_isr_worked( "body", isr_in_progress_body ); puts( "*** END OF TEST 37 ***" ); rtems_test_exit( 0 ); }
rtems_status_code lpc24xx_gpio_config( unsigned index, lpc24xx_gpio_settings settings ) { if (index <= LPC24XX_IO_INDEX_MAX) { rtems_interrupt_level level; uint32_t port = LPC24XX_IO_PORT(index); uint32_t port_bit = LPC24XX_IO_PORT_BIT(index); uint32_t output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U; uint32_t resistor = settings & 0x3U; #ifdef ARM_MULTILIB_ARCH_V4 uint32_t select = LPC24XX_PIN_SELECT(index); uint32_t shift = LPC24XX_PIN_SELECT_SHIFT(index); /* Get resistor flags */ switch (resistor) { case LPC24XX_GPIO_RESISTOR_PULL_UP: resistor = 0x0U; break; case LPC24XX_GPIO_RESISTOR_NONE: resistor = 0x2U; break; case LPC24XX_GPIO_RESISTOR_PULL_DOWN: resistor = 0x3U; break; default: return RTEMS_INVALID_NUMBER; } #else uint32_t iocon_mask = IOCON_HYS | IOCON_INV | IOCON_SLEW | IOCON_OD | IOCON_FILTER; uint32_t iocon = (settings & iocon_mask) | IOCON_ADMODE; uint32_t iocon_invalid = settings & ~(iocon_mask | LPC24XX_GPIO_OUTPUT); /* Get resistor flags */ switch (resistor) { case LPC24XX_GPIO_RESISTOR_NONE: resistor = IOCON_MODE(0); break; case LPC24XX_GPIO_RESISTOR_PULL_DOWN: resistor = IOCON_MODE(1); break; case LPC24XX_GPIO_RESISTOR_PULL_UP: resistor = IOCON_MODE(2); break; case LPC17XX_GPIO_HYSTERESIS: resistor = IOCON_MODE(3); break; } iocon |= resistor; if (iocon_invalid != 0) { return RTEMS_INVALID_NUMBER; } if (output && (settings & LPC17XX_GPIO_INPUT_INVERT) != 0) { return RTEMS_INVALID_NUMBER; } if ((settings & LPC17XX_GPIO_INPUT_FILTER) == 0) { iocon |= IOCON_FILTER; } else { iocon &= ~IOCON_FILTER; } #endif rtems_interrupt_disable(level); #ifdef ARM_MULTILIB_ARCH_V4 /* Resistor */ LPC24XX_PINMODE [select] = (LPC24XX_PINMODE [select] & ~(LPC24XX_PIN_SELECT_MASK << shift)) | ((resistor & LPC24XX_PIN_SELECT_MASK) << shift); #else LPC17XX_IOCON [index] = iocon; #endif rtems_interrupt_flash(level); /* Input or output */ LPC24XX_FIO [port].dir = (LPC24XX_FIO [port].dir & ~(1U << port_bit)) | (output << port_bit); rtems_interrupt_enable(level); } else { return RTEMS_INVALID_ID; } return RTEMS_SUCCESSFUL; }