OS_Claim (0x1F)
adrian (2547) 18 posts |
I’m trying to program a function in RISC OS which executes whenever it gets an interrupt (0×02). The problem is that I don’t know how exactly OS_Claim works. Do I have to modify the CPSR as if I was working with a handler, or does it just jump from the IRQ handler to my code and returns to the IRQ handler? I’d also like to show a message via SWI and I dont know if that will be possible from this function. Thanks. |
Colin (478) 2433 posts |
Have you read the interrupt handling section of PRM 1? Use of the IRQV has been deprecated for a long time and in any case it only receives unknown IRQ’s. Unknown IRQ’s are disabled by default. |
adrian (2547) 18 posts |
Hi Colin, .global _start @ Enable OS_Claim for Interrupts @ Enable Enable_IRQ_1 @ Load value to Compare Register @ Infinite Loop to check Timer’s Behavior. MOV R8, #0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ disable interrupts adr r0, text text: .asciz “Handler\n” @ Remove interrupt from Status Register @ Re-Load Compare Register @ enable interrupts ldmfd r13!, {r0-r3, r12, lr} |
Rick Murray (539) 13850 posts |
You could dump the PSR to someplace and examine the flags to see what the processor mode is? Or, better yet, look at the PRM. p1-77 states that IrqV is always executed in IRQ mode. As Colin said, using OS_Claim/IrqV is deprecated. It was used in Arthur (back in, what was it, 1986?) but it is no longer to be used within RISC OS. So you should not be using it. Look at OS_ClaimDeviceVector (PRM 1-123). Better still, read the chapter on dealing with interrupts.
Is it safe to call OS_Write0 in this way? Data is written to the usual output streams, and from IRQ code may not necessarily be re-entrant. Take a look at DADebug. Oh, and you should always be calling X-version SWIs in IRQ code.
It’s my own personal style, but I’d be using defined constants there. After a bit of digging, I now know that 0×20003000 is the Pi’s BCM2835 System Timer; loading doubleword from +4 is the 64 bit value of the system timer counter. Writing to +&10 is writing to the System Timer Compare 1. Writing CLO (R0) to to C1 will schedule an interrupt. You already know this, I’m just working through the code. Something like:
One thing I did notice . . . are those addresses correct? They are indeed the physical addresses of the devices, however are these maintained through the MMU and the logical addressing known within the RISC OS realm? |
adrian (2547) 18 posts |
Hi Rick, Thank you very much for your answer. To write that code I’ve reading this link http://xinu.mscs.mu.edu/BCM2835_System_Timer and the BCM2835. What do you mean with this sentence: “Oh, and you should always be calling X-version SWIs in IRQ code” Can I use SWIs in the IRQ Handler? |
patric aristide (434) 418 posts |
You can find an online version on this site under “Documents” |
Rick Murray (539) 13850 posts |
!!!! Please read https://www.riscosopen.org/wiki/documentation/show/IrqV and note the bit that says “It must not be called with OS_CallAVector.”
What do you mean by Monitor Mode?
Please do not think I am being impolite . . . but you are using a deprecated function, calling it incorrectly, and you do not seem to be aware of the two different ways in which SWIs can be called (what the X bit is for; XOS_Write0 vs OS_Write0). |
Steve Pampling (1551) 8172 posts |
curious: cspr? |
adrian (2547) 18 posts |
CPSR sorry. |
adrian (2547) 18 posts |
Hi all! My idea is to first program using HAL and finally, manually. I’ve followed all the steps that are specified in the webpage, and I’ve seen that some of the HALs work but other ones (I think) are not implemented (HAL_TimerIRQStatus). .global _start .align 2 @ Enable interrupts @ ClaimDeviceVector @ IRQEnable @ TimerSetPeriod @ Infinite loop mov r8, #0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ STMFD r13!, {r0-r3, r12, r14} @ IRQStatus @ If IRQStatus returns 0, Timer was not the cause of the IRQ. @ TimerIRQClear @ IRQClear @ Counter+1 out: I imagine I will have to change to Supervisor mode to use SWIs but not sure: |
Rick Murray (539) 13850 posts |
Does your assembler not allow you to use definitions so these (and the “magic values”) can be properly named? For using the timers – perhaps the HALTimer module would be simpler → http://homepage.ntlworld.com/rik.griffin/haltimer.html |
adrian (2547) 18 posts |
Hi Rick |
Rick Murray (539) 13850 posts |
The first thing to do, then, is to decrypt the code.
You are running this as a module or single-tasking, aren’t you? TaskWindows are bad…
In this case, if it was me, I’d drop in a call to transmit a ‘.’ on the serial port and then watch (on another computer connected to the serial) to see if anything is received. You could also spit out ABCD (etc), a letter for each state that the code is passing through to see how much (if anything) actually gets executed. |
adrian (2547) 18 posts |
Hi! |
Rick Murray (539) 13850 posts |
https://www.riscosopen.org/forum/forums/5/topics/2207?page=2#posts-27672 |
Dominic Plunkett (2553) 2 posts |
Some questions: Why .align 2 ? Which memory space is counter defined in? Do you know the purpose of stacking registers on the way into the IRQ? What about R8 R9? |
adrian (2547) 18 posts |
Hey Dominic, |
Dominic Plunkett (2553) 2 posts |
Depends on how you are doing it. Most likely they are in different memory spaces. If you can provide detailed answers you may understand what is wrong. In you code snippet you don’t provide enough info for us to work it out. Eg how you start your code. |
Martin Avison (27) 1494 posts |
@Dominic: Can you define what you mean by ‘memory space’ please? |
Rick Murray (539) 13850 posts |
Dominic:
It’s a
Martin – I am wondering if he isn’t asking what I asked a while back – are we working with logical or physical addresses here?
Evidently not. Adrian:
Could you please link to the place where you saw this code, and a (complete) copy of what you are trying to get working? Looking at your code, it is not clear how or when it runs. Module? Application? Multitasking? I am going to go out on a limb and wonder if you are not running this in a TaskWindow (based upon the infinite loop – nobody would do such a thing if they also wanted to check to see what effect the code is having). If this is the case, you do realise that any time your task is paged out (which will be, statistically, the majority of the time), your pointers given to OS_ClaimDeviceVector will point at random parts of other applications. If you want to do it like this, you’ll want to claim a little bit of RMA and place your interrupt handler in there (as a stop-gap until you write a proper module). Also, investigate the HALTimer module – because due to hardware differences, what works on a Pi may not work on a Beagle, or Panda, or… |
adrian (2547) 18 posts |
Hi! Well, I use gcc downloaded (from the PackMan), and using the Risc Os’ ‘cmd’ I compile them using ‘as’ and link them with ‘ld’. Main: .align 2 @ Enable interrupts @ ClaimDeviceVector @ IRQEnable @ TimerSetPeriod @ Infinite loop @ If it’s different from 0, it has entered the handler @ If it’s 0, just do the loop again mov r8, #0 Handler: .timerhandler ; HAL_TimerIRQClear ; HAL_IRQClear ; Disable Interrupts in general ; enumerate_list ?? ; Increment Counter ; Enable Interrupts in general ; Reload registers Do I have to change to Supervisor mode to call SWI? |
Rick Murray (539) 13850 posts |
Hi, thanks. If I have time I’ll convert that to objasm format and see what it does. Next question – how are you running the program? By the way: You are still trashing R8 and R9. At this stage of development, be paranoid and stack every register you touch. It’s the safest approach. Also keep your comments up to date with the code : |
Steve Pampling (1551) 8172 posts |
Interesting exercise. |
Rick Murray (539) 13850 posts |
Judging by the ‘@’ comments and the weird syntax, I think it might be “gas” or whatever the gcc assembler is called. |
Steve Pampling (1551) 8172 posts |
ah, Ben’s “favourite” (not) |