Compile a new libmbed.a file

I need to increase the stack size of the lwip-tcpip thread using "lwip.tcpip-thread-stacksize".

This I thought wouild have been possibl;e simply by changing the mbed_app.json file, but according to arduino support, it needs a complete recompile of the system, and the mbed_app.json file is placed in the conf folder under variants, and it is incorporated from there.

I have tried to figure out how to recompile the library, and have gotten nowhere.

I installed mbel studio, but that does not help, as it doess no recognise the mbed-os-to-arduino command - which is what is supposed to be executed.

I tried installing mbed studio in a raspberry pi, but it hangs when trying to install / update udev ?

I installed a linux shell in windows, and tried from there, that failed as well with a number of errors.

Does anyone have a conceise description of how to recompile the OS to generate a new libmbed.a file - preferrably in windows.

Thanks

In order to compile the entire "libmbed.a" file - you need all the source code files first to do so
(good luck to find really all files in one repository).
And: in order to generate a LIB, you need a "special" project setup in order to create a LIB instead of an EXEcutable (possible, but needs really all source code files, header files etc. - a separate topic).

BTW: why do you think it is necessary to modify the "stack size"?

The stack size used for your entire own FW comes from your own linker script and project setup.
A LIB does not manage neither creates a stack. It is the last part of your linker to bind the stack in your "executable" with all the code (also coming from a LIB).
All the code in LIB is still "relocatable", not yet bound. Sure, if stack is needed - the code just uses the "stack" which is assumed as "available" during run-time. Stack becomes just available when you "link" your code with the LIB, not before.

You can increase the stack size yourself: it sits in the linker_script.ld file. If you need more stack, even for all the functions in the LIB - your project linker script assigns it at the last step of compile. Your own project linker setting provides the stack also for all the LIB code.

Provide more stack in YOUR project linker script if you think the LIB functions need more space. No need to compile the LIB source code again: there is nothing inside the LIB which is related to the stack organization (and total size needed at the end for system).

The stack size needed depends more on: how many "nested calls" do you have, esp. very important if you use code in a "recursive" way (a function calling itself again, stacking up all until the exit from the most inner one, recursive coding can eat up any stack size!).

Stack and stack size is managed by your linker script, not by the LIB (a LIB is "stack-independent" code). Just to make sure to provide enough stack for the entire system (a LIB does not have any stack size or stack management related code inside - wasted time to trim a LIB for "stack needed" = rewriting all the code in the LIB).

Thanks for the reply. I jknow for mBed OS threads created by my own software, I have to define the stack size in code, for example

rtos::Thread TMP117_Thread(osPriorityNormal, 1600L);

I dump the stack info of all the running threads in my application, and I believe the lwip thread is the culprit (it is defined as 1200 bytes in the header files), it is always maxed out at 1200 (see first one in the list below). It is possible that only exactly 1200 bytes are required, but I am very suspicious that that is not the case.

I had pointed this out to Arduino support in release 3.2, and was hoping 3.3.0 would have corrected it, but it did not.

My own threads are all comfortably below the allotted amount of stack. I also wanted to be able to decrease the main thread stack size, as it defaultrs at 32k, which is way too much for my purpose.

I looked at the linker_script.ld files in my 3.3.0 directories, and unfortunately, I do not see anything that allows me to alter the individual thread stack sizes.

Heap Cur=63369  Heap Res=435776 Heap max=67741
uptime (days:hh:mm:ss) = 0:02:19:40

      Thread: 0x2400f970, Stack size: 1200, Max stack: 1200
      Thread: 0x24024500, Stack size: 4096, Max stack: 928
      Thread: 0x24006c04, Stack size: 896, Max stack: 328
      Thread: 0x24003434, Stack size: 4400, Max stack: 1952
      Thread: 0x240122f8, Stack size: 2048, Max stack: 320
      Thread: 0x240041e0, Stack size: 3008, Max stack: 1360
      Thread: 0x24007090, Stack size: 32768, Max stack: 8456
      Thread: 0x24004320, Stack size: 4104, Max stack: 344
      Thread: 0x24003740, Stack size: 2000, Max stack: 688
      Thread: 0x24003378, Stack size: 2000, Max stack: 664
      Thread: 0x240035cc, Stack size: 1568, Max stack: 720
      Thread: 0x24003cc4, Stack size: 1600, Max stack: 600
      Thread: 0x24003bf4, Stack size: 2032, Max stack: 608
      Thread: 0x240030f0, Stack size: 6000, Max stack: 1440
      Thread: 0x240032bc, Stack size: 2688, Max stack: 904
      Thread: 0x240034f0, Stack size: 1552, Max stack: 624
      Thread: 0x24003a68, Stack size: 1536, Max stack: 640
      Thread: 0x240031b8, Stack size: 1584, Max stack: 704
      Thread: 0x240045c4, Stack size: 2400, Max stack: 1248
      Thread: 0x24006bc0, Stack size: 768, Max stack: 104
      Thread: 0x24017538, Stack size: 256, Max stack: 128
      Thread: 0x2400f430, Stack size: 2048, Max stack: 200

As for the libmbed.a compile, I am told by Arduino Support that some time in the near future, documentation will be released to allow us to more easily do this

OK, sure:
if LIB functions fork a thread: the Thread Stack Size is fix coded.
But I would assume: threads sitting in LIB would use an appropriate stack size.

And the RTOS thread stack sizes come from a different setting: it is not the MCU "regular" stack.
It is a globally defined memory used as RTOS Thread Stacks. There is a macro somewhere in the RTOS_Config which defines the total stack size for all threads. (a header file which defines the RTOS Thread Stack).

This is NOT related to the linker script and the stack size there.
But the stack size in linker script matters still a bit if you use RTOS: it can be the stack size needed to do HW Interrupts, e.g. device, EXTI interrupts.
The MCU has TWO stacks!, be aware of that HW interrupts might use another stack.
And the RTOS threads/tasks use one of them which is set via a H-file for RTOS config.

I would assume:

  • the RTOS threads in LIBs are OK with their their stack size (each, otherwise not well tested and implemented)
  • but the entire stack for RTOS (set via this H-file for RTOS config) is too small
  • you have so many threads launched that the RTOS stack is overflowing (the fix setting)

Sure, you cannot modify the stack size of a single thread in LIB, but I "hope" you can increase the total amount of stack for all RTOS threads (in sum).

It is in my project (a plain STM32CubeIDE, not Arduino, not mbed) the file "FreeRTOSConfig.h"
with these lines:

#define configMINIMAL_STACK_SIZE                 ((uint16_t)1024)		//XXXX
#define configTOTAL_HEAP_SIZE                    ( ( size_t )(64 * 1024) )

The configTOTAL_HEAP_SIZE is the total stack size for all in RTOS (stack, heap, MemPool ?).

If this define sits also in your LIB: "you are screwed" (and a need to modify just this H file in LIB)
It would be a pretty ugly SW design and limits the amount of threads you can create.

There would be still a "trick" to increase the total RTOS stack region. But it needs details about the name of the RTOS-Stack-Memory and an entry in your project_linker.ld script (extend the size for this RTOS Stack region via linker script, as reserved (and extend) memory).

Rather than using the Portenta board package that you download via the IDE, you need to clone the ArduinoCore-mbed git repository to a specific location in your $sketchbook folder. This repository can be found here on GitHub. It's README indicates to where you should clone the repository and how to run the above mentioned mbed-os-to-arduino script. In addition to those instructions, I also installed the Mbed-cli tools before running the mbed-os-to-arduino script since the script depends on them.

I suspect it will be easiest to run that script on a Linux machine. You could try the Linux shell in Windows. I have run it on macOS but I had to hack some parts of the script to get it working on that platform.

You don't need to clone ArduinoCore-Mbed repository as it is included in the Arduino15 folder when you download the portenta Core (Full path for me is Arduino15/packages/arduino/hardware/mbed_portenta/3.3.0)
I compiled it successfully with Cygwin on Windows, I detailed the procedure here

The Arduino15/packages/arduino/hardware/mbed_portenta/3.3.0 folder already has all Mbed-OS header files. Copy the source files that you are interested in into the tree. The Arduino 1.8 GUI will then automatically compile these source files. To avoid multiple references, you need to remove the corresponding *.o files from libmbed.a using the ar executable for the platform (like arm-none-eabi-ar.exe). It is not difficult to create a makefile project that does the Arduino 1.8 build in STM32CubeIDE, that way you can avoid the caching in random places under temp, and also debug the source code.

I finally got it to compile - used a wsl2 install in windows, and after a couple of attempts, finally worked. WSL helps in that you can revert to a previous stage of the OS if you make export copies as you go along.

I posted the steps I took to compile the file here (after a few good suggestions from other members, including Martino Facchin)

Would you have any advice on how to compile a portenta h7 project using stm32cubeide?

I setup a stm32cubeide project using the files from ...\AppData\Local\Arduino15\packages\arduino\hardware\mbed_portenta\4.0.2

I manually entered the setting from mbed_portenta\4.0.2\variants\PORTENTA_H7_M7
into the stm32cubeide project settings for complier and linker flag.

I also added the includes from includes.txt

I configure the project to use libmbed.a (:libmbed.a).

I replaced the files in arduino\as_mbed_library with the ones from ...\mbed_portenta\4.0.2\variants\PORTENTA_H7_M7

I set the linker script to use the .LD file from ...\mbed_portenta\4.0.2\variants\PORTENTA_H7_M7

The project would build but would not run past WWDG_RST_IRQHandler.

My project does not have these files.
startup_stm32h747xx.s
stm32h7xx_it.c
system_stm32h7xx_dualcore_boot_cm4_cm7.c
I assume these are not needed because they are part of libmbed.a

Unfortunately, no experience there, however tjaekel has created a few projects. You can look at his github page - maybe it might help

I was able to get the project to run. Libmbed.a overrides
weak uint32_t HAL_GetTick(void) from stm32h7xx_hal.c with
uint32_t HAL_GetTick() from hal_tick_overrides.c

In the recompiled Libmbed.a for debugging I could see that there is a hal_tick_overrides.o but even so uint32_t HAL_GetTick() from hal_tick_overrides.c was not being used.

Adding hal_tick_overrides.c to my project allowed it to run but I don't know why I needed to do that.

I used the Arduino IDE to compile blinky project using the same recompiled libmbed.a that I had been using in STM32CubeIDE.

After compiling the project, I the created a debug configuration in STM32CubeIDE that used the Portenta_Blink.ino.elf created by Arduino IDE. When I would debug using this configuration the project would run and HAL_GetTick() from hal_tick_overrides.c was being used.

I wonder if it has to do with how Arduino IDE does the linking. I just noticed that Arduino IDE sets the flag --no-whole-archive.