Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2011-03

Interrupt vector table generation

12 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jeppe Johansen

As I wrote a while back, I would like to make it easier to handle interrupts when using fpc for embedded work
The current solution is to use procedure variables with indirect jumps in inline assembler. While that works okay it takes up a lot of space on devices with lots of interrupts, and introduces unnecessary interrupt latencies

An idea would be to use weak linking, and while it's possible in external assembler, a nicer solution would be to handle it in procedure directives. That would mean addition of some functionality that is generally unportable and ambiguous across platforms. So I've moved away from this idea for now

A better idea, I think, is to use the old interrupt procedure directive. For some embedded platforms simply allow also specifying a interrupt vector/index after the interrupt keyword. Ex:

procedure USARTRxInterrupt; interrupt 10;
begin
    // Handler code
end;

And from that automatically generate an interrupt vector table in the compiler when compiling a program. Those tables of course look different for each targetted architecture, but usually they are either tables of branch instructions or addresses. For embedded work you'll specify the controllertype anyway, and that way know how large the table is, and what kind of vector to use

Further, a future benefit of using the interrupt keyword could be generation of procedure exit code. Some platforms need a special "return from exception/interrupt" instructions at the end of interrupt handlers

I've made an implementation of this here:
http://j-software.dk/interrupttable.patch.txt

Regards,
Jeppe

Reply by email

waldo kitty
to Jeppe Johansen
Jeppe Johansen wrote 8 lines
A better idea, I think, is to use the old interrupt procedure directive. For some embedded platforms simply allow also specifying a interrupt vector/index after the interrupt keyword. Ex: procedure USARTRxInterrupt; interrupt 10; begin // Handler code end;

is that "10" meaning interrupt ten in decimal or sixteen in hex or two in binary? yeah, maybe a silly question but still one that needs to be asked and clarified so there's no confusion in documentation ;)

i've several older TP6/7 programs that install interrupt handlers for various reasons... this functionality is highly desired in them for their DOS compiled versions (ie: explicitly giving up time slices) but i've not yet any idea if it is necessary on other platforms... at least one, the timer interrupt, is very highly desired for certain timing scenarios... especially those that speed up the computers timer chip and the installed handler adjusts things so as to maintain the proper clock timer kicking of 18.2 times/second...

Reply by email

Ralf A. Quint
to waldo kitty
waldo kitty wrote 13 lines
On 3/6/2011 16:46, Jeppe Johansen wrote: >A better idea, I think, is to use the old interrupt procedure directive. For >some embedded platforms simply allow also specifying a interrupt vector/index >after the interrupt keyword. Ex: > >procedure USARTRxInterrupt; interrupt 10; >begin >// Handler code >end; is that "10" meaning interrupt ten in decimal or sixteen in hex or two in binary? yeah, maybe a silly question but still one that needs to be asked and clarified so there's no confusion in documentation ;)

Sorry Mark, but it is absolutely clear that it is to be decimal, after all it doesn't have any base modifier, like

$10 for a hexadecimal number or
&10 for a octal number or
%10 for a binary number

as defined in the FreePascal docs
(http://www.freepascal.org/docs-html/ref/refse6.html)

Ralf ;-)

Reply by email

Mark Morgan Lloyd
to Jeppe Johansen: As I wrote a while back, I would like to make it easier to handle interrupts when using…
Jeppe Johansen wrote 32 lines
As I wrote a while back, I would like to make it easier to handle interrupts when using fpc for embedded work The current solution is to use procedure variables with indirect jumps in inline assembler. While that works okay it takes up a lot of space on devices with lots of interrupts, and introduces unnecessary interrupt latencies An idea would be to use weak linking, and while it's possible in external assembler, a nicer solution would be to handle it in procedure directives. That would mean addition of some functionality that is generally unportable and ambiguous across platforms. So I've moved away from this idea for now A better idea, I think, is to use the old interrupt procedure directive. For some embedded platforms simply allow also specifying a interrupt vector/index after the interrupt keyword. Ex: procedure USARTRxInterrupt; interrupt 10; begin // Handler code end; And from that automatically generate an interrupt vector table in the compiler when compiling a program. Those tables of course look different for each targetted architecture, but usually they are either tables of branch instructions or addresses. For embedded work you'll specify the controllertype anyway, and that way know how large the table is, and what kind of vector to use Further, a future benefit of using the interrupt keyword could be generation of procedure exit code. Some platforms need a special "return from exception/interrupt" instructions at the end of interrupt handlers

I'm not sure that this belongs in a core language, because (a) the whole concept of interrupts is non-portable, (b) the precise point at which the vector (or equivalent) is installed is determined by the logic of the program, and (c) it says nothing about disabling interrupts while the vector is updated or what to do with the interrupt controller afterwards.

Being able to mark a procedure as preserving all registers is highly useful, and saves a lot of messing with assembler. What I've done in the past (on x86 protected mode) was to build the final binary as an NE-format .exe with entry points exported by name, then use a final builder/binder stage (loosely patterned after Intel's) that set up all vectors etc.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Jeppe Johansen
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 37 lines
Jeppe Johansen wrote: > As I wrote a while back, I would like to make it easier to handle > interrupts when using fpc for embedded work > The current solution is to use procedure variables with indirect > jumps in inline assembler. While that works okay it takes up a lot of > space on devices with lots of interrupts, and introduces unnecessary > interrupt latencies > > An idea would be to use weak linking, and while it's possible in > external assembler, a nicer solution would be to handle it in > procedure directives. That would mean addition of some functionality > that is generally unportable and ambiguous across platforms. So I've > moved away from this idea for now > > A better idea, I think, is to use the old interrupt procedure > directive. For some embedded platforms simply allow also specifying a > interrupt vector/index after the interrupt keyword. Ex: > > procedure USARTRxInterrupt; interrupt 10; > begin > // Handler code > end; > > And from that automatically generate an interrupt vector table in the > compiler when compiling a program. Those tables of course look > different for each targetted architecture, but usually they are > either tables of branch instructions or addresses. For embedded work > you'll specify the controllertype anyway, and that way know how large > the table is, and what kind of vector to use > > Further, a future benefit of using the interrupt keyword could be > generation of procedure exit code. Some platforms need a special > "return from exception/interrupt" instructions at the end of > interrupt handlers I'm not sure that this belongs in a core language, because (a) the whole concept of interrupts is non-portable

You could say the same about perfectly valid pascal code writing and reading from memory mapped hardware registers

On those platforms this change is aimed for(ARM, AVR, AVR32, etc), the interrupt vector table is usually mapped into ROM at address 0. There might not be a way to change it, so the values in it are constant. All interrupt vectors have a specific purpose

It's not aimed for complex architectures such as x86 where interrupt vectors aren't constant

Reply by email

Marco van de Voort
to Jeppe Johansen: As I wrote a while back, I would like to make it easier to handle interrupts when using…

In our previous episode, Jeppe Johansen said:

Show quoted text 8 lines
A better idea, I think, is to use the old interrupt procedure directive. For some embedded platforms simply allow also specifying a interrupt vector/index after the interrupt keyword. Ex: procedure USARTRxInterrupt; interrupt 10; begin // Handler code end;

I do know how GCC does it with the embedded target (dspic) that I use at work:

the name of the interrupt routine is hardwired to the table entry. This allows to get rid of the number constants (which are maintained centrally) all together.

It also allows to keep code portable between different versions that might have a different interrupt table layout (since the CPU dependant mapping from names to numbers would be different).

Reply by email

Jeppe Johansen
to Marco van de Voort
Marco van de Voort wrote 19 lines
In our previous episode, Jeppe Johansen said: > A better idea, I think, is to use the old interrupt procedure directive. > For some embedded platforms simply allow also specifying a interrupt > vector/index after the interrupt keyword. Ex: > > procedure USARTRxInterrupt; interrupt 10; > begin > // Handler code > end; I do know how GCC does it with the embedded target (dspic) that I use at work: the name of the interrupt routine is hardwired to the table entry. This allows to get rid of the number constants (which are maintained centrally) all together. It also allows to keep code portable between different versions that might have a different interrupt table layout (since the CPU dependant mapping from names to numbers would be different).

Wouldn't this be the same as having numbered constants? That is allowed in the implementation

You could have somthing like this, and control it with the controllertype unit

unit stm32f103re;
interface
const
  UsartRXInt = 10;
implementation
end.
...
unit stm32f103ct;
interface
const
  UsartRXInt = 32;
implementation
end.
...
program myprogram;
procedure MyRXInterrupt; interrupt UsartRXInt;
begin
end;
begin
end.

Reply by email

Marco van de Voort
to Jeppe Johansen

In our previous episode, Jeppe Johansen said:

Show quoted text 9 lines
> the name of the interrupt routine is hardwired to the table entry. This > allows to get rid of the number constants (which are maintained centrally) > all together. > > It also allows to keep code portable between different versions that might > have a different interrupt table layout (since the CPU dependant mapping > from names to numbers would be different). Wouldn't this be the same as having numbered constants? That is allowed in the implementation

That is possible yes. But this is compiler enforced, in the sense if the symbol is not in the linker file for the current target, you'll get an linking error. While as with numbers and numeric constants, you can enter any number.

But you are right that allowing numbered constants takes the main problem (different device versions different interrupt table numbers) away.

Reply by email

Florian Klämpfl
to Jeppe Johansen: As I wrote a while back, I would like to make it easier to handle interrupts when using…
Jeppe Johansen wrote
As I wrote a while back, I would like to make it easier to handle interrupts when using fpc for embedded work

After reading the related discussion, I think the approach is fine.

Show quoted text 6 lines
Further, a future benefit of using the interrupt keyword could be generation of procedure exit code. Some platforms need a special "return from exception/interrupt" instructions at the end of interrupt handlers I've made an implementation of this here: http://j-software.dk/interrupttable.patch.txt

I think when searching for interrupt handlers, also the procdefs should be processed.

Reply by email

Jonas Maebe
to Florian Klämpfl
Florian Klämpfl wrote 10 lines
Am 06.03.2011 22:46, schrieb Jeppe Johansen: > Further, a future benefit of using the interrupt keyword could be > generation of procedure exit code. Some platforms need a special "return > from exception/interrupt" instructions at the end of interrupt handlers > > I've made an implementation of this here: > http://j-software.dk/interrupttable.patch.txt I think when searching for interrupt handlers, also the procdefs should be processed.

It would be nice if it could be done with less ifdefs all over the place though.

Jonas

Reply by email

Florian Klämpfl
to Jonas Maebe
Jonas Maebe wrote 15 lines
On 13 Mar 2011, at 16:31, Florian Klämpfl wrote: > Am 06.03.2011 22:46, schrieb Jeppe Johansen: >> Further, a future benefit of using the interrupt keyword could be >> generation of procedure exit code. Some platforms need a special "return >> from exception/interrupt" instructions at the end of interrupt handlers >> >> I've made an implementation of this here: >> http://j-software.dk/interrupttable.patch.txt > > I think when searching for interrupt handlers, also the procdefs should > be processed. It would be nice if it could be done with less ifdefs all over the place though.

Yes, I planned to remove them and depend on systems_interrupt_table as much as possible.

Reply by email

Jeppe Johansen
to Florian Klämpfl
Florian Klämpfl wrote 15 lines
Am 13.03.2011 16:34, schrieb Jonas Maebe: > On 13 Mar 2011, at 16:31, Florian Klämpfl wrote: > >> Am 06.03.2011 22:46, schrieb Jeppe Johansen: >>> Further, a future benefit of using the interrupt keyword could be >>> generation of procedure exit code. Some platforms need a special "return >>> from exception/interrupt" instructions at the end of interrupt handlers >>> >>> I've made an implementation of this here: >>> http://j-software.dk/interrupttable.patch.txt >> I think when searching for interrupt handlers, also the procdefs should >> be processed. > It would be nice if it could be done with less ifdefs all over the place though. Yes, I planned to remove them and depend on systems_interrupt_table as much as possible.

An update here: http://j-software.dk/interrupttable3.patch.txt

I removed a good deal of the ifdefs
Added a new calling convention pocall_interrupt - which is only set if there's an interrupt vector specified
Fixed the procdef searching

Any opinions? :)

Reply by email