nrfcxx  0.1.0
C++-17 Framework for Nordic nRF5 Devices
Functions
system.h File Reference

NRFCXX system enhancements to newlib. More...

#include <stdbool.h>
#include <unistd.h>

Go to the source code of this file.

Functions

void * _nrfcxx_sbrk_fatal (ptrdiff_t increment)
 An sbrk() implementation that rejects any attempt to allocate memory dynamically. More...
 
void * _nrfcxx_sbrk_heap (ptrdiff_t increment)
 An sbrk() implementation that depends on a fixed heap allocated within the standard startup infrastructure. More...
 
void * _nrfcxx_sbrk_fixedstack (ptrdiff_t increment)
 An sbrk() implementation that allows heap (growing up) to grow to the bottom of a reserved stack region. More...
 
void * _nrfcxx_sbrk_dynstack (ptrdiff_t increment)
 An sbrk() implementation that allows heap (growing up) and stack (growing down) to share a region of memory. More...
 
void * _nrfcxx_sbrk_unlimitedstack (ptrdiff_t increment)
 An sbrk() implementation that allows heap (growing up) and stack (growing down) to share a region of memory, with a minimum size reserved for the stack but allowing for the stack to grow below that point. More...
 
void * _sbrk (intptr_t increment)
 The system function used to allocate memory for use by libc heap memory management. More...
 
void * _nrfcxx_sbrk_error (void *brk, ptrdiff_t current, ptrdiff_t increment)
 This function is invoked whenever _sbrk() runs out of memory. More...
 
bool _nrfcxx_cstdio_allowed (bool allowed)
 Function used to control whether the automatic enabling of UART to support stdio operations is supported. More...
 
size_t _nrfcxx_heap_used (void)
 Return the amount of heap memory currently in use within the system, in bytes.
 

Detailed Description

NRFCXX system enhancements to newlib.

This file declares functions that support the newlib nosys replacement used by default in nrfcxx.

Note
Several parts of newlib require support for allocation from the heap. If the stdio infrastructure is referenced normally, roughly 1468 bytes is allocated for state maintenance. If setvbuf(3) is used to disable buffering on stdio, this is reduced to about 436 bytes. In any case, selecting _nrfcxx_sbrk_fatal() will cause failures if some newlib functions are invoked, and reducing the default heap allocation in startup_CMx.S is risky.

Function Documentation

◆ _nrfcxx_cstdio_allowed()

bool _nrfcxx_cstdio_allowed ( bool  allowed)

Function used to control whether the automatic enabling of UART to support stdio operations is supported.

For convenience during development this feature is enabled by default, but having a UART running and active can complicate power and critical timing measurements. Invoking this function prior to any cstdio operations will inhibit starting the UART and cause all primitive I/O operations to return as though they did something.

Parameters
allowedif false will prevent any subsequent cstdio operations from enabling the UART.
Returns
true iff the UART had already been automatically enabled in support of cstdio operations.

◆ _nrfcxx_sbrk_dynstack()

void* _nrfcxx_sbrk_dynstack ( ptrdiff_t  increment)

An sbrk() implementation that allows heap (growing up) and stack (growing down) to share a region of memory.

An error is indicated if the new break point would encroach into the current stack space.

Note
Like _nrfcxx_sbrk_unlimited(), but eliminating the minimum reserved stack. Not sure why this would be worth doing, but for completeness....

◆ _nrfcxx_sbrk_error()

void* _nrfcxx_sbrk_error ( void *  brk,
ptrdiff_t  current,
ptrdiff_t  increment 
)

This function is invoked whenever _sbrk() runs out of memory.

libnrfcxx.a provides a weak definition that invokes nrfcxx::failsafe with nrfcxx::FailSafeCode::HEAP_OVERRUN. The application may provide an alternative implementation that is more diagnostic or that returns the responsibility of handling out-of-memory to the application (i.e. requires the application to check allocation return values).

Parameters
brkthe current program break
currenttotal number of bytes allocated by previous successful invocations of _sbrk() (i.e., allocated bytes preceding brk)
incrementthe number of bytes in the request that _sbrk() cannot satisfy
Returns
This function need not return. An implementation that does return must set errno to ENOMEM and return (void*)-1.

◆ _nrfcxx_sbrk_fatal()

void* _nrfcxx_sbrk_fatal ( ptrdiff_t  increment)

An sbrk() implementation that rejects any attempt to allocate memory dynamically.

This is not quite equivalent to _nrfcxx_sbrk_heap() with a zero-sized heap, as simply invoking _sbrk() will result in the failure even if the requested increment was zero.

Note
_nrfcxx_heap_used() invokes _sbrk with a zero increment. So does newlib prior to allocating for stdio support.

◆ _nrfcxx_sbrk_fixedstack()

void* _nrfcxx_sbrk_fixedstack ( ptrdiff_t  increment)

An sbrk() implementation that allows heap (growing up) to grow to the bottom of a reserved stack region.

An error is indicated if the new program break would encroach into the reserved stack space. There is no check against the current stack pointer.

Note
This policy is preferred to _nrfcxx_sbrk_unlimitedstack() when code may be executing in tasks where the stack frame is in previously allocated memory.

◆ _nrfcxx_sbrk_heap()

void* _nrfcxx_sbrk_heap ( ptrdiff_t  increment)

An sbrk() implementation that depends on a fixed heap allocated within the standard startup infrastructure.

An error is indicated if the reserved heap size would be exceeded. There is no check against the current stack pointer.

◆ _nrfcxx_sbrk_unlimitedstack()

void* _nrfcxx_sbrk_unlimitedstack ( ptrdiff_t  increment)

An sbrk() implementation that allows heap (growing up) and stack (growing down) to share a region of memory, with a minimum size reserved for the stack but allowing for the stack to grow below that point.

An error is indicated if the new break point would encroach into the reserved stack space or the currently used stack space.

◆ _sbrk()

void* _sbrk ( intptr_t  increment)

The system function used to allocate memory for use by libc heap memory management.

By default this symbol is a weak alias to _nrfcxx_sbrk_unlimitedstack(). This matches the nosys behavior of newlib. To select another policy you must provide a non-weak alias to one of the other policies or your own implementation. Alternative implementations include:

You can do this in the application main file with:

extern "C" {
void* _sbrk_for_app (ptrdiff_t increment)
{
  return _nrfcxx_sbrk_heap(increment);
}
void* _sbrk (ptrdiff_t increment) __attribute__((__alias__("_sbrk_for_app")));
}
Note
As of GCC 4 the alias must be defined in the same translation unit, hence the need for a local definition that wraps the provided function.

The reserved system stack space is 3 KiBy, which is sufficient for use with standard newlib operations. The application can increase this by declaring objects that will force that space to be expanded, as with:

__attribute__((__section__(".heap.extension")))
volatile uint32_t extend_by_512_words[512];
Note
All NRFCXX policies invoke _nrfcxx_sbrk_error() if allocation fails, allowing an application to control response to the failure.
Parameters
incrementthe number of bytes of additional memory that libc needs in order to perform additional allocations.
Returns
a pointer to the new end-of-memory, or (void*)-1 if no allocation can be performed.
See also
_nrfcxx_heap_used