This is the mail archive of the crossgcc@cygnus.com mailing list for the crossgcc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
> The fix for this problem is to have a counter that increments on > disable, and decrements on enable. The enable routine will only > actually enable interrupts if the value of the counter is zero. We > must make sure that the increment and decrement operations are also > atomic; therefore, we must actually disable interrupts before the > counter is incremented in assembler_routine_to_disable_interrupts(), > and decrement before we disable interrupts in > assembler_routine_to_enable_interrupts() (we realize, of course, that > it is an error to call assembler_routine_to_enable_interrupts() when > interrupts are not disabled!), and only actually enable interrupts in > assembler_routine_to_enable_interrupts() is the counter goes to zero. > The counter must be global in C, but should probably be class static > in C++. In our system, we have a target-dependent header file that defines four macros: - enableInts() unconditionally enables interrupts - disableInts() unconditionally disables interrupts - inhibitInts() saves the CPU's interrupt mask bit in an auto variable, then invokes disableInts() - restoreInts() sets the CPU's interrupt mask bit from the auto variable written by inhibitInts(). For example, with the Hitachi Super-H processor, we use #define enableInts() asm("stc sr,r3; and %0,r3; ldc r3,sr" : : "r" (__int_enable_mask__) : "r3" ); #define disableInts() asm("stc sr,r3; and %0,r3; or %1,r3; ldc r3,sr" : : "r" (0xFFFFFF0F), "r" (__int_disable_mask__) : "r3" ); #define inhibitInts() long sr; asm("stc sr,r3; mov.l r3,%0" : "=m" (sr) : : "r3"); disableInts(); #define restoreInts() asm("mov.l %0,r3; ldc r3,sr" : : "m" (sr) : "r3"); A typical entry point into an i/o driver then becomes: scibuf::put(char c) { inhibitInts(); // fiddle with i/o, and so forth restoreInts(); } This method isn't perfect, but it does allow inhibiting interrupts deep in a library without interfering with the application's interrupt enable/disable status. Also, since we have such a file for each processor, interrupt mask handling becomes portable. Regards, David Querbach Real-Time Systems Inc. _______________________________________________ New CrossGCC FAQ: http://www.objsw.com/CrossGCC _______________________________________________ To remove yourself from the crossgcc list, send mail to crossgcc-request@cygnus.com with the text 'unsubscribe' (without the quotes) in the body of the message.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |