comp.lang.ada
 help / color / mirror / Atom feed
* How to emulate multiple exports
@ 2020-04-19 23:53 Jere
  2020-04-20  6:27 ` Egil H H
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Jere @ 2020-04-19 23:53 UTC (permalink / raw)


I am working in a space constrained environment (256k flash)
and I want to try and reuse the same exported function for
all of my unused interrupt handlers.

procedure Default;
procedure Default is
begin
   -- Do some complex stuff;
end Default;

Each unused interrupt handler looks for a 
unique/specific external symbol name.

However, the Export aspect/pragma can only
be specified once for Default.  I've tried 
a few different solutions but all of them
are not really desirable.

1.  Tried doing renames of Default.  Doesn't
work as the compiler is smart enough to 
figure this out and complain that I have
multiple exports.

2.  Using a generic Default function and 
instantiating a separate copy for each unused
handler.  This lets me give each an export and
the code inside Default, but a separate copy
of Default is created for each handler causing
a severe loss of ROM space.

3.  Calling Default inside a wrapper procedure.
This is better than option #2, but still takes up
a lot of lost ROM space (multiple copies of the
wrapper function essentially).

In C and C++ I was able to leverage the 
alias attribute to do this, but I have been
unsuccessful in getting the analogous 
Linker_Alias pragma to work (it just ignores
Default altogether).

So is there any way to do this?  Or am I just
stuck with all the code bloat?

I'm working with the GNAT 2019 CE cross compiler
for ARM on Windows 10.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-19 23:53 How to emulate multiple exports Jere
@ 2020-04-20  6:27 ` Egil H H
  2020-04-20 20:48   ` Jere
  2020-04-20  6:52 ` Jeffrey R. Carter
  2020-04-20  9:57 ` Simon Wright
  2 siblings, 1 reply; 9+ messages in thread
From: Egil H H @ 2020-04-20  6:27 UTC (permalink / raw)


On Monday, April 20, 2020 at 1:53:14 AM UTC+2, Jere wrote:
> I am working in a space constrained environment (256k flash)
> and I want to try and reuse the same exported function for
> all of my unused interrupt handlers.
> 
> However, the Export aspect/pragma can only
> be specified once for Default.  I've tried 
> a few different solutions but all of them
> are not really desirable.
> 
> So is there any way to do this?  Or am I just
> stuck with all the code bloat?
> 

4. Let the linker do it.
GNAT/GCC, at least, can duplicate symbols using the --defsym=alias=original command line parameter.

You can find a working example at https://gist.github.com/egilhh/ff0e4ffd8184e85dc4865194977f3185

(This worked on my linux laptop, at least)

-- 
~egilhh

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-19 23:53 How to emulate multiple exports Jere
  2020-04-20  6:27 ` Egil H H
@ 2020-04-20  6:52 ` Jeffrey R. Carter
  2020-04-20 20:51   ` Jere
  2020-04-20  9:57 ` Simon Wright
  2 siblings, 1 reply; 9+ messages in thread
From: Jeffrey R. Carter @ 2020-04-20  6:52 UTC (permalink / raw)


On 4/20/20 1:53 AM, Jere wrote:
> I am working in a space constrained environment (256k flash)
> and I want to try and reuse the same exported function for
> all of my unused interrupt handlers.
> 
> procedure Default;
> procedure Default is
> begin
>     -- Do some complex stuff;
> end Default;

Interrupt handling in Ada is defined in ARM C.3 
(http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-C-3.html). The standard 
way to use a single handler for multiple interrupts is to create the handler as 
a library-level parameterless protected procedure with aspect Interrupt_Handler 
set to True. At elaboration, calls to Ada.Interrupts.Attach_Handler attach this 
handler to multiple Interrupt_Ids. No Export is needed.

GNAT is supposed to support Annex C for all targets, so I would expect this to 
work with your setup. Perhaps there is something about your target that prevents 
this approach, but this would be my initial approach to the problem.

-- 
Jeff Carter
"He that hath no beard is less than a man."
Much Ado About Nothing
132

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-19 23:53 How to emulate multiple exports Jere
  2020-04-20  6:27 ` Egil H H
  2020-04-20  6:52 ` Jeffrey R. Carter
@ 2020-04-20  9:57 ` Simon Wright
  2020-04-20 20:57   ` Jere
  2 siblings, 1 reply; 9+ messages in thread
From: Simon Wright @ 2020-04-20  9:57 UTC (permalink / raw)


Jere <jhb.chat@gmail.com> writes:

> I am working in a space constrained environment (256k flash)
> and I want to try and reuse the same exported function for
> all of my unused interrupt handlers.

I don't know if it'll help, but I handle a similar problem in Cortex
GNAT RTS starting here:

https://github.com/simonjwright/cortex-gnat-rts/blob/master/stm32f4/adainclude/startup.adb#L147

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-20  6:27 ` Egil H H
@ 2020-04-20 20:48   ` Jere
  0 siblings, 0 replies; 9+ messages in thread
From: Jere @ 2020-04-20 20:48 UTC (permalink / raw)


On Monday, April 20, 2020 at 2:27:22 AM UTC-4, Egil H H wrote:
> On Monday, April 20, 2020 at 1:53:14 AM UTC+2, Jere wrote:
> > I am working in a space constrained environment (256k flash)
> > and I want to try and reuse the same exported function for
> > all of my unused interrupt handlers.
> > 
> > However, the Export aspect/pragma can only
> > be specified once for Default.  I've tried 
> > a few different solutions but all of them
> > are not really desirable.
> > 
> > So is there any way to do this?  Or am I just
> > stuck with all the code bloat?
> > 
> 
> 4. Let the linker do it.
> GNAT/GCC, at least, can duplicate symbols using the --defsym=alias=original command line parameter.
> 
> You can find a working example at https://gist.github.com/egilhh/ff0e4ffd8184e85dc4865194977f3185
> 
> (This worked on my linux laptop, at least)
> 
> -- 
> ~egilhh

Thanks!  I'll try it out.  One of the symbols is weak, so we'll 
have to see how that interacts.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-20  6:52 ` Jeffrey R. Carter
@ 2020-04-20 20:51   ` Jere
  0 siblings, 0 replies; 9+ messages in thread
From: Jere @ 2020-04-20 20:51 UTC (permalink / raw)


On Monday, April 20, 2020 at 2:52:55 AM UTC-4, Jeffrey R. Carter wrote:
> On 4/20/20 1:53 AM, Jere wrote:
> > I am working in a space constrained environment (256k flash)
> > and I want to try and reuse the same exported function for
> > all of my unused interrupt handlers.
> > 
> > procedure Default;
> > procedure Default is
> > begin
> >     -- Do some complex stuff;
> > end Default;
> 
> Interrupt handling in Ada is defined in ARM C.3 
> (http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-C-3.html). The standard 
> way to use a single handler for multiple interrupts is to create the handler as 
> a library-level parameterless protected procedure with aspect Interrupt_Handler 
> set to True. At elaboration, calls to Ada.Interrupts.Attach_Handler attach this 
> handler to multiple Interrupt_Ids. No Export is needed.
> 
> GNAT is supposed to support Annex C for all targets, so I would expect this to 
> work with your setup. Perhaps there is something about your target that prevents 
> this approach, but this would be my initial approach to the problem.
> 
> -- 
> Jeff Carter
> "He that hath no beard is less than a man."
> Much Ado About Nothing
> 132

Unfortunately, the runtime I am using doesn't support
protected types and the Ada standard doesn't really
provide any support for interrupts in that arena that
I can tell.  A lot of this has to be done
on a platform by platform basis, but I was hoping
that there was a way to at least leverage Export
as that was language defined.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-20  9:57 ` Simon Wright
@ 2020-04-20 20:57   ` Jere
  2020-04-21  7:58     ` Simon Wright
  0 siblings, 1 reply; 9+ messages in thread
From: Jere @ 2020-04-20 20:57 UTC (permalink / raw)


On Monday, April 20, 2020 at 5:57:06 AM UTC-4, Simon Wright wrote:
> Jere  writes:
> 
> > I am working in a space constrained environment (256k flash)
> > and I want to try and reuse the same exported function for
> > all of my unused interrupt handlers.
> 
> I don't know if it'll help, but I handle a similar problem in Cortex
> GNAT RTS starting here:
> 
> https://github.com/simonjwright/cortex-gnat-rts/blob/master/stm32f4/adainclude/startup.adb#L147

That looks closer to what I was trying.  Out of curiosity, how
does it handle someone wanting to later on assign a specific
peripheral ISR (like a timer for example)?  It looks like
all the remaining ISR slots use the same external 
symbol (IRQ_Handler)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-20 20:57   ` Jere
@ 2020-04-21  7:58     ` Simon Wright
  2020-04-24  1:36       ` Jere
  0 siblings, 1 reply; 9+ messages in thread
From: Simon Wright @ 2020-04-21  7:58 UTC (permalink / raw)


Jere <jhb.chat@gmail.com> writes:

> On Monday, April 20, 2020 at 5:57:06 AM UTC-4, Simon Wright wrote:
>> Jere  writes:
>> 
>> > I am working in a space constrained environment (256k flash)
>> > and I want to try and reuse the same exported function for
>> > all of my unused interrupt handlers.
>> 
>> I don't know if it'll help, but I handle a similar problem in Cortex
>> GNAT RTS starting here:
>> 
>> https://github.com/simonjwright/cortex-gnat-rts/blob/master/stm32f4/adainclude/startup.adb#L147
>
> That looks closer to what I was trying.  Out of curiosity, how
> does it handle someone wanting to later on assign a specific
> peripheral ISR (like a timer for example)?  It looks like
> all the remaining ISR slots use the same external 
> symbol (IRQ_Handler)

It doesn't. Of course it could (write to the interrupt vector & set the
hardware interrupt priority in NVIC), but you wouldn't then be able to
use a protected handler. I don't think you'd want to? the reason for
having a specific handler would be for performance, e.g. drone motor
electronic speed control.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How to emulate multiple exports
  2020-04-21  7:58     ` Simon Wright
@ 2020-04-24  1:36       ` Jere
  0 siblings, 0 replies; 9+ messages in thread
From: Jere @ 2020-04-24  1:36 UTC (permalink / raw)


On Tuesday, April 21, 2020 at 3:58:24 AM UTC-4, Simon Wright wrote:
> Jere writes:
> 
> > On Monday, April 20, 2020 at 5:57:06 AM UTC-4, Simon Wright wrote:
> >> Jere  writes:
> >> 
> >> > I am working in a space constrained environment (256k flash)
> >> > and I want to try and reuse the same exported function for
> >> > all of my unused interrupt handlers.
> >> 
> >> I don't know if it'll help, but I handle a similar problem in Cortex
> >> GNAT RTS starting here:
> >> 
> >> https://github.com/simonjwright/cortex-gnat-rts/blob/master/stm32f4/adainclude/startup.adb#L147
> >
> > That looks closer to what I was trying.  Out of curiosity, how
> > does it handle someone wanting to later on assign a specific
> > peripheral ISR (like a timer for example)?  It looks like
> > all the remaining ISR slots use the same external 
> > symbol (IRQ_Handler)
> 
> It doesn't. Of course it could (write to the interrupt vector & set the
> hardware interrupt priority in NVIC), but you wouldn't then be able to
> use a protected handler. I don't think you'd want to? the reason for
> having a specific handler would be for performance, e.g. drone motor
> electronic speed control.

In my scenario, I'm working with a ZFP runtime, so I don't have access
to protected types.  I don't think I can leverage the attach handler
method?  What I currently have is an array of weak references so that
client code can export a procedure using that symbol name to add their
handlers.  I don't like this though as I haven't found a good way to
default those handlers, which I feel is pretty unsafe.  If they enable
an interrupt without a handler it might just jump into the wind.

I could do it with a C file, but I am struggling to keep this as much 
Ada as possible.

Performance on ISRs is a concern.  I'm running at 4MHz, so about 250ns
per instruction cycle and I interface with some things that need
on the order of 10us response time (infrequently, but when it happens, 
the performance needs to be there).  Otherwise, I might just use an 
indirect jump to another memory location and manage my ISR's there 
(similar to how a primitive bootloader might handle an IVT).

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-04-24  1:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-19 23:53 How to emulate multiple exports Jere
2020-04-20  6:27 ` Egil H H
2020-04-20 20:48   ` Jere
2020-04-20  6:52 ` Jeffrey R. Carter
2020-04-20 20:51   ` Jere
2020-04-20  9:57 ` Simon Wright
2020-04-20 20:57   ` Jere
2020-04-21  7:58     ` Simon Wright
2020-04-24  1:36       ` Jere

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox