Dear NXP and community,
For our application we are trying to build a CAN bootloader and are taking inspiration from the application notes: AN12323.
An implementation of the application notes is provided and in this implementation it is mentioned that position independent code is required and that the provided .bin files were created with the IAR IDE. As a test I wanted to created my own .bin file to upload to the s32k EVB as part of the gateway application. For this test I created a green blinking led program that runs perfectly on the EVB. After selecting the option in the S32DS -fPIC see included image.
The application crashes and it seems to crash on the CLOCK_SYS_Init function.
I have included the project as a reference. I have read more people had trouble with the -fPIC option but there seemed to be different reasons for it.
Additional information of other ways I can create binary files to use in the AN12323 application using the S32DS are welcome. If people have managed to create their own binaries to upload to the gateway program I would love to hear how they did it.
Kind regards,
Sebastiaan Verhoek
There is new example with PIC https://community.nxp.com/docs/DOC-345595
I found the following year old topic and wondering why NXP's S32DS still can't compile truly position independent code. Is there anybody who can point me to the issue? Thanks.
c - Compiling and linking position independent code (PIC) for ARM M4 - Stack Overflow
Hey Sebastiaan,
Did you have any success in compiling position independent binary (PIC) to use with AN12323? I'd love to hear your tips if you've succeeded. Thanks.
Kind regards,
Eric
Hey Eric,
Unfortunately I have had no successes yet in compiling a position independent binary. As mentioned I am currently settling with the non-position independent version. I am still planning to look further into this. So if I find something I will reply to you. If you happen to find something please do the same :smileyhappy:.
Kind regards,
Sebastiaan
Hey Sebastian,
Will definitely do! I'm currently trying to replace one of the LED blinking image with the one compiled by IAR Workbench to see if it works. Also, I was trying to get non-position independent code, but stuck in the same place as you were. Custom built image does not blink LED, but the one with come with the application note works just fine. Could you elaborate bit more on "not relocation interrupt table"? I must be missing something and I'd really appreciate if you could provide some tips or point me to the right direction. Thanks a lot in advance!
Kind regards,
Eric
Hey Eric,
For the non-position independent code:
I have unfortunately since modified my application quite a bit from the original example so I can no longer share it.
Some tips which helped me though:
First of all you need to compile your custom code to one of the memory locations so the linker file of your custom code needs to be updated as follows:
The independent code example however assumes the interrupt table was placed at location 0x00000000 and manually relocates it.
To disable this functionality simply comment out the following lines from the function below:
In the void Flash_Block_to_Update(void) function I set the old and new address to always point to block A
Using:
flash_new_image_address_block=FLASH_BLOCK_A_ADDRESS;
flash_old_image_address_block=FLASH_BLOCK_A_ADDRESS;
/*Add image header offset */
flash_new_image_address_block=flash_new_image_address_block+IMAGE_HEADER_BYTE_SIZE;
flash_old_image_address_block=flash_old_image_address_block+IMAGE_HEADER_BYTE_SIZE;
But be careful because in the Update_FW_Headers function the old header (which is equal to the new header in our case) is being erased. So to prevent this behaviour also comment out the lines seen below.
Some other tips (not sure if you have done these already):
- check if the custom blinking led code properly functions when normally flashing it.
- If you are using the 2 EVB using the gateway code simply replace one of the files provided blinking led binaries using the exact name (this avoids having to mess with the names in the linker files)
- Sometimes cleaning the application seems to help.
- A nice feature in the S32 DS is the ability to directly check the memory locations in the S32k chip. By going to Window->Show View -> Memory you can add a monitor at location 0x2000 and compare it to an objdump of the binary file you are trying to upload to see if the data is being properly stored.
Hope this helps!
I am guessing you are also not aware if their are other (open source) solutions for compiling position independent code.
Kind regards
Sebastiaan
Hey Sebastian,
I noticed there are few differences there. When you set the both address to FLASH_BLOCK_A_ADDRESS, it means that technically there is no A/B and firmware is always flashed in a same location. Therefore, if you match with that address from linker file then it would work as if you're directly flashing. With that being said, what I'm trying to do is to have A/B, even though they could be non POC code, but should be able switch 2 different locations back and forth.
Also, even the weirdest thing is that, I've compiled POC code using IAR Workbench, but it is still not working and I'm pretty much running out of ideas and options. Just to make sure that I've got the right binary, even though I'm fairly sure it is the correct image, I'm attaching the example POC binary here. Could you try flashing it in your case to see if it is running just fine? Thanks.
Regards,
Eric
Hey Eric,
Sorry for the delay.
I am not seeing a response after running the code you sent. But I am also not quite sure what it is supposed to do.
I am not quite sure how you would want to have the code sit randomly at 1 of the 2 locations and still have the instructions point to the right location without PIC code.
Kind regards,
Sebastiaan
Hey Sebastiaan,
The image that I've sent you is supposed to blink LED and compiled with PIC code, so I was wondering if it works in your case. Thank you for letting me know that it wasn't working!
Regarding your question, I believe something like wolfBoot/firmware_update.md at master · wolfSSL/wolfBoot · GitHub can be achieved in order to alternate between 2 different firmware, which is what I am planning to accomplish. That way you can have essentially the same functionality as the application note while using position-dependent code.
Regards,
Eric
Hi Sebastiaan Verhoek,
What is the exact location in Clock_SYS_Init where the program crashes? What is the crash behavior?
Thanks,
Rares
Hello Sebastiaan,
Can you check in init_data_bss function if the data section is initialized correctly?
Thank you,
Rares
Dear Rares,
I am not 100% sure what I am looking for as I do not have a whole lot experience with this.
I set a breakpoint at the init_data_bss() (not sure if this correctly works) but when stepping through the code and checking the variables (again not sure if debugging works properly at this stage in the program). But on line 164 of startup.c:
data_ram = (uint8_t *)__DATA_RAM;
The right side seems to be initialized see image below.
But the left side after stepping to the next line still seemed uninitialized (see below):
Is this indeed the problem or am I trying to measure something that cannot be measured. When I am not using the -fpic tag or -fpie tag data_ram will be assigned the same value as __DATA_RAM (see below).
If this is indeed the issue then how can I solve it?
Kind regards,
Sebastiaan
Hi Sebastiaan Verhoek
The problem is the access to the global variables, the instructions of the code are indeed compiled independent to the address, but the global variables have to be accessed with the GOT (global offset table), the __DATA_RAM is an extern global variable, so it doesn't know the location of this variable. Unfortunately, this implementation hasn't been done in S32DS.
Best regards
Jorge Alcala
Dear NXP community,
I have fixed the issue and I am now capable of booting my own position dependent code from one fixed location. (The issue came down to not relocating the interrupt table as was done in the application note and probably the build that was not properly containing a new software version). Also viewing the actual memory of the EVB with S32DS helped greatly.
I am still looking for a way to generate position independent code. So any help in that regards is greatly appreciated.
Kind regards,
Sebastiaan Verhoek
Can you please share the code here sir???
I'm also working on the CAN bootloader and using AN12323 as a base code for that. i want to make my application position independent for that I want to implement PIC. i was reading this space for some support, can you either share the code or guide me through it to achieve!!
your help will be appreciated. thank you, sir.
Dear Jorge Alcala,
For our application it is not a hard requirement that the bootloader is an A/B swap bootloader.
Therefore I have tried to place a simple program (the blinking green led mentioned at the starting post) in a static location in memory where the bootloader will place it.
I have updated the flash.ld of the simple program file to be the following:
The bootloader application is updated to always place the application in block A and also jump to location A:
flash_new_image_address_block=FLASH_BLOCK_A_ADDRESS;
flash_old_image_address_block=FLASH_BLOCK_A_ADDRESS;
To match the Firmware 1 location linked below (being location A).
The code is functional when normally uploaded to an EVB. But when trying to use the bootloader the entire program is uploaded, but no LEDs blink as a result.
The default Blue blinking led program can still be uploaded properly using the bootloader.
Are there any other steps that have to be done to have the bootloader function properly?
The interrupt vector is placed in location 0x00000000 due to the following comment in the application note:
"Addresses in the interrupt table are not affected by the ropi and remain the same as declared in the linker file. To solve this, the interrupt is located starting at address 0x00000000 as by default in the linker file, and then an offset address must be added to each entry of the interrupt table during the update process, except for the first entry that is the stack pointer. The address offset value depends on where the new firmware will be in program flash. Hence, when an interrupt happens, core jumps to the exact location in program flash where the application firmware is placed."
But placing the interrupt table at location 0x00002000 yielded the same result.
Any help on the matter is deeply appreciated.
Kind regards,
Sebastiaan
Dear Jorge Alcala,
Is this purely a compilation step or can I easily change something in the implementation?
Does NXP offer any solutions to build this position independent code?
In the application notes AN12323, it is mentioned the demos were built using the IAR EWARM compiler.
As a small startup company we would like to prevent purchasing costly licenses.
We currently already have created a working program to load code according to the application note that can load the example projects.
Is there any advice you can give to us to implement our bootloader?
Kind regards,
Sebastiaan Verhoek