How to guarantee that mainline code doesn't affect ISR

This forum handles questions and discussions concerning Microchip’s 8-bit compilers, assemblers, linkers and related tools.

How to guarantee that mainline code doesn't affect ISR

Postby AaronD » Thu Dec 18, 2014 9:15 pm

The PIC16F1454 has lots of banks and a little bit of COMMON, so variable placement makes a difference in code speed because of the bank switches or absence thereof.

I have an ISR that needs to be absolutely predictable in how long it takes from trigger to action, where action is one of many things that is determined by a state machine. (more than just the interrupt flags) So there's some conditional logic in between that needs to take exactly the same time regardless of what the main code is at revision <insert number here>.

Using the XC8 PRO compiler version 1.33, I'm not entirely comfortable that it will honor that. It tries to optimize everything holistically, including both the main code and the ISR, and it apparently makes some guesses towards a compromise between everything. Ideally, I want to put all of the variables that are used in the time-critical section of the ISR in COMMON so I don't need bank switches, but XC8 insists on putting some stack and other stuff in there first so that those variables don't fit. If I try to force them in anyway with a near qualifier (and a compiler option to require compliance), it fails with "can't find space..." If I reserve some COMMON space with a linker option, it will quietly honor that by displacing the stack into bank 0, but then the manual placement into the reserved COMMON space seems to generate bank switches, despite being COMMON.

I've asked MCP support about it, and after several weeks they finally said to convert all of my local variables into globals so that there's no stack, and then it should work. :roll:

I suppose I can live with the unnecessary bank switches - just tweak my tuning #defines to match - but is there a way to lock down the ISR's timing without them?
AaronD
 
Posts: 11
Joined: Thu Jul 31, 2014 8:44 pm
PIC experience: Experienced Hobbyist

Re: How to guarantee that mainline code doesn't affect ISR

Postby ric » Fri Dec 19, 2014 4:00 am

How many variables are you talking about?
It's pretty tight, as there are only 16 common bytes.
Why don't you force all your time critical variables into a single bank outside the common area?
(Banks switches are just a single instruction in PIC16F1xxx chips, so they are much less of a hindrance than they were in older parts too.)

Of course, the other option is to write the ISR yourself in assembler.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 611
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: How to guarantee that mainline code doesn't affect ISR

Postby AaronD » Fri Dec 19, 2014 5:09 pm

4 int's (8 bytes)
2 char's (2 bytes)
2 bits (1 byte)

Total 11 bytes, so it should fit, even with the the top 2 reserved for the compiler's non-negotiable use.



For now, that's what I did. I used the bank0 qualifier for the int's and char's and used near for the bits, and rechecked the tuning. There are a few bank switches that could go away if they were in common, but at least my equal-time if-else's and accurate running-timer capture weren't affected. (no latch register on this chip for a multi-byte timer, must read the entire timer twice to account for low-byte overflow between 8-bit reads)

I started to rewrite the ISR in assembly, like I did with the custom startup code, but I didn't get very far.

I think I'll keep the bank0 until I can make them all near. It did add a couple of instruction cycles, but I can account for that and it works.
AaronD
 
Posts: 11
Joined: Thu Jul 31, 2014 8:44 pm
PIC experience: Experienced Hobbyist


Return to MPLAB XC8

Who is online

Users browsing this forum: No registered users and 1 guest

cron