Macro MBED_ALIGN expands in C to _Alignas which can't be used in the
type declaration. This patch moves it to the first type definition
which makes this code compile properly in CPP and C.
The test case for multithreaded erase/program/read allocates a few
Thread objects from the heap and starts them. It has a few problems:
* To check that there will be enough heap to start a new thread, the
test case tries to allocate a dummy buffer of the thread's heap size
and then frees it, before starting the thread. Then the thread will
allocate its own stack. Such check is not reliable, because threads
that are already running also perform additional allocation (when
running `test_thread_job()`) and may take away the memory we just
checked.
* When deleting all threads in a loop, the loop boundary misses the
last thread if the last thread object was allocated but not started
(i.e. due to failed thread stack allocation check).
To fix the issues
* Start a thread without any allocation test. Following the preceding
commit "rtos: Thread: Make stack allocation failure runtime catchable",
`Thread::start()` now returns `osErrorNoMemory` if stack allocation
fails which we can handle.
* Store pointers to all threads in a zero-initialized array, and
free all elements at the end of the test.
When a Thread object's stack memory is not provided, its `start()`
member function dynamically allocates its stack from the heap. If
allocation fails, there is no way to catch it because
* `std::nothrow` is missing after the `new` keyword. As Mbed OS
is built with `-fno-exceptions` (C++ exceptions disabled), failed
allocation results in an unrecoverable fault.
* The attempted `nullptr` check, which doesn't work anyway due to
the first point, is an assertion instead of error returning.
Assertions should be used as a development tool to ensure code
behaves correctly. But out-of-memory is a completely valid runtime
situation.
This commit adds the missing `std::nothrow`, and makes `Thread::start()`
return `osErrorNoMemory` if allocation fails so the caller can handle
it.
Note: A case when a thread should never fail due to lack of memory
is the main thread. But the main thread's stack is a pre-allocated
array in the static memory, passed to the `Thread()` constructor
during thread creation, so it's not impacted by this change.
This patch contains improvements mentioned in the unresolved PR
comments:
- function names were changed from socket_sendmsg/socket_recvmsg to
socket_sendto_control/socket_recvfrom_control.
- default implementation of this functions was provided in the
NetworkStack class.
- MsgHeaderIterator accesses elements on the aligned addresses.
Change MCUboot image versioning to meet requirements below:
1. Major.Minor.Revision must be non-decremental when used to derive security counter (-s 'auto').
2. Make Major.Minor.Revision+Build incremental to identify the firmware itself through psa_fwu_query().
3. Get around MCUboot failure with TF-M underestimated MAX_BOOT_RECORD_SZ
Import mcu partition header (renamed to partition_M2354_im.h) for resolving peripheral base with security.
Though Mbed is non-secure only and needn't secure peripheral base, some BSP driver code still rely on it.
`HAL_SPI_Receive_IT` HAL function causes dummy reads in 3-wire mode,
that causes data corruption in RX FIFO/register. It isn't possible
to fix it without signification refactoring, but we may prevent data
corruption with the following fixes:
- RX buffer/register cleanup after asynchronous transfer in 3-wire mode
- Explicit RX buffer/register cleanup after SPI initialization
(for cases if we re-create SPI object).
All STM32 families except STM32H7 has the following 3-wire SPI peculiarity in master receive mode:
SPI continuously generates clock signal till it's disabled by a software. It causes that a software
must disable SPI in time. Otherwise, "dummy" reads will be generated.
Current STM32 synchronous SPI 3-wire implementation relies on HAL library functions HAL_SPI_Receive/HAL_SPI_Transmit.
It performs some SPI state checks to detect errors, but unfortunately it isn't fast enough to disable SPI in time.
Additionally, a multithreading environment or interrupt events may cause extra delays.
This commit contains the custom transmit/receive function for SPI 3-wire mode. It uses critical sections to
prevents accidental interrupt event delays, disables SPI after each frame receiving and disables SPI during
frame generation. It adds some delay between SPI frames (~700 ns), but gives reliable 3-wire SPI communications.
- move a code that waits readable SPI state from `spi_master_write`
function to inline functions `msp_writable` and `msp_wait_writable`
- move a code that waits writeable SPI state from `spi_master_write`
function to inline functions `msp_readable` and `msp_wait_readable`
- move a code that writes data to SPI from `spi_master_write`
function to inline function `msp_write_data`
- move a code that reads data from SPI from `spi_master_write`
function to inline function `msp_read_data`
This reverts commit 6649e95106.
In the malloc test, `ALLOC_ARRAY_SIZE` defines the *capacity* of array
that stores pointers to `malloc`'d buffers. It is *not* the number
of allocations.
In an ideal scenario, the test makes as many allocations as possible
until the heap runs out and malloc() returns NULL. So revert the
capacity of the array of pointers from 50 back to 100 so this array
is less likely to run out before the heap does.
The commit 84d0689 "Nano-malloc: Fix for unwanted external heap
fragmentation" from newlib 4.1.0 introduced several optimizations,
one of which is as follows:
When the last chunk in the free list is smaller than requested,
nano_malloc() calls sbrk(0) to see if the heap's current head is
adjacent to this chunk, and if so it asks sbrk() to allocate the
difference in bytes only and expands the current chunk.
This doesn't work if the heap consists of non-contiguous regions.
sbrk(0) returns the the current region's head if the region has any
remaining capacity. But if this capacity is not enough for the second
(non-trivial) call to sbrk() described above, allocation will happen
from the next region if available. Expanding the current chunk won't
work and will result in a segmentation fault.
So this optimization needs to be reverted in order to bring back
compatibility with non-contiguous heaps. Before the next version
of newlib becomes available and gets updated in the GCC Arm Embedded
Toolchain, we work around this issue by including the fix in Mbed OS.
The linker prioritizes malloc() from the project to the one from the
toolchain.