Discussion:
[PIC] Setting a function address in C32 and linker?
Harold Hallikainen
2018-01-09 05:21:17 UTC
Permalink
I'm finding linker scripts to be pretty cryptic, and the documentation
from Microchip only slightly less so.

I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?

Thanks!

Harold
--
FCC Rules Updated Daily at http://www.hallikainen.com
Not sent from an iPhone.
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Isaac M. Bavaresco
2018-01-09 12:25:44 UTC
Permalink
You can do it without changing the linker script:

__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...

Cheers,

Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/pi
Harold Hallikainen
2018-01-09 14:31:03 UTC
Permalink
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."

Thanks! More ideas?

Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
FCC Rules Updated Daily at http://www.hallikainen.com
Not sent from an iPhone.
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Isaac M. Bavaresco
2018-01-09 17:26:16 UTC
Permalink
Are you trying to write a bootloader?

In the linker-script:

MEMORY
    {
    ...
    secondary_entry_pt         : ORIGIN = 0x9FC02F00, LENGTH =     0x10
    ...
    }


EntryPoint.S:

/*============================================================================*/
        .set        nomips16
        .set        noreorder
        .set         noat
/*============================================================================*/
        .extern    EntryPoint
        .global    SecondaryEntryPoint

        .section .secondary_entry_pt,code,keep

        .ent    SecondaryEntryPoint

SecondaryEntryPoint:
        la        $k0,EntryPoint
        jr        $k0
        nop

        .end    SecondaryEntryPoint
/*============================================================================*/
Post by Harold Hallikainen
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."
Thanks! More ideas?
Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options a
Isaac M. Bavaresco
2018-01-09 17:38:24 UTC
Permalink
Oops! Forgot some pieces... And used a wrong address...


In the linker-script:

_SECONDARY_ENTRY_PT = 0xBFC02F00;
MEMORY
{
...
/* Do not forget to reduce kseg0_program_mem to exclude the bytes of
the section below */
secondary_entry_pt : ORIGIN = 0xBFC02F00, LENGTH =     0x10
...
}
SECTIONS
{
...
.secondary_entry_pt _SECONDARY_ENTRY_PT :
{
KEEP(*(.secondary_entry_pt.*))
KEEP(*(.secondary_entry_pt))
} > secondary_entry_pt
...
}


EntryPoint.S:

/*============================================================================*/
        .set        nomips16
        .set        noreorder
        .set         noat
/*============================================================================*/
        .extern    EntryPoint
        .global    SecondaryEntryPoint

        .section .secondary_entry_pt,code,keep

        .ent    SecondaryEntryPoint

SecondaryEntryPoint:
        la        $k0,EntryPoint
        jr        $k0
        nop

        .end    SecondaryEntryPoint
/*============================================================================*/

Somewhere.c:

void EntryPoint( void )
{
...
}
Post by Harold Hallikainen
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."
Thanks! More ideas?
Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/li
Isaac M. Bavaresco
2018-01-09 17:52:39 UTC
Permalink
Harold,

I used assembly just because I wanted to ensure that the entry-point had
a fixed length. I have an array of them.

You can use "__attribute__((section(...),keep))" in a C function.

Cheers,

Isaac
Post by Isaac M. Bavaresco
Oops! Forgot some pieces... And used a wrong address...
_SECONDARY_ENTRY_PT = 0xBFC02F00;
MEMORY
{
...
/* Do not forget to reduce kseg0_program_mem to exclude the bytes of
the section below */
secondary_entry_pt : ORIGIN = 0xBFC02F00, LENGTH =     0x10
...
}
SECTIONS
{
...
{
KEEP(*(.secondary_entry_pt.*))
KEEP(*(.secondary_entry_pt))
} > secondary_entry_pt
...
}
/*============================================================================*/
        .set        nomips16
        .set        noreorder
        .set         noat
/*============================================================================*/
        .extern    EntryPoint
        .global    SecondaryEntryPoint
        .section .secondary_entry_pt,code,keep
        .ent    SecondaryEntryPoint
        la        $k0,EntryPoint
        jr        $k0
        nop
        .end    SecondaryEntryPoint
/*============================================================================*/
void EntryPoint( void )
{
...
}
Post by Harold Hallikainen
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."
Thanks! More ideas?
Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/list
Harold Hallikainen
2018-01-09 19:15:54 UTC
Permalink
THANKS! As I mentioned before, I find linker scripts pretty cryptic. I'll
see if I can figure out what you're suggesting.

Yes, this is for a bootloader. What I need is to ensure that my function
that copies firmware from external flash to internal flash is always at
the same address in the boot section. I originally put a jump table in,
but it ended up in the application area instead of the boot area, so I
cannot rely on it. I need to ensure my function stays at the correct
address. So far, I've done this by having the application send an error
message to the UART I'm watching during debug if the function is not at
the right address. I then add or subtract nops to fix it (ideally it would
not move anyway, but sometimes things change).

I adapted the default linker script back in 2010 for this. It does not
have a MEMORY section, but, instead, includes ProcDefs.ld, which I
modified and renamed, and which DOES have a MEMORY section.

I have:

kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
BootJumpTable_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000

However, it looks like I never made a section that used BootJumpTable_mem,
so that's probably why the jump table ended up in the application flash.

My current thinking is that I need to create a small MEMORY section at the
address I want my function to end up at, then create a SECTIONS with an
ORIGIN with the MEMORY section name. Does that sound about right?

It would sure be easier if the address attribute worked!

THANKS!

Harold
Post by Isaac M. Bavaresco
Harold,
I used assembly just because I wanted to ensure that the entry-point had
a fixed length. I have an array of them.
You can use "__attribute__((section(...),keep))" in a C function.
Cheers,
Isaac
Post by Isaac M. Bavaresco
Oops! Forgot some pieces... And used a wrong address...
_SECONDARY_ENTRY_PT = 0xBFC02F00;
MEMORY
{
...
/* Do not forget to reduce kseg0_program_mem to exclude the bytes of
the section below */
secondary_entry_pt : ORIGIN = 0xBFC02F00, LENGTH =     0x10
...
}
SECTIONS
{
...
{
KEEP(*(.secondary_entry_pt.*))
KEEP(*(.secondary_entry_pt))
} > secondary_entry_pt
...
}
/*============================================================================*/
        .set        nomips16
        .set        noreorder
        .set         noat
/*============================================================================*/
        .extern    EntryPoint
        .global    SecondaryEntryPoint
        .section .secondary_entry_pt,code,keep
        .ent    SecondaryEntryPoint
        la        $k0,EntryPoint
        jr        $k0
        nop
        .end    SecondaryEntryPoint
/*============================================================================*/
void EntryPoint( void )
{
...
}
Post by Harold Hallikainen
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."
Thanks! More ideas?
Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the
documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
FCC Rules Updated Daily at http://www.hallikainen.com
Not sent from an iPhone.
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Isaac M. Bavaresco
2018-01-09 19:55:07 UTC
Permalink
Harold,

Microchip has some sample boot-loaders that you can use as a template,
including linker-scripts.

To avoid the problem you are facing, the correct solution would be to
create a custom linker-script that maps all the executable code sections
to the boot area (0x9fc0xxxx and 0xbfc0xxxx addresses).

If you do that, then perhaps the address attribute works, because *there
is* an executable section mapped into the area that your address points to.

But you could also create a specific section for you function.

Cheers,

Isaac
Post by Harold Hallikainen
THANKS! As I mentioned before, I find linker scripts pretty cryptic. I'll
see if I can figure out what you're suggesting.
Yes, this is for a bootloader. What I need is to ensure that my function
that copies firmware from external flash to internal flash is always at
the same address in the boot section. I originally put a jump table in,
but it ended up in the application area instead of the boot area, so I
cannot rely on it. I need to ensure my function stays at the correct
address. So far, I've done this by having the application send an error
message to the UART I'm watching during debug if the function is not at
the right address. I then add or subtract nops to fix it (ideally it would
not move anyway, but sometimes things change).
I adapted the default linker script back in 2010 for this. It does not
have a MEMORY section, but, instead, includes ProcDefs.ld, which I
modified and renamed, and which DOES have a MEMORY section.
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
BootJumpTable_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
However, it looks like I never made a section that used BootJumpTable_mem,
so that's probably why the jump table ended up in the application flash.
My current thinking is that I need to create a small MEMORY section at the
address I want my function to end up at, then create a SECTIONS with an
ORIGIN with the MEMORY section name. Does that sound about right?
It would sure be easier if the address attribute worked!
THANKS!
Harold
Post by Isaac M. Bavaresco
Harold,
I used assembly just because I wanted to ensure that the entry-point had
a fixed length. I have an array of them.
You can use "__attribute__((section(...),keep))" in a C function.
Cheers,
Isaac
Post by Isaac M. Bavaresco
Oops! Forgot some pieces... And used a wrong address...
_SECONDARY_ENTRY_PT = 0xBFC02F00;
MEMORY
{
...
/* Do not forget to reduce kseg0_program_mem to exclude the bytes of
the section below */
secondary_entry_pt : ORIGIN = 0xBFC02F00, LENGTH =     0x10
...
}
SECTIONS
{
...
{
KEEP(*(.secondary_entry_pt.*))
KEEP(*(.secondary_entry_pt))
} > secondary_entry_pt
...
}
/*============================================================================*/
        .set        nomips16
        .set        noreorder
        .set         noat
/*============================================================================*/
        .extern    EntryPoint
        .global    SecondaryEntryPoint
        .section .secondary_entry_pt,code,keep
        .ent    SecondaryEntryPoint
        la        $k0,EntryPoint
        jr        $k0
        nop
        .end    SecondaryEntryPoint
/*============================================================================*/
void EntryPoint( void )
{
...
}
Post by Harold Hallikainen
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."
Thanks! More ideas?
Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the
documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
ht
Harold Hallikainen
2018-01-09 20:20:28 UTC
Permalink
THANKS! Many years ago, in a thread I started at
http://www.microchip.com/forums/m610634.aspx#610684 , JasonK at Microchip
wrote "Unfortunately, the address attribute will work only in program
flash or data memory but not boot flash. You will need to modify the
linker script to get functions at a specific address in boot flash. We may
update the address attribute to work in boot memory in a future release."

I will keep messing with this. THANKS for all your time!

Harold
Post by Isaac M. Bavaresco
Harold,
Microchip has some sample boot-loaders that you can use as a template,
including linker-scripts.
To avoid the problem you are facing, the correct solution would be to
create a custom linker-script that maps all the executable code sections
to the boot area (0x9fc0xxxx and 0xbfc0xxxx addresses).
If you do that, then perhaps the address attribute works, because *there
is* an executable section mapped into the area that your address points to.
But you could also create a specific section for you function.
Cheers,
Isaac
Post by Harold Hallikainen
THANKS! As I mentioned before, I find linker scripts pretty cryptic. I'll
see if I can figure out what you're suggesting.
Yes, this is for a bootloader. What I need is to ensure that my function
that copies firmware from external flash to internal flash is always at
the same address in the boot section. I originally put a jump table in,
but it ended up in the application area instead of the boot area, so I
cannot rely on it. I need to ensure my function stays at the correct
address. So far, I've done this by having the application send an error
message to the UART I'm watching during debug if the function is not at
the right address. I then add or subtract nops to fix it (ideally it would
not move anyway, but sometimes things change).
I adapted the default linker script back in 2010 for this. It does not
have a MEMORY section, but, instead, includes ProcDefs.ld, which I
modified and renamed, and which DOES have a MEMORY section.
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
BootJumpTable_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
However, it looks like I never made a section that used
BootJumpTable_mem,
so that's probably why the jump table ended up in the application flash.
My current thinking is that I need to create a small MEMORY section at the
address I want my function to end up at, then create a SECTIONS with an
ORIGIN with the MEMORY section name. Does that sound about right?
It would sure be easier if the address attribute worked!
THANKS!
Harold
Post by Isaac M. Bavaresco
Harold,
I used assembly just because I wanted to ensure that the entry-point had
a fixed length. I have an array of them.
You can use "__attribute__((section(...),keep))" in a C function.
Cheers,
Isaac
Post by Isaac M. Bavaresco
Oops! Forgot some pieces... And used a wrong address...
_SECONDARY_ENTRY_PT = 0xBFC02F00;
MEMORY
{
...
/* Do not forget to reduce kseg0_program_mem to exclude the bytes of
the section below */
secondary_entry_pt : ORIGIN = 0xBFC02F00, LENGTH =     0x10
...
}
SECTIONS
{
...
{
KEEP(*(.secondary_entry_pt.*))
KEEP(*(.secondary_entry_pt))
} > secondary_entry_pt
...
}
/*============================================================================*/
        .set        nomips16
        .set        noreorder
        .set         noat
/*============================================================================*/
        .extern    EntryPoint
        .global    SecondaryEntryPoint
        .section .secondary_entry_pt,code,keep
        .ent    SecondaryEntryPoint
        la        $k0,EntryPoint
        jr        $k0
        nop
        .end    SecondaryEntryPoint
/*============================================================================*/
void EntryPoint( void )
{
...
}
Post by Harold Hallikainen
Thanks! Apparently that does now work in the boot section of flash. I saw
that written somewhere online yesterday. I tried it anyway and got
"address attribute ignored."
Thanks! More ideas?
Harold
Post by Isaac M. Bavaresco
__attribute__((address(<your_address_here>))) <return_type>
<function_name>( <arguments> ){...
Cheers,
Isaac
Post by Harold Hallikainen
I'm finding linker scripts to be pretty cryptic, and the
documentation
from Microchip only slightly less so.
I have a couple functions that I've managed to get into boot flash, but
I'd like to set the addresses of these functions. How do I do that?
Thanks!
Harold
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
---
Este email foi escaneado pelo Avast antivírus.
https://www.avast.com/antivirus
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
FCC Rules Updated Daily at http://www.hallikainen.com
Not sent from an iPhone.
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Loading...