mirror of https://github.com/ARMmbed/mbed-os.git
STM32H7: Don't use DTCM memory for heap (#396)
* STM32H7: Don't use DTCM memory for heap * Update CM4 linker script assertionpull/15531/head
parent
0fb002c6c9
commit
2564b2c1bf
|
@ -29,10 +29,20 @@ static osMutexId_t env_mutex_id;
|
||||||
static mbed_rtos_storage_mutex_t env_mutex_obj;
|
static mbed_rtos_storage_mutex_t env_mutex_obj;
|
||||||
static osMutexAttr_t env_mutex_attr;
|
static osMutexAttr_t env_mutex_attr;
|
||||||
|
|
||||||
|
// Stack symbols from linker script
|
||||||
extern uint32_t __StackLimit;
|
extern uint32_t __StackLimit;
|
||||||
extern uint32_t __StackTop;
|
extern uint32_t __StackTop;
|
||||||
|
|
||||||
|
// Heap symbols from linker script
|
||||||
|
#if defined(MBED_SPLIT_HEAP)
|
||||||
|
extern uint32_t __mbed_sbrk_start;
|
||||||
|
extern uint32_t __mbed_krbs_start;
|
||||||
|
extern uint32_t __mbed_sbrk_start_0;
|
||||||
|
extern uint32_t __mbed_krbs_start_0;
|
||||||
|
#else
|
||||||
extern uint32_t __end__;
|
extern uint32_t __end__;
|
||||||
extern uint32_t __HeapLimit;
|
extern uint32_t __HeapLimit;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void __libc_init_array(void);
|
extern void __libc_init_array(void);
|
||||||
|
|
||||||
|
@ -45,8 +55,15 @@ void software_init_hook(void)
|
||||||
{
|
{
|
||||||
mbed_stack_isr_start = (unsigned char *) &__StackLimit;
|
mbed_stack_isr_start = (unsigned char *) &__StackLimit;
|
||||||
mbed_stack_isr_size = (uint32_t) &__StackTop - (uint32_t) &__StackLimit;
|
mbed_stack_isr_size = (uint32_t) &__StackTop - (uint32_t) &__StackLimit;
|
||||||
|
#if defined(MBED_SPLIT_HEAP)
|
||||||
|
mbed_heap_start = (unsigned char *) &__mbed_sbrk_start;
|
||||||
|
mbed_heap_size = (uint32_t) &__mbed_krbs_start - (uint32_t) &__mbed_sbrk_start;
|
||||||
|
mbed_heap_start_0 = (unsigned char *) &__mbed_sbrk_start_0;
|
||||||
|
mbed_heap_size_0 = (uint32_t) &__mbed_krbs_start_0 - (uint32_t) &__mbed_sbrk_start_0;
|
||||||
|
#else
|
||||||
mbed_heap_start = (unsigned char *) &__end__;
|
mbed_heap_start = (unsigned char *) &__end__;
|
||||||
mbed_heap_size = (uint32_t) &__HeapLimit - (uint32_t) &__end__;
|
mbed_heap_size = (uint32_t) &__HeapLimit - (uint32_t) &__end__;
|
||||||
|
#endif
|
||||||
|
|
||||||
mbed_init();
|
mbed_init();
|
||||||
mbed_rtos_start();
|
mbed_rtos_start();
|
||||||
|
|
|
@ -58,6 +58,11 @@ extern "C" {
|
||||||
extern unsigned char *mbed_heap_start;
|
extern unsigned char *mbed_heap_start;
|
||||||
extern uint32_t mbed_heap_size;
|
extern uint32_t mbed_heap_size;
|
||||||
|
|
||||||
|
#if defined(MBED_SPLIT_HEAP)
|
||||||
|
extern unsigned char *mbed_heap_start_0;
|
||||||
|
extern uint32_t mbed_heap_size_0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Stack limits */
|
/* Stack limits */
|
||||||
extern unsigned char *mbed_stack_isr_start;
|
extern unsigned char *mbed_stack_isr_start;
|
||||||
extern uint32_t mbed_stack_isr_size;
|
extern uint32_t mbed_stack_isr_size;
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
* - Value INITIAL_SP is ignored
|
* - Value INITIAL_SP is ignored
|
||||||
*
|
*
|
||||||
* GCC Memory layout :
|
* GCC Memory layout :
|
||||||
* - Heap explicitly placed in linker script (*.ld file) and heap start (__end___) and heap end (__HeapLimit) should be defined in linker script
|
* - Heap explicitly placed in linker script (*.ld file) and heap start (__end___) and heap end (__HeapLimit) should be defined in linker script (or __mbed_sbrk_start/__mbed_sbrk_start_0 and __mbed_krbs_start/__mbed_krbs_start_0 for split heap targets)
|
||||||
* - Interrupt stack placed in linker script **.ld file) and stack start (__StackTop) and stack end (__StackLimit) should be defined in linker script
|
* - Interrupt stack placed in linker script **.ld file) and stack start (__StackTop) and stack end (__StackLimit) should be defined in linker script
|
||||||
*
|
*
|
||||||
* ARM Memory layout :
|
* ARM Memory layout :
|
||||||
|
|
|
@ -120,6 +120,11 @@ extern const char __stderr_name[] = "/stderr";
|
||||||
unsigned char *mbed_heap_start = 0;
|
unsigned char *mbed_heap_start = 0;
|
||||||
uint32_t mbed_heap_size = 0;
|
uint32_t mbed_heap_size = 0;
|
||||||
|
|
||||||
|
#if defined(MBED_SPLIT_HEAP)
|
||||||
|
unsigned char *mbed_heap_start_0 = 0;
|
||||||
|
uint32_t mbed_heap_size_0 = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||||
|
|
||||||
/* newlib has the filehandle field in the FILE struct as a short, so
|
/* newlib has the filehandle field in the FILE struct as a short, so
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "mbed_error.h"
|
#include "mbed_error.h"
|
||||||
#include "mbed_toolchain.h"
|
#include "mbed_toolchain.h"
|
||||||
|
#include "mbed_boot.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "cmsis.h"
|
#include "cmsis.h"
|
||||||
|
@ -28,10 +29,6 @@
|
||||||
*/
|
*/
|
||||||
#if !defined(MBED_CONF_RTOS_PRESENT)
|
#if !defined(MBED_CONF_RTOS_PRESENT)
|
||||||
|
|
||||||
/* Heap limits - only used if set */
|
|
||||||
extern unsigned char *mbed_heap_start;
|
|
||||||
extern uint32_t mbed_heap_size;
|
|
||||||
|
|
||||||
/* Stack limits */
|
/* Stack limits */
|
||||||
unsigned char *mbed_stack_isr_start = 0;
|
unsigned char *mbed_stack_isr_start = 0;
|
||||||
uint32_t mbed_stack_isr_size = 0;
|
uint32_t mbed_stack_isr_size = 0;
|
||||||
|
@ -154,8 +151,16 @@ const uint32_t os_cb_sections[] __attribute__((section(".rodata"))) = {};
|
||||||
|
|
||||||
extern uint32_t __StackLimit;
|
extern uint32_t __StackLimit;
|
||||||
extern uint32_t __StackTop;
|
extern uint32_t __StackTop;
|
||||||
|
|
||||||
|
#if defined(MBED_SPLIT_HEAP)
|
||||||
|
extern uint32_t __mbed_sbrk_start;
|
||||||
|
extern uint32_t __mbed_krbs_start;
|
||||||
|
extern uint32_t __mbed_sbrk_start_0;
|
||||||
|
extern uint32_t __mbed_krbs_start_0;
|
||||||
|
#else
|
||||||
extern uint32_t __end__;
|
extern uint32_t __end__;
|
||||||
extern uint32_t __HeapLimit;
|
extern uint32_t __HeapLimit;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int __real_main(void);
|
extern int __real_main(void);
|
||||||
|
|
||||||
|
@ -163,8 +168,16 @@ void software_init_hook(void)
|
||||||
{
|
{
|
||||||
mbed_stack_isr_start = (unsigned char *) &__StackLimit;
|
mbed_stack_isr_start = (unsigned char *) &__StackLimit;
|
||||||
mbed_stack_isr_size = (uint32_t) &__StackTop - (uint32_t) &__StackLimit;
|
mbed_stack_isr_size = (uint32_t) &__StackTop - (uint32_t) &__StackLimit;
|
||||||
|
|
||||||
|
#if defined(MBED_SPLIT_HEAP)
|
||||||
|
mbed_heap_start = (unsigned char *) &__mbed_sbrk_start;
|
||||||
|
mbed_heap_size = (uint32_t) &__mbed_krbs_start - (uint32_t) &__mbed_sbrk_start;
|
||||||
|
mbed_heap_start_0 = (unsigned char *) &__mbed_sbrk_start_0;
|
||||||
|
mbed_heap_size_0 = (uint32_t) &__mbed_krbs_start_0 - (uint32_t) &__mbed_sbrk_start_0;
|
||||||
|
#else
|
||||||
mbed_heap_start = (unsigned char *) &__end__;
|
mbed_heap_start = (unsigned char *) &__end__;
|
||||||
mbed_heap_size = (uint32_t) &__HeapLimit - (uint32_t) &__end__;
|
mbed_heap_size = (uint32_t) &__HeapLimit - (uint32_t) &__end__;
|
||||||
|
#endif
|
||||||
|
|
||||||
mbed_init();
|
mbed_init();
|
||||||
software_init_hook_rtos();
|
software_init_hook_rtos();
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "greentea-client/test_env.h"
|
#include "greentea-client/test_env.h"
|
||||||
#include "utest/utest.h"
|
#include "utest/utest.h"
|
||||||
#include "unity/unity.h"
|
#include "unity/unity.h"
|
||||||
|
#include "mbed_boot.h"
|
||||||
|
|
||||||
using utest::v1::Case;
|
using utest::v1::Case;
|
||||||
|
|
||||||
|
@ -39,18 +40,9 @@ static const int test_timeout = 30;
|
||||||
// Malloc fill pattern
|
// Malloc fill pattern
|
||||||
#define MALLOC_FILL 0x55
|
#define MALLOC_FILL 0x55
|
||||||
|
|
||||||
extern unsigned char *mbed_heap_start;
|
|
||||||
extern uint32_t mbed_heap_size;
|
|
||||||
extern unsigned char *mbed_stack_isr_start;
|
extern unsigned char *mbed_stack_isr_start;
|
||||||
extern uint32_t mbed_stack_isr_size;
|
extern uint32_t mbed_stack_isr_size;
|
||||||
|
|
||||||
#if defined(TOOLCHAIN_GCC_ARM) && defined(MBED_SPLIT_HEAP)
|
|
||||||
extern uint32_t __mbed_sbrk_start_0;
|
|
||||||
extern uint32_t __mbed_krbs_start_0;
|
|
||||||
unsigned char *mbed_heap_start_0 = (unsigned char *) &__mbed_sbrk_start_0;;
|
|
||||||
uint32_t mbed_heap_size_0 = (uint32_t) &__mbed_krbs_start_0 - (uint32_t) &__mbed_sbrk_start_0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct linked_list {
|
struct linked_list {
|
||||||
linked_list *next;
|
linked_list *next;
|
||||||
uint8_t data[MALLOC_TEST_SIZE];
|
uint8_t data[MALLOC_TEST_SIZE];
|
||||||
|
|
|
@ -187,15 +187,14 @@ SECTIONS
|
||||||
_ebss = .;
|
_ebss = .;
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
.heap (COPY):
|
/* Check if data + stack will exceed SRAM limit */
|
||||||
|
ASSERT(_ebss < ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE, "region SRAM does not have enough space for boot stack size")
|
||||||
|
|
||||||
|
.heap_0 (NOLOAD):
|
||||||
{
|
{
|
||||||
__end__ = .;
|
PROVIDE(__mbed_sbrk_start_0 = .);
|
||||||
PROVIDE(end = .);
|
|
||||||
PROVIDE(__mbed_sbrk_start = .);
|
|
||||||
*(.heap*)
|
|
||||||
. = ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
. = ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__mbed_krbs_start = .);
|
PROVIDE(__mbed_krbs_start_0 = .);
|
||||||
__HeapLimit = .;
|
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
@ -213,9 +212,6 @@ SECTIONS
|
||||||
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__stack = __StackTop);
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds SRAM limit */
|
|
||||||
ASSERT(__StackLimit >= __HeapLimit, "region SRAM overflowed with stack")
|
|
||||||
|
|
||||||
/* Ethernet DMA descriptors should be at the start of SRAM_D2 because they need an MPU region
|
/* Ethernet DMA descriptors should be at the start of SRAM_D2 because they need an MPU region
|
||||||
and because the CM4 and CM7 have to agree on their location.*/
|
and because the CM4 and CM7 have to agree on their location.*/
|
||||||
.eth_descriptors (NOLOAD) : {
|
.eth_descriptors (NOLOAD) : {
|
||||||
|
@ -230,11 +226,11 @@ SECTIONS
|
||||||
*(.EthBuffers)
|
*(.EthBuffers)
|
||||||
} >SRAM_D2
|
} >SRAM_D2
|
||||||
|
|
||||||
/* Use the rest of DTCM as additional heap */
|
/* Use SRAM_D2 as additional heap */
|
||||||
.heap_0 (COPY):
|
.heap (NOLOAD):
|
||||||
{
|
{
|
||||||
PROVIDE(__mbed_sbrk_start_0 = .);
|
PROVIDE(__mbed_sbrk_start = .);
|
||||||
. += (ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC) - .);
|
. += (ORIGIN(SRAM_D2) + LENGTH(SRAM_D2) - .);
|
||||||
PROVIDE(__mbed_krbs_start_0 = .);
|
PROVIDE(__mbed_krbs_start = .);
|
||||||
} > SRAM_DTC
|
} > SRAM_D2
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,14 +182,15 @@ SECTIONS
|
||||||
_ebss = .;
|
_ebss = .;
|
||||||
} > SRAM_D2
|
} > SRAM_D2
|
||||||
|
|
||||||
|
/* Check if data + stack will exceed SRAM limit */
|
||||||
|
ASSERT(_ebss < ORIGIN(SRAM_D2) + LENGTH(SRAM_D2) - MBED_CONF_TARGET_BOOT_STACK_SIZE, "region SRAM does not have enough space for boot stack size")
|
||||||
|
|
||||||
.heap (COPY):
|
.heap (COPY):
|
||||||
{
|
{
|
||||||
__end__ = .;
|
__end__ = .;
|
||||||
PROVIDE(end = .);
|
PROVIDE(end = .);
|
||||||
PROVIDE(__mbed_sbrk_start = .);
|
|
||||||
*(.heap*)
|
*(.heap*)
|
||||||
. = ORIGIN(SRAM_D2) + LENGTH(SRAM_D2) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
. = ORIGIN(SRAM_D2) + LENGTH(SRAM_D2) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__mbed_krbs_start = .);
|
|
||||||
__HeapLimit = .;
|
__HeapLimit = .;
|
||||||
} > SRAM_D2
|
} > SRAM_D2
|
||||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
@ -207,9 +208,6 @@ SECTIONS
|
||||||
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__stack = __StackTop);
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds SRAM_D2 limit */
|
|
||||||
ASSERT(__StackLimit >= __HeapLimit, "region SRAM_D2 overflowed with stack")
|
|
||||||
|
|
||||||
/* Put crash data in the otherwise unused D3 SRAM */
|
/* Put crash data in the otherwise unused D3 SRAM */
|
||||||
.crash_data_ram :
|
.crash_data_ram :
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,14 +174,14 @@ SECTIONS
|
||||||
_ebss = .;
|
_ebss = .;
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
|
/* Check if data + stack will exceed SRAM limit */
|
||||||
|
ASSERT(_ebss < ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE, "region SRAM does not have enough space for boot stack size")
|
||||||
|
|
||||||
.heap (COPY):
|
.heap (COPY):
|
||||||
{
|
{
|
||||||
__end__ = .;
|
__end__ = .;
|
||||||
PROVIDE(end = .);
|
PROVIDE(end = .);
|
||||||
PROVIDE(__mbed_sbrk_start = .);
|
|
||||||
*(.heap*)
|
|
||||||
. = ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
. = ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__mbed_krbs_start = .);
|
|
||||||
__HeapLimit = .;
|
__HeapLimit = .;
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
|
@ -230,12 +230,4 @@ SECTIONS
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
__CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
|
__CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
|
||||||
} > SRAM_D3
|
} > SRAM_D3
|
||||||
|
|
||||||
/* Use the rest of DTCM as additional heap */
|
|
||||||
.heap_0 (COPY):
|
|
||||||
{
|
|
||||||
PROVIDE(__mbed_sbrk_start_0 = .);
|
|
||||||
. += (ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC) - .);
|
|
||||||
PROVIDE(__mbed_krbs_start_0 = .);
|
|
||||||
} > SRAM_DTC
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,15 +174,14 @@ SECTIONS
|
||||||
_ebss = .;
|
_ebss = .;
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
.heap (COPY):
|
/* Check if data + stack will exceed SRAM limit */
|
||||||
|
ASSERT(_ebss < ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE, "region SRAM does not have enough space for boot stack size")
|
||||||
|
|
||||||
|
.heap_0 (NOLOAD):
|
||||||
{
|
{
|
||||||
__end__ = .;
|
PROVIDE(__mbed_sbrk_start_0 = .);
|
||||||
PROVIDE(end = .);
|
|
||||||
PROVIDE(__mbed_sbrk_start = .);
|
|
||||||
*(.heap*)
|
|
||||||
. = ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
. = ORIGIN(SRAM) + LENGTH(SRAM) - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__mbed_krbs_start = .);
|
PROVIDE(__mbed_krbs_start_0 = .);
|
||||||
__HeapLimit = .;
|
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
@ -200,9 +199,6 @@ SECTIONS
|
||||||
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
__StackLimit = __StackTop - MBED_CONF_TARGET_BOOT_STACK_SIZE;
|
||||||
PROVIDE(__stack = __StackTop);
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
/* Check if data + heap + stack exceeds SRAM limit */
|
|
||||||
ASSERT(__StackLimit >= __HeapLimit, "region SRAM overflowed with stack")
|
|
||||||
|
|
||||||
/* Put crash data in the otherwise unused D3 SRAM */
|
/* Put crash data in the otherwise unused D3 SRAM */
|
||||||
.crash_data_ram :
|
.crash_data_ram :
|
||||||
{
|
{
|
||||||
|
@ -229,11 +225,11 @@ SECTIONS
|
||||||
*(.EthBuffers)
|
*(.EthBuffers)
|
||||||
} >SRAM_AXI
|
} >SRAM_AXI
|
||||||
|
|
||||||
/* Use the rest of DTCM as additional heap */
|
/* Use SRAM_AXI as additional heap */
|
||||||
.heap_0 (COPY):
|
.heap (NOLOAD):
|
||||||
{
|
{
|
||||||
PROVIDE(__mbed_sbrk_start_0 = .);
|
PROVIDE(__mbed_sbrk_start = .);
|
||||||
. += (ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC) - .);
|
. += (ORIGIN(SRAM_AXI) + LENGTH(SRAM_AXI) - .);
|
||||||
PROVIDE(__mbed_krbs_start_0 = .);
|
PROVIDE(__mbed_krbs_start = .);
|
||||||
} > SRAM_DTC
|
} > SRAM_AXI
|
||||||
}
|
}
|
||||||
|
|
|
@ -3455,8 +3455,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"macros_add": [
|
"macros_add": [
|
||||||
"CORE_CM7",
|
"CORE_CM7"
|
||||||
"MBED_SPLIT_HEAP"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"NUCLEO_H745ZI_Q": {
|
"NUCLEO_H745ZI_Q": {
|
||||||
|
@ -3522,8 +3521,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"macros_add": [
|
"macros_add": [
|
||||||
"CORE_CM7",
|
"CORE_CM7"
|
||||||
"MBED_SPLIT_HEAP"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"MCU_STM32H747xI_CM4": {
|
"MCU_STM32H747xI_CM4": {
|
||||||
|
|
Loading…
Reference in New Issue