cancel
Showing results for 
Search instead for 
Did you mean: 

OTA modular update STM32F446ZET6 with FreeRTOS

jaumas43
Associate II

Hi all,

I need to perform a modular update in my f446 board for my project.

The board is running a FreeRTOS, and the idea is to only modify the content of one task without affecting the content of other tasks. For doing this, every task calls its function, and these functions are defined in specific areas of memory defined in the linker file.

Here is an example of a function:

void __attribute__((section(".custom_section1"))) application1 (void)

{

printf("in app 1 \r\n");

}

 

Here is a part of the linker file:

...

APPLICATION_1 (rx) : ORIGIN = 0x8010000, LENGTH = 64K /* Sector 3 */

...

.custom_section1 :

{

*(.custom_section1)

} > APPLICATION_1

 

 

And here is the task calling the application:

void StartApp1(void *argument)

{

for(;;)

{

 

application1();

osDelay(1000);

 

}

/* USER CODE END StartApp1 */

}

 

 

 

Before performing the update everything works perfectly, the tasks call the functions and with CubeProgrammer I check that they are stored where we want them to be.

 

 

The problem comes after the update. I am sending through CAN the code of the new function that I want to run, which is this:

void __attribute__((section(".custom_section1"))) application1 (void)

{

printf("in app 1.1 \r\n");

}

 

This function works also perfectly in the sending board and in the location where it is expected.

 

When the information comes through CAN, the task that runs the application is deleted, the memory sector gets erased and then I coppy this message in that exact same memory address. After checking the memory content I see that it is the exact content as in the 'sending board'.

 

But then, when launching the new task that calls this new function it crashes right when it calls it.

 

I have already tried different approaches, to do it by suspending and relaunching the original task, to create a new task (like described before), to stop all the tasks . I see that the problem is not task related because I put some printf in the new task to see that it works, the problem is just in calling this new function. I also tried to reset the system after the new function is coppied, but still crashes there.

 

Is what I am trying to do possible? And what is avoiding launching this new function?

 

Thanks a lot in advance

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

You mention being a "beginner" but what does that mean to a guy who coded MCU's in assembler in secondary school 4 decades ago. I need some jumping off point, on something you can relate too.

What schooling and experience do you have in coding or computing?

New to STM32? Any other MCU, IDE, etc

New to Assemblers, Compilers, Linkers, Loaders, etc? College level coverage of said?

 

Like I said it's not the "function" it's all the baggage that comes with it. The MCU doesn't come with an OS, and a deep layer of support, executables and DLLs. It's all delivered as a mostly monolithic blob of code. You can jump from one blob to the other, but they tend to be self-contained, have their own Vector Table, and Reset_Handler() entry point. And their own view of how memory is allocated and used.

You could mount something like a DLL, but there's a lot of two-way contracts and expectations with that.

Perhaps look at ST's IAP loader model, a loader that can bring up the bulk of the board, MCU, memory, etc, and than transfer to 1 to N different Applications placed in memory.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

6 REPLIES 6

It depends I suppose on how self contained this task is. It's frequently going to be what it calls (dependencies) and what memory, FLASH and RAM the linker allocates each separate build of things.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi,

Thanks for the reply! Could you elaborate a bit further?

The new task just prints something and calls the new function (application1()):

void StartApp1_1(void *argument)

{

 for(;;)

 {

   printf("About to try to relaunch with a new function \r\n");

   application1();

   osDelay(1000);

 }

}

 

And the new function is stored in the same address where the old one was and the content is this:

#include "applications.h"

#include <stdio.h>

 

void __attribute__((section(".custom_section1"))) application1 (void)

{

printf("in app 1.1 \r\n");

}

 

My idea was that, by giving the new function the same name as the previous one and storing it in the same place, this would be ok with the linker file.

The new task is working, as I see the printf, but when it executes the function it crashes.

Forgive me if I am asking something that makes no sense, I am a beginner.

 

If you've solved the problem yourself, I'm not sure on the point of elaborating further.

The code you present is trivial yes, but it's all the OTHER code that it brings with it, and the fact you can't typically just call a singular function from an entirely different code space. The linker assumes it has a clean sheet to work with, and the C runtime initialization expects to be called first to clear and copy statics into RAM. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I am sorry, I think there has been a misunderstanding,

I have not solved it, since calling the function still breaks the system.

Is there then a way of modify this other code so that it is able to execute it? Like calling this C runtime initialization from the code after update?

And, since this function is defined in the same address as the previous one with the same name as the previous one, shouldn't the linker file think that it is the previous code?

 

You mention being a "beginner" but what does that mean to a guy who coded MCU's in assembler in secondary school 4 decades ago. I need some jumping off point, on something you can relate too.

What schooling and experience do you have in coding or computing?

New to STM32? Any other MCU, IDE, etc

New to Assemblers, Compilers, Linkers, Loaders, etc? College level coverage of said?

 

Like I said it's not the "function" it's all the baggage that comes with it. The MCU doesn't come with an OS, and a deep layer of support, executables and DLLs. It's all delivered as a mostly monolithic blob of code. You can jump from one blob to the other, but they tend to be self-contained, have their own Vector Table, and Reset_Handler() entry point. And their own view of how memory is allocated and used.

You could mount something like a DLL, but there's a lot of two-way contracts and expectations with that.

Perhaps look at ST's IAP loader model, a loader that can bring up the bulk of the board, MCU, memory, etc, and than transfer to 1 to N different Applications placed in memory.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks, no I am not new to programming, and I had already done some projects in College with STM32 and C, it is more the Asemblers, Compilers, linkers etc, I never had to dig into this stuff and worry about what happens after compiling. I also don´t have any experience with bootloaders.

 

I will give it a try to the IAP loader. For what I understand, what the bootloader does in the examples is this:

1- Receiving the new program

2- Writing the new code

3- Verifying that it is correct

4- Jump to the first Address of the application (I assume that the Vector Table, and Reset_Handler() part comes here).

 

My main doubt is, given that I performed the first 3 steps in the main FreeRTOS code, do I need to create a separate program (Bootloader) to jump again to the start of the application, or can I perform this jumping part with a function inside my main FreeRTOS code?

Thanks again for your time