pgh@stl.stc.co.uk (P.G.Hamer) (04/22/91)
I am a novice OS/9 user on a 68020 box, no 68K assembler experience. So far I have been able to stay in C and everything is going well. BUT we need to run a small C routine in response to externally generated interrupt every 10mS. From the manual it looks like we have to write a (minimal) device handler to do this. [Polling is definitely out, there is a fair bit of concurrency.] Does anybody have code for a small device driver we could hack? Or other advice to offer. Regards, Peter
ps3@ph3hp840.physik.uni-stuttgart.de (ps-Gruppe) (05/07/91)
In article <4310@stl.stc.co.uk> "P.G.Hamer" <pgh@stl.stc.co.uk> writes: >... >BUT we need to run a small C routine in response to externally generated >interrupt every 10mS. > >From the manual it looks like we have to write a (minimal) device handler >to do this. [Polling is definitely out, there is a fair bit of concurrency.] > >Does anybody have code for a small device driver we could hack? Or other >advice to offer. To handle interrupts you must use the os9-function F$IRQ. With this function call you can put an assembler-routine into the interrupt-daisy-chain. The parameter a3 (port address) is not used by OS9, it is just given to your interrupt-routine. So you may use it for any purpose. Refer to your technical OS9-Manual for further information about F$IRQ or ask me. No problem so far - but the F$IRQ-Call is a privileged system state servivce request. This means, the caller programm must run in supervisor state. But this is a bad solution, because : - system state routines are not timesliced. So you stop your Multitasking. - There's no memory protection - If your process stops irregular the whole system may crash So you have to use an other solution: You can either write a device driver or a traphandler, which is running in supervisor state. If you prefer a device driver, you may communicate with this device by read, write, setstt and/or getstt. If you prefer a traphandler, I can give you a complete solution: You just have to write a traphandler with the 'SupStat'-bit set in the module header. This handler is allowed to do the F$IRQ-call. It has two functions: One for installing an interrupt service routine and one for removing it. All your program has to do, is loading the traphandler into memory (F$TLink). Then you can use the two functions provided by the traphandler by putting the parameters to the registers and calling the handler with "trap #Trapnumber", where Trapnumber is the number you used in the F$TLink-call. The traphandler is included at the end of the mail. It is quite short and easy to understand. I've left my comments in german, because I'm short in time. I hope you understand the comments. There's a good explanation in the technical Manual. But there's 1 important thing missing: In the supervisor-mode the status-register is saved on the stack (which is not in normal-mode). So you have to leave the traphandler with "RTE" instead of "RTS". We are using this traphandler with Modula 2. If you are interested, I can send the interface Module between Modula and the Traphandler. >>>>>>>>> traphandler for installing interupt service routines <<<<<<<<<<< nam IRQ Handler ttl Traphandler fuer IRQ ***************************************************************************** * Dieser Traphandler dient zum sauberen Einhaengen von Interrupts. * * * * * * Funktion 1 : * * ============ * * * * Zweck : Haengt eine Interruptroutine ins System ein * * Aufruf : Trap #Nummer,1 * * Eingabe : A0.L : Zeiger auf Interruptroutine * * A3.L : Portadresse (Platz fuer Variablen) * * D0.B : Vektornummer des Interrupts * * D1.B : Prioritaet des Interrupts; 0 = alleiniger Besitz * * Ausgabe : D1.W : 0, wenn kein Fehler auftrat; sonst Fehlernummer * * * * * * Funktion 2 : * * ============ * * * * Zweck : Entfernt die Interruptroutine wieder aus dem System * * Aufruf : Trap #Nummer,2 * * Eingabe : D0.B : Vektornummer des Interrupts * * Ausgabe : D1.W : 0, wenn kein Fehler auftrat; sonst Fehlernummer * * * * * * History: * * 05.09.89 to.3 erste offizielle Version * * 30.05.90 to.3 Fehler, dass a2 zerstoert wurde, behoben. * ***************************************************************************** use <oskdefs.d> Type set (TrapLib<<8)+Objct Traphandler, Maschinensprache Revs set (SupStat<<8)+1 Supervisormodus, Revision Edition set 0 Stack set 8 zusaetzliche Stackgroesse psect IRQHandler,Type,Revs,Edition,Stack,TrapEnt dc.l TrapInit dc.l TrapTerm align TrapInit movem.l (a7)+,a6-a7 keine Initialisierung noetig rte TrapEnt movem.l a0/a2,-(a7) Rette verwendete Register move.w $0c(a7),d3 Offset = 4 + Anzahl der gesavten Reg. subq.b #$01,d3 beq.s Funktion1 subq.b #$01,d3 beq.s Funktion2 * Falsche Funktionsnummer moveq #$1,d1 Fehlernummer bra.s Ende * Funktion 1 wurde aufgerufen Funktion1 move.l #$00,a2 global static pointer; nicht benutzt bra.s weiter * Funktion 2 wurde aufgerufen Funktion2 move.l #$00,a0 delete from IRQ-Table move.l #$00,a2 weiter os9 F$IRQ fuehre Funktion aus bcs.s Ende Es trat Fehler auf moveq #$00,d1 kein Fehler Ende movem.l (a7)+,a0/a2/a6-a7 rte TrapTerm move.w #1<<8+199,d1 nie aufgerufen, fuer zukuenftige os9 F$Exit Versionen Error 001:199 ends >>>>>>>>>>>>>>>>> end of listing <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<