Skip to main content
Explorer
May 31, 2024
Solved

OTA modular update STM32F446ZET6 with FreeRTOS

  • May 31, 2024
  • 1 reply
  • 2110 views

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

 

 

 

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    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.

    1 reply

    Graduate II
    May 31, 2024

    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.

    jaumas43Author
    Explorer
    May 31, 2024

    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.

     

    Graduate II
    May 31, 2024

    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.