This is not strictly needed in order for #1056 to be resolved,
because the "make long-lived" machinery is unaware of this pointer.
However, as UARTs are assumed to be long-lived, this change is
beneficial because it moves the long-lived buffer into the upper
memory area with other long-lived objects, instead of remaining in
the low heap.
Particularly when they have buffers that are written via IRQ or DMA,
UART objects do not relocate gracefully. If such an object is
relocated to the long-lived pool after its original creation, the
IRQ or DMA will write to an unexpected location within the Python
heap, leading to a variety of symptoms. The most frequent symptom
is inability to read from the UART.
Consider the particular case of atmel-samd: usart_uart_obj_t
contains a usart_async_descriptor contains a _usart_async_device.
In _sercom_init_irq_param the address of this contained
_usart_async_device is assigned to a global array
sercom_to_sercom_dev which is later used from the interrupt context
_sercom_usart_interrupt_handler to store the received data in the
right ring buffer.
When the UART object is relocated to the long-lived heap, there's no
mechanism to re-point these internal pointers, so instead take the
cowardly way and allocate the UART object as long-lived.
Happily, almost all UART objects are likely to be long-lived, so
this is unlikely to have a negative effect on memory usage or heap
fragmentation.
Closes: #1056
Its slimmed down by removing the qstr and bit packing TCC info.
The trinket m0 build actually grows by 20 bytes. The arduino zero
build shrinks by 188 bytes.
This allows for the heap to fill all space but the stack. It also
allows us to designate space for memory outside the runtime for
things such as USB descriptors, flash cache and main filename.
Fixes#754