Variable alignment in arm-embedded

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Variable alignment in arm-embedded

Koenraad Lelong-2
Hi,

I want to make an interrupt-vector-table for the cortex-M3 processor.
When I read the docs of the processor good, the start of that table
needs to be on a multiple of $100 bytes in memory. Since with FPC there
seems no way of getting that table in flash I need to have it in RAM.
But how can I have the table at those $100-bytes multiple ? I found an
ALIGN directive, but that's limited to 32 bytes.
Any suggestions ?
I had hoped that the first variable would be at the first location in
RAM and the first variable in the startup-code is that vector-table.
Unfortunatly, my hope was in vain.

Any help ?

Regards,

Koenraad Lelong.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

RE : [fpc-pascal] Variable alignment in arm-embedded

Ludo Brands
> Hi,
>
> I want to make an interrupt-vector-table for the cortex-M3 processor.
> When I read the docs of the processor good, the start of that table
> needs to be on a multiple of $100 bytes in memory. Since with
> FPC there
> seems no way of getting that table in flash I need to have it in RAM.
> But how can I have the table at those $100-bytes multiple ? I
> found an
> ALIGN directive, but that's limited to 32 bytes.
> Any suggestions ?
> I had hoped that the first variable would be at the first location in
> RAM and the first variable in the startup-code is that vector-table.
> Unfortunatly, my hope was in vain.
>
> Any help ?
>

Handcrafted alignment:

var
  ReservedBlock:array[0..$1FF] of byte;
  IntVectors:pointer;
begin
  IntVectors:=pointer((ptruint(@ReservedBlock[0])+$100) and not $ff);
End;

Or dynamic:

Var
  pReservedBlock,IntVectors:pointer;
begin
  Getmem(pReservedBlock,$200);
  IntVectors:=pointer((ptruint(pReservedBlock)+$100) and not $ff);
End;


Ludo

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

Koenraad Lelong-2
On 08-06-12 06:45, Ludo Brands wrote:

>
> Handcrafted alignment:
>
> var
>    ReservedBlock:array[0..$1FF] of byte;
>    IntVectors:pointer;
> begin
>    IntVectors:=pointer((ptruint(@ReservedBlock[0])+$100) and not $ff);
> End;
>
> Or dynamic:
>
> Var
>    pReservedBlock,IntVectors:pointer;
> begin
>    Getmem(pReservedBlock,$200);
>    IntVectors:=pointer((ptruint(pReservedBlock)+$100) and not $ff);
> End;

Thanks Ludo,

I'll take that as a starting point. I hope I will not need the "lost"
256 bytes in the future.
I can replace the IntVectors-pointer with a pointer to a record of
pointers, isn't it ? That way I have a clearer view of what vectors I'm
working with.

TIntVectorTable = record of
        NMI_Handler,
        HardFault_Handler,
        MemManage_Handler,
        BusFault_Handler,
        UsageFault_Handler,
        SWI_Handler,
        DebugMonitor_Handler,
        PendingSV_Handler,
        Systick_Handler,
(* STM32 specific Interrupt Numbers *)
        WWDG_Handler,
        PVD_Handler,
        ...
        USBWakeUp_Handler : pointer;
end {TIntVectors};

var
  IntVectors : ^TIntVectorTable;
  ReservedBlock:array[0..$FF+SizeOf(TIntVectorTable)] of byte;

procedure SystickProc; interrupt;

begin
...
end;

begin
   IntVectors:=pointer((ptruint(@ReservedBlock[0])+$100) and not $ff);
   IntVectors^.SystickHandler:=@SystickProc;
...
end.

Koenraad
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

RE : RE : [fpc-pascal] Variable alignment in arm-embedded

Ludo Brands
> Thanks Ludo,
>
> I'll take that as a starting point. I hope I will not need the "lost"
> 256 bytes in the future.

I could be wrong but AFAIK if the compiler would do the alignment, the loss
can also be up to 255 bytes. Here you lose 256 bytes in all cases.

> I can replace the IntVectors-pointer with a pointer to a record of
> pointers, isn't it ? That way I have a clearer view of what
> vectors I'm
> working with.
>

Yes, of course.

Ludo

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

Jeppe Græsdal Johansen
Den 08-06-2012 14:28, Ludo Brands skrev:
>> Thanks Ludo,
>>
>> I'll take that as a starting point. I hope I will not need the "lost"
>> 256 bytes in the future.
> I could be wrong but AFAIK if the compiler would do the alignment, the loss
> can also be up to 255 bytes. Here you lose 256 bytes in all cases.
Yes, but this would allow the linker to place other stuff there which
fits in less than 255 bytes.

Wasting 255 bytes is a lot on systems that only has a few kilobytes of
RAM. I wonder if the restriction of 32 bytes on the align directive
could just be removed, or will we need some sort of linker script changes?
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
This post was updated on .
Hi Jeppe,

I've been using the actual ROM based interrupt table for the past month now in freepascal ad it seems to work great. No need to declare a block of RAM and pointing the interrupt table to it.

You can code any procedure and just give it the interrupt keyword with an address index.

For example:

procedure Systick_HandlerProc; interrupt 14;
begin
  // Process the interrupt
  if SysTickDelayCounter > 0 then dec(SysTickDelayCounter);
end;

There are 3 patches you need to apply to your compiler. I'll try to submit the patches to the Freepascal mailing list and hopefully someone will accept them, but in the mean time you can find them here.

https://github.com/alrieckert/freepascal/commit/8255677c9a79dfec22b65c5b34be43b1602c6928
https://github.com/alrieckert/freepascal/commit/2e40029a9d4b191ee06b7b3519bdc382769adbc7
https://github.com/alrieckert/freepascal/commit/1883b86791af851f0c5093760e349dc8854c5905

The first patch enables the interrupt keyword for the arm-embedded target and allows the compiler to generate the NVIT table that will link in at 0x080000000

The second patch is a small bug fix with the stm32f103.pp definition file

The third patch fixed the exit code, otherwise you will get Hard Fault interrupt when a interrupt occurs as a procedure is busy restoring the stack and SP.

No need to give the nostackframe since the ARMv7m automatically stores R0-R3, R12, SP and LR for you when  an interrupt occurs, thus the interrupt procedure looks exactly like a normal procedure.

Please let me know if you have any questions.

--
Anton  
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

Koenraad Lelong-2
In reply to this post by Jeppe Græsdal Johansen
On 08-06-12 14:37, Jeppe Græsdal Johansen wrote:

> Den 08-06-2012 14:28, Ludo Brands skrev:
>>> Thanks Ludo,
>>>
>>> I'll take that as a starting point. I hope I will not need the "lost"
>>> 256 bytes in the future.
>> I could be wrong but AFAIK if the compiler would do the alignment, the
>> loss
>> can also be up to 255 bytes. Here you lose 256 bytes in all cases.
> Yes, but this would allow the linker to place other stuff there which
> fits in less than 255 bytes.
>
> Wasting 255 bytes is a lot on systems that only has a few kilobytes of
> RAM. I wonder if the restriction of 32 bytes on the align directive
> could just be removed, or will we need some sort of linker script changes?

Hi,

I'm still struggling to get interrupts (or even inputs) work but I
wanted to comment on the size of the table. Reading the manuals I found
it's actually on a 512 byte boundery. The VTOR (Vector Table Offset
Register) masks off the last 9 bits (8..0).
If I need that space I will modify the start of RAM location and use the
first bytes of RAM for the vector-table.
It would be nice to have "external" linker scripts. That way you could
more easily add processors, or use custom bootloaders.

Regards,

Koenraad Lelong.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

Florian Klaempfl-5
In reply to this post by Jeppe Græsdal Johansen
Am 08.06.2012 14:37, schrieb Jeppe Græsdal Johansen:

> Den 08-06-2012 14:28, Ludo Brands skrev:
>>> Thanks Ludo,
>>>
>>> I'll take that as a starting point. I hope I will not need the "lost"
>>> 256 bytes in the future.
>> I could be wrong but AFAIK if the compiler would do the alignment, the
>> loss
>> can also be up to 255 bytes. Here you lose 256 bytes in all cases.
> Yes, but this would allow the linker to place other stuff there which
> fits in less than 255 bytes.
>
> Wasting 255 bytes is a lot on systems that only has a few kilobytes of
> RAM. I wonder if the restriction of 32 bytes on the align directive
> could just be removed, or will we need some sort of linker script changes?

It could be removed but I'am pretty sure that the linker does not use
the alignment space for other stuff.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

Florian Klaempfl
In reply to this post by Koenraad Lelong-2
Am 12.06.2012 09:50, schrieb Koenraad Lelong:

> On 08-06-12 14:37, Jeppe Græsdal Johansen wrote:
>> Den 08-06-2012 14:28, Ludo Brands skrev:
>>>> Thanks Ludo,
>>>>
>>>> I'll take that as a starting point. I hope I will not need the "lost"
>>>> 256 bytes in the future.
>>> I could be wrong but AFAIK if the compiler would do the alignment, the
>>> loss
>>> can also be up to 255 bytes. Here you lose 256 bytes in all cases.
>> Yes, but this would allow the linker to place other stuff there which
>> fits in less than 255 bytes.
>>
>> Wasting 255 bytes is a lot on systems that only has a few kilobytes of
>> RAM. I wonder if the restriction of 32 bytes on the align directive
>> could just be removed, or will we need some sort of linker script
>> changes?
>
> Hi,
>
> I'm still struggling to get interrupts (or even inputs) work but I
> wanted to comment on the size of the table. Reading the manuals I found
> it's actually on a 512 byte boundery. The VTOR (Vector Table Offset
> Register) masks off the last 9 bits (8..0).
> If I need that space I will modify the start of RAM location and use the
> first bytes of RAM for the vector-table.
> It would be nice to have "external" linker scripts. That way you could
> more easily add processors,

I think extending t_embedded.pas is the more clean solution to add new
controllers, especially because it makes it easier for other people to
use the added controllers.

> or use custom bootloaders.
>
> Regards,
>
> Koenraad Lelong.
> _______________________________________________
> fpc-pascal maillist - [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

Florian Klaempfl
In reply to this post by alrieckert
Am 11.06.2012 13:46, schrieb alrieckert:

> Hi Jeppe,
>
> I've been using the actual ROM based interrupt table for the past
> month now in freepascal ad it seems to work great. No need to declare
> a block of RAM and pointing the interrupt table to it.
>
> You can code any procedure and just give it the interrupt keyword
> with an address index.
>
> For example:
>
>
>
> There are 3 patches you need to apply to your compiler. I'll try to
> submit the patches to the Freepascal mailing list and hopefully
> someone will accept them, but in the mean time you can find them
> here.

Better submit a bug tracker entry. This way it cannot get lost.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

RE : [fpc-pascal] Variable alignment in arm-embedded

Koenraad Lelong-2
In reply to this post by alrieckert
On 11-06-12 13:46, alrieckert wrote:
> Hi Jeppe,
>
> I've been using the actual ROM based interrupt table for the past month now
> in freepascal ad it seems to work great. No need to declare a block of RAM
> and pointing the interrupt table to it.
>
...
>
> Please let me know if you have any questions.
>
> --
> Anton

Hi Anton,

I just tried something, but it seems that the vector table is not
updated. I enclose my project.
This afternoon I downloaded your whole git-repo following your links. I
compiled my crosscompiler. Then I tried a bare project. First I found
that the flash-start was wrong. I corrected that and recompiled the
compiler. Then I compiled the bare-program again. I didn't find my
systick-handler (optimized away !?). Then I tried to "use" the handler
and now I see the systick-handler in the disassembly (bare.dis).
Unfortunately, I don't see the address of the systick-handler in the
vector-table.

What am I doing wrong ?

Koenraad.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Bare.tar.bz (10K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
This post was updated on .
Hi Koenraad,

Glad to see more people that want to make use of Freepascal for STM32.

I've had a quick look at your project and everything seems fine. The only thing I noted is that the interrupt procedures must be in a separate unit. I've changed your project and recompiled it and now it seems fine.

Please just make sure about your starting address for the flash. I'm using the STM32F103CBT6 and the start address is 0x08000000 and not 0x0800000

I'll have a look at why the interrupt procedures needs to be separate and get back to you.

I've also attached one of my sample projects that you can test with. The project will blink a LED on PortB.8 making use of the Systick timer and echo all data send to it via USART1 back making use of the USART interrupt. It also includes a large set of the STM32 StdPeripheral libraries that is ported to Pascal.

Regards
Anton

Bare2.tar.gz
test.tar.gz
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
alrieckert wrote
I'll have a look at why the interrupt procedures needs to be separate and get back to you.
Ok, the compiler was only scanning the used source files for interrupt procedures and not the main file as well. I've added the necessary code to ncgutil.pas that will allow the compiler to scan the main project file as well.

https://github.com/alrieckert/freepascal/commit/0589b86b052cc0711f69d4f61f9f4869f6b95cc4 

Your project should now generate the Vector table correctly. Please keep me informed.

Regards
Anton
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
In reply to this post by alrieckert
alrieckert wrote
Please just make sure about your starting address for the flash. I'm using the STM32F103CBT6 and the start address is 0x08000000 and not 0x0800000
I've just verified it. The starting address for the flash should be 0x08000000. The reason for mine being 0x08003000 is that I'm making use of a USB DFU bootloader to load my program onto the device.

Would be nice if we could specify the flash start offset at compile (link) time and not to hard code this into the compiler?

Regards
Anton
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

Tomas Hajny-2
On Wed, June 13, 2012 07:37, alrieckert wrote:

> alrieckert wrote
>>
>> Please just make sure about your starting address for the flash. I'm
>> using
>> the STM32F103CBT6 and the start address is 0x08000000 and not 0x0800000
>>
> I've just verified it. The starting address for the flash should be
> 0x08000000. The reason for mine being 0x08003000 is that I'm making use of
> a
> USB DFU bootloader to load my program onto the device.
>
> Would be nice if we could specify the flash start offset at compile (link)
> time and not to hard code this into the compiler?

Sorry for a possibly stupid question, but is this offset (conceptionally)
comparable to the -WB option used for some other targets? If so, it might
make sense to extend it also for your case...

Tomas


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

RE : [fpc-pascal] Variable alignment in arm-embedded

Koenraad Lelong-2
In reply to this post by alrieckert
On 13-06-12 07:37, alrieckert wrote:

>
> alrieckert wrote
>>
>> Please just make sure about your starting address for the flash. I'm using
>> the STM32F103CBT6 and the start address is 0x08000000 and not 0x0800000
>>
> I've just verified it. The starting address for the flash should be
> 0x08000000. The reason for mine being 0x08003000 is that I'm making use of a
> USB DFU bootloader to load my program onto the device.
>
> Would be nice if we could specify the flash start offset at compile (link)
> time and not to hard code this into the compiler?
>
> Regards
> Anton
>
Thanks Anton,

I will try this right away. And good spotting that start-address. I
think I removed the 3 and somehow didn't replace it with a 0. I would
have had a hard time debugging that I think. I'm using an STM32F103RB
b.t.w. (Olimexino-STM board).

About that DFU-loader, do you have to do anything special to be able to
use fpc, besides modifying your start-address ? Any links to read more
about it ?
Now I'm using jtag to flash and debug my software.

Regards,

Koenraad.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
Koenraad Lelong-2 wrote
About that DFU-loader, do you have to do anything special to be able to
use fpc, besides modifying your start-address ? Any links to read more
about it ?
Now I'm using jtag to flash and debug my software.
Hi Koenraad,

I'm using "DfuSe USB device firmware upgrade STMicroelectronics extension" from ST. You can download it from this link.
http://www.st.com/internet/mcu/product/164487.jsp

 I compiled the project with IAR, got a HEX file that I uploaded to my microcontroller using a STLink2 (JTAG).

Now when you hold the button and power up the micro, it will enter bootload mode and allow you to upload new firmware via the USB. The only requirement is that your new project will start at 0x08003000 since the bootloader resides at the beginning.

As from a FPC view, you only need to change the flash stat offset as I had it.

The link I posted has all the required software, docs and drivers you will need.

Please ask if you have any other questions.

--
Anton
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
In reply to this post by Tomas Hajny-2
Tomas Hajny-2 wrote
Sorry for a possibly stupid question, but is this offset (conceptionally)
comparable to the -WB option used for some other targets? If so, it might
make sense to extend it also for your case...
Hi Tomas,

Not a stupid question at all. To be totally honest, I have no idea what the -WB parameter does. I tried to play around with it, but it tells me illegal parameter -WBxxx

Basically what needs to happen, is al link time, the link script needs to take the flash start address as a variable from somewhere. So this is an example of the current link.res  that is generated by the compiler. The origin and lengths are hardcoded.

ENTRY(_START)
MEMORY
{
    flash : ORIGIN = 0x08000000, LENGTH = 0x00020000
    ram : ORIGIN = 0x20000000, LENGTH = 0x00005000
}
_stack_top = 0x20005000;
SECTIONS
{
     .text :
    {
    KEEP(*(.init, .init.*))
    *(.text, .text.*)
    *(.strings)
    *(.rodata, .rodata.*)
    *(.comment)
    _etext = .;
    } >flash
    .data :
    {
    _data = .;
    *(.data, .data.*)
    KEEP (*(.fpc .fpc.n_version .fpc.n_links))
    _edata = .;
    } >ram AT >flash
    .bss :
    {
    _bss_start = .;
    *(.bss, .bss.*)
    *(COMMON)
    } >ram
. = ALIGN(4);
_bss_end = . ;
}
_end = .;

and all that needs to happen is you need to be able to set the

flash ORIGIN,
flash LENGTH,
ram ORIGIN,
ram LENGTH

with either a parameter or as compiler directives.

Regards
--
Anton
Reply | Threaded
Open this post in threaded view
|

Re: RE : RE : [fpc-pascal] Variable alignment in arm-embedded

alrieckert
In reply to this post by Florian Klaempfl
Florian Klämpfl wrote
Better submit a bug tracker entry. This way it cannot get lost.
Hi Florian,
Thank you, I do have an open bug on this issue here
Freepascal Bug ID 22146
--
Regards
Anton Rieckert
Reply | Threaded
Open this post in threaded view
|

Re: RE : [fpc-pascal] Variable alignment in arm-embedded

Tomas Hajny-2
In reply to this post by alrieckert
On Wed, June 13, 2012 12:55, alrieckert wrote:

> Tomas Hajny-2 wrote
>>
>> Sorry for a possibly stupid question, but is this offset
>> (conceptionally)
>> comparable to the -WB option used for some other targets? If so, it
>> might
>> make sense to extend it also for your case...
>>
>
> Hi Tomas,
>
> Not a stupid question at all. To be totally honest, I have no idea what
> the
> -WB parameter does.

You can find some information about the image addresses on MS Windows on
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/compdirsimagebaseaddress_xml.html
and
http://blogs.msdn.com/b/calvin_hsia/archive/2007/07/27/dll-image-base-addresses-are-the-same-in-xp-different-on-vista.aspx.
Maybe that helps you to check if it is conceptually similar/comparable, or
not.


> I tried to play around with it, but it tells me
> illegal parameter -WBxxx

Yes, the parameter is enabled only for certain platforms (see the compiler
help listed if calling it without parameters), that's why I talked about
extending it (by enabling it for another target on line 1704 of
options.pas in trunk and adding support for using the passed value in
t_embed.pas - see TExternalLinkerWin methods SetDefaultInfo,
WriteResponseFile and MakeExecutable in t_win.pas to see how it is
accessed and used for the Windows targets).


> Basically what needs to happen, is al link time, the link script needs to
> take the flash start address as a variable from somewhere. So this is an
> example of the current link.res  that is generated by the compiler. The
> origin and lengths are hardcoded.
>
> and all that needs to happen is you need to be able to set the
>
> with either a parameter or as compiler directives.

(Re-)using image base would provide both options.

Tomas


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
12