New heap manager.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1221 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
8da7f367ee
commit
2c46df1916
|
@ -18,9 +18,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file src/templates/chconf.h
|
* @file templates/chconf.h
|
||||||
* @brief Configuration file template.
|
* @brief Configuration file template.
|
||||||
* @addtogroup Config
|
* @addtogroup config
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -32,29 +32,36 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frequency of the system timer that drives the system ticks. This also
|
* @brief System tick frequency.
|
||||||
* defines the system tick time unit.
|
* @details Frequency of the system timer that drives the system ticks. This
|
||||||
|
* setting also defines the system tick time unit.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
|
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
|
||||||
#define CH_FREQUENCY 1000
|
#define CH_FREQUENCY 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constant is the number of system ticks allowed for the threads before
|
* @brief Round robin interval.
|
||||||
* preemption occurs. This option is only meaningful if the option
|
* @details This constant is the number of system ticks allowed for the
|
||||||
* @p CH_USE_ROUNDROBIN is also active.
|
* threads before preemption occurs. Setting this value to zero
|
||||||
|
* disables the round robin mechanism.
|
||||||
|
*
|
||||||
|
* @note Disabling round robin makes the kernel more compact and generally
|
||||||
|
* faster but forbids multiple threads at the same priority level.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
||||||
#define CH_TIME_QUANTUM 20
|
#define CH_TIME_QUANTUM 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
|
* @brief Nested locks.
|
||||||
|
* @details If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
|
||||||
* operations is allowed.<br>
|
* operations is allowed.<br>
|
||||||
* For performance and code size reasons the recommended setting is to leave
|
* For performance and code size reasons the recommended setting
|
||||||
* this option disabled.<br>
|
* is to leave this option disabled.<br>
|
||||||
* You can use this option if you need to merge ChibiOS/RT with external
|
* You may use this option if you need to merge ChibiOS/RT with
|
||||||
* libraries that require nested lock/unlock operations.
|
* external libraries that require nested lock/unlock operations.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
|
||||||
|
@ -62,23 +69,18 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the kernel performs the round robin scheduling algorithm
|
* @brief Managed RAM size.
|
||||||
* on threads of equal priority.
|
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||||
* @note The default is @p TRUE.
|
* then the whole available RAM is used. The core memory is made
|
||||||
*/
|
* available to the heap allocator and/or can be used directly through
|
||||||
#if !defined(CH_USE_ROUNDROBIN) || defined(__DOXYGEN__)
|
* the simplified core memory allocator.
|
||||||
#define CH_USE_ROUNDROBIN TRUE
|
*
|
||||||
#endif
|
* @note In order to let the OS manage the whole RAM the linker script must
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of RAM bytes to use as system heap. If set to zero then the whole
|
|
||||||
* available RAM is used as system heap.
|
|
||||||
* @note In order to use the whole RAM as system heap the linker script must
|
|
||||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||||
* @note Requires @p CH_USE_HEAP.
|
* @note Requires @p CH_USE_COREMEM.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_HEAP_SIZE) || defined(__DOXYGEN__)
|
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
|
||||||
#define CH_HEAP_SIZE 0
|
#define CH_MEMCORE_SIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -86,8 +88,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then time efficient rather than space efficient code is used
|
* @brief OS optimization.
|
||||||
* when two possible implementations exist.
|
* @details If enabled then time efficient rather than space efficient code
|
||||||
|
* is used when two possible implementations exist.
|
||||||
|
*
|
||||||
* @note This is not related to the compiler optimization options.
|
* @note This is not related to the compiler optimization options.
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
|
@ -96,18 +100,20 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled defines a CPU register to be used as storage for the global
|
* @brief Exotic optimization.
|
||||||
* @p currp variable. Caching this variable in a register can greatly
|
* @details If defined then a CPU register is used as storage for the global
|
||||||
* improve both space and time efficiency of the generated code. Another side
|
* @p currp variable. Caching this variable in a register greatly
|
||||||
* effect is that one less register has to be saved during the context switch
|
* improves both space and time OS efficiency. A side effect is that
|
||||||
* resulting in lower RAM usage and faster code.
|
* one less register has to be saved during the context switch
|
||||||
|
* resulting in lower RAM usage and faster context switch.
|
||||||
|
*
|
||||||
* @note This option is only usable with the GCC compiler and is only useful
|
* @note This option is only usable with the GCC compiler and is only useful
|
||||||
* on processors with many registers like ARM cores.
|
* on processors with many registers like ARM cores.
|
||||||
* @note If this option is enabled then ALL the libraries linked to the
|
* @note If this option is enabled then ALL the libraries linked to the
|
||||||
* ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
|
* ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
|
||||||
* -ffixed-@<reg@>.
|
* -ffixed-@<reg@>.
|
||||||
* @note This option must be enabled in the Makefile, it is listed here for
|
* @note This option must be enabled in the Makefile, it is listed here for
|
||||||
* documentation.
|
* documentation only.
|
||||||
*/
|
*/
|
||||||
#if defined(__DOXYGEN__)
|
#if defined(__DOXYGEN__)
|
||||||
#define CH_CURRP_REGISTER_CACHE "reg"
|
#define CH_CURRP_REGISTER_CACHE "reg"
|
||||||
|
@ -118,7 +124,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the @p chThdWait() function is included in the kernel.
|
* @brief Threads synchronization APIs.
|
||||||
|
* @details If enabled then the @p chThdWait() function is included in
|
||||||
|
* the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
|
||||||
|
@ -126,7 +135,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Semaphores APIs are included in the kernel.
|
* @brief Semaphores APIs.
|
||||||
|
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
@ -134,8 +145,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then the threads are enqueued on semaphores by priority rather
|
* @brief Semaphores queuing mode.
|
||||||
* than FIFO order.
|
* @details If enabled then the threads are enqueued on semaphores by
|
||||||
|
* priority rather than in FIFO order.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE. Enable this if you have special requirements.
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -144,8 +157,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Semaphores the @p chSemWaitSignal() API is included
|
* @brief Atomic semaphore API.
|
||||||
* in the kernel.
|
* @details If enabled then the semaphores the @p chSemWaitSignal() API
|
||||||
|
* is included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -154,7 +169,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Mutexes APIs are included in the kernel.
|
* @brief Mutexes APIs.
|
||||||
|
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
||||||
|
@ -162,7 +179,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Conditional Variables APIs are included in the kernel.
|
* @brief Conditional Variables APIs.
|
||||||
|
* @details If enabled then the conditional variables APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_MUTEXES.
|
* @note Requires @p CH_USE_MUTEXES.
|
||||||
*/
|
*/
|
||||||
|
@ -171,7 +191,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Conditional Variables APIs are included in the kernel.
|
* @brief Conditional Variables APIs with timeout.
|
||||||
|
* @details If enabled then the conditional variables APIs with timeout
|
||||||
|
* specification are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_CONDVARS.
|
* @note Requires @p CH_USE_CONDVARS.
|
||||||
*/
|
*/
|
||||||
|
@ -180,7 +203,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Event flags APIs are included in the kernel.
|
* @brief Events Flags APIs.
|
||||||
|
* @details If enabled then the event flags APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
|
||||||
|
@ -188,8 +213,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the @p chEvtWaitXXXTimeout() functions are included in
|
* @brief Events Flags APIs with timeout.
|
||||||
* the kernel.
|
* @details If enabled then the events APIs with timeout specification
|
||||||
|
* are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_EVENTS.
|
* @note Requires @p CH_USE_EVENTS.
|
||||||
*/
|
*/
|
||||||
|
@ -198,7 +225,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Synchronous Messages APIs are included in the kernel.
|
* @brief Synchronous Messages APIs.
|
||||||
|
* @details If enabled then the synchronous messages APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
@ -206,7 +236,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then messages are served by priority rather than in FIFO order.
|
* @brief Synchronous Messages queuing mode.
|
||||||
|
* @details If enabled then messages are served by priority rather than in
|
||||||
|
* FIFO order.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE. Enable this if you have special requirements.
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
* @note Requires @p CH_USE_MESSAGES.
|
* @note Requires @p CH_USE_MESSAGES.
|
||||||
*/
|
*/
|
||||||
|
@ -215,16 +248,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Asynchronous Messages (Mailboxes) APIs are included
|
* @brief Mailboxes APIs.
|
||||||
* in the kernel.
|
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||||
|
* included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
|
||||||
#define CH_USE_MAILBOXES TRUE
|
#define CH_USE_MAILBOXES TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the I/O queues APIs are included in the kernel.
|
* @brief I/O Queues APIs.
|
||||||
|
* @details If enabled then the I/O queues APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -233,9 +271,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the memory heap allocator APIs are included in the kernel.
|
* @brief Core Memory Manager APIs.
|
||||||
|
* @details If enabled then the core memory manager APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_MUTEXES or @p CH_USE_SEMAPHORES.
|
*/
|
||||||
|
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
#define CH_USE_MEMCORE TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Heap Allocator APIs.
|
||||||
|
* @details If enabled then the memory heap allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_USE_COREMEM and either @p CH_USE_MUTEXES or
|
||||||
|
* @p CH_USE_SEMAPHORES.
|
||||||
* @note Mutexes are recommended.
|
* @note Mutexes are recommended.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
@ -243,18 +296,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled enforces the use of the C-runtime @p malloc() and @p free()
|
* @brief C-runtime allocator.
|
||||||
* functions as backend for the system heap allocator.
|
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
||||||
|
* @p malloc() and @p free() functions.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
* @note Requires @p CH_USE_HEAP.
|
* @note Requires @p CH_USE_HEAP.
|
||||||
|
* @note The C-runtime may or may not require @p CH_USE_COREMEM, see the
|
||||||
|
* appropriate documentation.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
||||||
#define CH_USE_MALLOC_HEAP FALSE
|
#define CH_USE_MALLOC_HEAP FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the memory pools allocator APIs are included in the
|
* @brief Memory Pools Allocator APIs.
|
||||||
* kernel.
|
* @details If enabled then the memory pools allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||||
|
@ -262,8 +321,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the dynamic threads creation APIs are included in the
|
* @brief Dynamic Threads APIs.
|
||||||
* kernel.
|
* @details If enabled then the dynamic threads creation APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_WAITEXIT.
|
* @note Requires @p CH_USE_WAITEXIT.
|
||||||
*/
|
*/
|
||||||
|
@ -276,8 +337,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled then the checks on the API functions input
|
* @brief Debug option, parameters checks.
|
||||||
|
* @details If enabled then the checks on the API functions input
|
||||||
* parameters are activated.
|
* parameters are activated.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||||
|
@ -285,9 +348,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled then all the assertions in the kernel code are
|
* @brief Debug option, consistency checks.
|
||||||
* activated. This includes consistency checks inside the kernel, runtime
|
* @details If enabled then all the assertions in the kernel code are
|
||||||
* anomalies and port-defined checks.
|
* activated. This includes consistency checks inside the kernel,
|
||||||
|
* runtime anomalies and port-defined checks.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||||
|
@ -295,8 +360,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled the context switch circular trace buffer is
|
* @brief Debug option, trace buffer.
|
||||||
|
* @details If enabled then the context switch circular trace buffer is
|
||||||
* activated.
|
* activated.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||||
|
@ -304,25 +371,37 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled a runtime stack check is performed.
|
* @brief Debug option, stack checks.
|
||||||
|
* @details If enabled then a runtime stack check is performed.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
* @note The stack check is performed in a architecture/port dependent way. It
|
* @note The stack check is performed in a architecture/port dependent way. It
|
||||||
* may not be implemented at all.
|
* may not be implemented or some ports.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled the threads working area is filled with a byte
|
* @brief Debug option, stacks initialization.
|
||||||
* pattern when a thread is created.
|
* @details If enabled then the threads working area is filled with a byte
|
||||||
|
* value when a thread is created. This can be useful for the
|
||||||
|
* runtime measurement of the used stack.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_FILL_THREADS FALSE
|
#define CH_DBG_FILL_THREADS FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled a field is added to the @p Thread structure that
|
* @brief Debug option, threads profiling.
|
||||||
|
* @details If enabled then a field is added to the @p Thread structure that
|
||||||
* counts the system ticks occurred while executing the thread.
|
* counts the system ticks occurred while executing the thread.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note This debug option is defaulted to TRUE because it is required by
|
||||||
|
* some test cases into the test suite.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_THREADS_PROFILING TRUE
|
#define CH_DBG_THREADS_PROFILING TRUE
|
||||||
|
@ -333,38 +412,46 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User fields added to the end of the @p Thread structure.
|
* @brief Threads descriptor structure hook.
|
||||||
|
* @details User fields added to the end of the @p Thread structure.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_FIELDS \
|
#define THREAD_EXT_FIELDS \
|
||||||
struct { \
|
struct { \
|
||||||
/* Add thread custom fields here.*/ \
|
/* Add threads custom fields here.*/ \
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User initialization code added to the @p chThdInit() API.
|
* @brief Threads initialization hook.
|
||||||
* @note It is invoked from within @p chThdInit().
|
* @details User initialization code added to the @p chThdInit() API.
|
||||||
|
*
|
||||||
|
* @note It is invoked from within @p chThdInit() and implicitily from all
|
||||||
|
* the threads creation APIs.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_INIT(tp) { \
|
#define THREAD_EXT_INIT(tp) { \
|
||||||
/* Add thread initialization code here.*/ \
|
/* Add threads initialization code here.*/ \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User finalization code added to the @p chThdExit() API.
|
* @brief Threads finalization hook.
|
||||||
|
* @details User finalization code added to the @p chThdExit() API.
|
||||||
|
*
|
||||||
* @note It is inserted into lock zone.
|
* @note It is inserted into lock zone.
|
||||||
|
* @note It is also invoked when the threads simply return in order to
|
||||||
|
* terminate.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_EXIT(tp) { \
|
#define THREAD_EXT_EXIT(tp) { \
|
||||||
/* Add thread finalization code here.*/ \
|
/* Add threads finalization code here.*/ \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code inserted inside the idle thread loop immediately after an interrupt
|
* @brief Idle Loop hook.
|
||||||
* resumed execution.
|
* @details This hook is continuously invoked by the idle thread loop.
|
||||||
*/
|
*/
|
||||||
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
||||||
#define IDLE_LOOP_HOOK() { \
|
#define IDLE_LOOP_HOOK() { \
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file src/templates/chconf.h
|
* @file templates/chconf.h
|
||||||
* @brief Configuration file template.
|
* @brief Configuration file template.
|
||||||
* @addtogroup Config
|
* @addtogroup config
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -32,29 +32,36 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frequency of the system timer that drives the system ticks. This also
|
* @brief System tick frequency.
|
||||||
* defines the system tick time unit.
|
* @details Frequency of the system timer that drives the system ticks. This
|
||||||
|
* setting also defines the system tick time unit.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
|
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
|
||||||
#define CH_FREQUENCY 1000
|
#define CH_FREQUENCY 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constant is the number of system ticks allowed for the threads before
|
* @brief Round robin interval.
|
||||||
* preemption occurs. This option is only meaningful if the option
|
* @details This constant is the number of system ticks allowed for the
|
||||||
* @p CH_USE_ROUNDROBIN is also active.
|
* threads before preemption occurs. Setting this value to zero
|
||||||
|
* disables the round robin mechanism.
|
||||||
|
*
|
||||||
|
* @note Disabling round robin makes the kernel more compact and generally
|
||||||
|
* faster but forbids multiple threads at the same priority level.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
||||||
#define CH_TIME_QUANTUM 20
|
#define CH_TIME_QUANTUM 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
|
* @brief Nested locks.
|
||||||
|
* @details If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
|
||||||
* operations is allowed.<br>
|
* operations is allowed.<br>
|
||||||
* For performance and code size reasons the recommended setting is to leave
|
* For performance and code size reasons the recommended setting
|
||||||
* this option disabled.<br>
|
* is to leave this option disabled.<br>
|
||||||
* You can use this option if you need to merge ChibiOS/RT with external
|
* You may use this option if you need to merge ChibiOS/RT with
|
||||||
* libraries that require nested lock/unlock operations.
|
* external libraries that require nested lock/unlock operations.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
|
||||||
|
@ -62,23 +69,18 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the kernel performs the round robin scheduling algorithm
|
* @brief Managed RAM size.
|
||||||
* on threads of equal priority.
|
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||||
* @note The default is @p TRUE.
|
* then the whole available RAM is used. The core memory is made
|
||||||
*/
|
* available to the heap allocator and/or can be used directly through
|
||||||
#if !defined(CH_USE_ROUNDROBIN) || defined(__DOXYGEN__)
|
* the simplified core memory allocator.
|
||||||
#define CH_USE_ROUNDROBIN TRUE
|
*
|
||||||
#endif
|
* @note In order to let the OS manage the whole RAM the linker script must
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of RAM bytes to use as system heap. If set to zero then the whole
|
|
||||||
* available RAM is used as system heap.
|
|
||||||
* @note In order to use the whole RAM as system heap the linker script must
|
|
||||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||||
* @note Requires @p CH_USE_HEAP.
|
* @note Requires @p CH_USE_COREMEM.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_HEAP_SIZE) || defined(__DOXYGEN__)
|
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
|
||||||
#define CH_HEAP_SIZE 0
|
#define CH_MEMCORE_SIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -86,8 +88,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then time efficient rather than space efficient code is used
|
* @brief OS optimization.
|
||||||
* when two possible implementations exist.
|
* @details If enabled then time efficient rather than space efficient code
|
||||||
|
* is used when two possible implementations exist.
|
||||||
|
*
|
||||||
* @note This is not related to the compiler optimization options.
|
* @note This is not related to the compiler optimization options.
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
|
@ -96,18 +100,20 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled defines a CPU register to be used as storage for the global
|
* @brief Exotic optimization.
|
||||||
* @p currp variable. Caching this variable in a register can greatly
|
* @details If defined then a CPU register is used as storage for the global
|
||||||
* improve both space and time efficiency of the generated code. Another side
|
* @p currp variable. Caching this variable in a register greatly
|
||||||
* effect is that one less register has to be saved during the context switch
|
* improves both space and time OS efficiency. A side effect is that
|
||||||
* resulting in lower RAM usage and faster code.
|
* one less register has to be saved during the context switch
|
||||||
|
* resulting in lower RAM usage and faster context switch.
|
||||||
|
*
|
||||||
* @note This option is only usable with the GCC compiler and is only useful
|
* @note This option is only usable with the GCC compiler and is only useful
|
||||||
* on processors with many registers like ARM cores.
|
* on processors with many registers like ARM cores.
|
||||||
* @note If this option is enabled then ALL the libraries linked to the
|
* @note If this option is enabled then ALL the libraries linked to the
|
||||||
* ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
|
* ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
|
||||||
* -ffixed-@<reg@>.
|
* -ffixed-@<reg@>.
|
||||||
* @note This option must be enabled in the Makefile, it is listed here for
|
* @note This option must be enabled in the Makefile, it is listed here for
|
||||||
* documentation.
|
* documentation only.
|
||||||
*/
|
*/
|
||||||
#if defined(__DOXYGEN__)
|
#if defined(__DOXYGEN__)
|
||||||
#define CH_CURRP_REGISTER_CACHE "reg"
|
#define CH_CURRP_REGISTER_CACHE "reg"
|
||||||
|
@ -118,7 +124,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the @p chThdWait() function is included in the kernel.
|
* @brief Threads synchronization APIs.
|
||||||
|
* @details If enabled then the @p chThdWait() function is included in
|
||||||
|
* the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
|
||||||
|
@ -126,7 +135,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Semaphores APIs are included in the kernel.
|
* @brief Semaphores APIs.
|
||||||
|
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
@ -134,8 +145,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then the threads are enqueued on semaphores by priority rather
|
* @brief Semaphores queuing mode.
|
||||||
* than FIFO order.
|
* @details If enabled then the threads are enqueued on semaphores by
|
||||||
|
* priority rather than in FIFO order.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE. Enable this if you have special requirements.
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -144,8 +157,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Semaphores the @p chSemWaitSignal() API is included
|
* @brief Atomic semaphore API.
|
||||||
* in the kernel.
|
* @details If enabled then the semaphores the @p chSemWaitSignal() API
|
||||||
|
* is included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -154,7 +169,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Mutexes APIs are included in the kernel.
|
* @brief Mutexes APIs.
|
||||||
|
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
||||||
|
@ -162,7 +179,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Conditional Variables APIs are included in the kernel.
|
* @brief Conditional Variables APIs.
|
||||||
|
* @details If enabled then the conditional variables APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_MUTEXES.
|
* @note Requires @p CH_USE_MUTEXES.
|
||||||
*/
|
*/
|
||||||
|
@ -171,7 +191,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Conditional Variables APIs are included in the kernel.
|
* @brief Conditional Variables APIs with timeout.
|
||||||
|
* @details If enabled then the conditional variables APIs with timeout
|
||||||
|
* specification are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_CONDVARS.
|
* @note Requires @p CH_USE_CONDVARS.
|
||||||
*/
|
*/
|
||||||
|
@ -180,7 +203,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Event flags APIs are included in the kernel.
|
* @brief Events Flags APIs.
|
||||||
|
* @details If enabled then the event flags APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
|
||||||
|
@ -188,8 +213,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the @p chEvtWaitXXXTimeout() functions are included in
|
* @brief Events Flags APIs with timeout.
|
||||||
* the kernel.
|
* @details If enabled then the events APIs with timeout specification
|
||||||
|
* are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_EVENTS.
|
* @note Requires @p CH_USE_EVENTS.
|
||||||
*/
|
*/
|
||||||
|
@ -198,7 +225,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Synchronous Messages APIs are included in the kernel.
|
* @brief Synchronous Messages APIs.
|
||||||
|
* @details If enabled then the synchronous messages APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
@ -206,7 +236,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then messages are served by priority rather than in FIFO order.
|
* @brief Synchronous Messages queuing mode.
|
||||||
|
* @details If enabled then messages are served by priority rather than in
|
||||||
|
* FIFO order.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE. Enable this if you have special requirements.
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
* @note Requires @p CH_USE_MESSAGES.
|
* @note Requires @p CH_USE_MESSAGES.
|
||||||
*/
|
*/
|
||||||
|
@ -215,16 +248,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Asynchronous Messages (Mailboxes) APIs are included
|
* @brief Mailboxes APIs.
|
||||||
* in the kernel.
|
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||||
|
* included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
|
||||||
#define CH_USE_MAILBOXES TRUE
|
#define CH_USE_MAILBOXES TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the I/O queues APIs are included in the kernel.
|
* @brief I/O Queues APIs.
|
||||||
|
* @details If enabled then the I/O queues APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -233,9 +271,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the memory heap allocator APIs are included in the kernel.
|
* @brief Core Memory Manager APIs.
|
||||||
|
* @details If enabled then the core memory manager APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_MUTEXES or @p CH_USE_SEMAPHORES.
|
*/
|
||||||
|
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
#define CH_USE_MEMCORE TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Heap Allocator APIs.
|
||||||
|
* @details If enabled then the memory heap allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_USE_COREMEM and either @p CH_USE_MUTEXES or
|
||||||
|
* @p CH_USE_SEMAPHORES.
|
||||||
* @note Mutexes are recommended.
|
* @note Mutexes are recommended.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
@ -243,18 +296,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled enforces the use of the C-runtime @p malloc() and @p free()
|
* @brief C-runtime allocator.
|
||||||
* functions as backend for the system heap allocator.
|
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
||||||
|
* @p malloc() and @p free() functions.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
* @note Requires @p CH_USE_HEAP.
|
* @note Requires @p CH_USE_HEAP.
|
||||||
|
* @note The C-runtime may or may not require @p CH_USE_COREMEM, see the
|
||||||
|
* appropriate documentation.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
||||||
#define CH_USE_MALLOC_HEAP FALSE
|
#define CH_USE_MALLOC_HEAP FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the memory pools allocator APIs are included in the
|
* @brief Memory Pools Allocator APIs.
|
||||||
* kernel.
|
* @details If enabled then the memory pools allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||||
|
@ -262,8 +321,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the dynamic threads creation APIs are included in the
|
* @brief Dynamic Threads APIs.
|
||||||
* kernel.
|
* @details If enabled then the dynamic threads creation APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_WAITEXIT.
|
* @note Requires @p CH_USE_WAITEXIT.
|
||||||
*/
|
*/
|
||||||
|
@ -276,8 +337,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled then the checks on the API functions input
|
* @brief Debug option, parameters checks.
|
||||||
|
* @details If enabled then the checks on the API functions input
|
||||||
* parameters are activated.
|
* parameters are activated.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||||
|
@ -285,9 +348,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled then all the assertions in the kernel code are
|
* @brief Debug option, consistency checks.
|
||||||
* activated. This includes consistency checks inside the kernel, runtime
|
* @details If enabled then all the assertions in the kernel code are
|
||||||
* anomalies and port-defined checks.
|
* activated. This includes consistency checks inside the kernel,
|
||||||
|
* runtime anomalies and port-defined checks.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||||
|
@ -295,8 +360,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled the context switch circular trace buffer is
|
* @brief Debug option, trace buffer.
|
||||||
|
* @details If enabled then the context switch circular trace buffer is
|
||||||
* activated.
|
* activated.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||||
|
@ -304,25 +371,37 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled a runtime stack check is performed.
|
* @brief Debug option, stack checks.
|
||||||
|
* @details If enabled then a runtime stack check is performed.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
* @note The stack check is performed in a architecture/port dependent way. It
|
* @note The stack check is performed in a architecture/port dependent way. It
|
||||||
* may not be implemented at all.
|
* may not be implemented or some ports.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled the threads working area is filled with a byte
|
* @brief Debug option, stacks initialization.
|
||||||
* pattern when a thread is created.
|
* @details If enabled then the threads working area is filled with a byte
|
||||||
|
* value when a thread is created. This can be useful for the
|
||||||
|
* runtime measurement of the used stack.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_FILL_THREADS FALSE
|
#define CH_DBG_FILL_THREADS FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled a field is added to the @p Thread structure that
|
* @brief Debug option, threads profiling.
|
||||||
|
* @details If enabled then a field is added to the @p Thread structure that
|
||||||
* counts the system ticks occurred while executing the thread.
|
* counts the system ticks occurred while executing the thread.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note This debug option is defaulted to TRUE because it is required by
|
||||||
|
* some test cases into the test suite.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_THREADS_PROFILING TRUE
|
#define CH_DBG_THREADS_PROFILING TRUE
|
||||||
|
@ -333,41 +412,49 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User fields added to the end of the @p Thread structure.
|
* @brief Threads descriptor structure hook.
|
||||||
|
* @details User fields added to the end of the @p Thread structure.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_FIELDS \
|
#define THREAD_EXT_FIELDS \
|
||||||
struct { \
|
struct { \
|
||||||
/* Add thread custom fields here.*/ \
|
/* Add threads custom fields here.*/ \
|
||||||
/* Space for the LWIP sys_timeouts structure.*/ \
|
/* Space for the LWIP sys_timeouts structure.*/ \
|
||||||
void *p_lwipspace[1]; \
|
void *p_lwipspace[1]; \
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User initialization code added to the @p chThdInit() API.
|
* @brief Threads initialization hook.
|
||||||
* @note It is invoked from within @p chThdInit().
|
* @details User initialization code added to the @p chThdInit() API.
|
||||||
|
*
|
||||||
|
* @note It is invoked from within @p chThdInit() and implicitily from all
|
||||||
|
* the threads creation APIs.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_INIT(tp) { \
|
#define THREAD_EXT_INIT(tp) { \
|
||||||
/* Add thread initialization code here.*/ \
|
/* Add threads initialization code here.*/ \
|
||||||
(tp)->p_lwipspace[0] = NULL; \
|
(tp)->p_lwipspace[0] = NULL; \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User finalization code added to the @p chThdExit() API.
|
* @brief Threads finalization hook.
|
||||||
|
* @details User finalization code added to the @p chThdExit() API.
|
||||||
|
*
|
||||||
* @note It is inserted into lock zone.
|
* @note It is inserted into lock zone.
|
||||||
|
* @note It is also invoked when the threads simply return in order to
|
||||||
|
* terminate.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_EXIT(tp) { \
|
#define THREAD_EXT_EXIT(tp) { \
|
||||||
/* Add thread finalization code here.*/ \
|
/* Add threads finalization code here.*/ \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code inserted inside the idle thread loop immediately after an interrupt
|
* @brief Idle Loop hook.
|
||||||
* resumed execution.
|
* @details This hook is continuously invoked by the idle thread loop.
|
||||||
*/
|
*/
|
||||||
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
||||||
#define IDLE_LOOP_HOOK() { \
|
#define IDLE_LOOP_HOOK() { \
|
||||||
|
|
|
@ -66,7 +66,7 @@ void sys_init(void) {
|
||||||
|
|
||||||
sys_sem_t sys_sem_new(u8_t count) {
|
sys_sem_t sys_sem_new(u8_t count) {
|
||||||
|
|
||||||
sys_sem_t sem = chHeapAlloc(sizeof(Semaphore));
|
sys_sem_t sem = chHeapAlloc(NULL, sizeof(Semaphore));
|
||||||
chSemInit(sem, (cnt_t)count);
|
chSemInit(sem, (cnt_t)count);
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) {
|
||||||
sys_mbox_t sys_mbox_new(int size) {
|
sys_mbox_t sys_mbox_new(int size) {
|
||||||
sys_mbox_t mbox;
|
sys_mbox_t mbox;
|
||||||
|
|
||||||
mbox = chHeapAlloc(sizeof(Mailbox) + sizeof(msg_t) * size);
|
mbox = chHeapAlloc(NULL, sizeof(Mailbox) + sizeof(msg_t) * size);
|
||||||
chMBInit(mbox, (void *)(((uint8_t *)mbox) + sizeof(Mailbox)), size);
|
chMBInit(mbox, (void *)(((uint8_t *)mbox) + sizeof(Mailbox)), size);
|
||||||
return mbox;
|
return mbox;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ struct sys_timeouts *sys_arch_timeouts(void) {
|
||||||
sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg),
|
sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg),
|
||||||
void *arg, int stacksize, int prio) {
|
void *arg, int stacksize, int prio) {
|
||||||
size_t wsz = THD_WA_SIZE(stacksize);
|
size_t wsz = THD_WA_SIZE(stacksize);
|
||||||
void *wsp = chHeapAlloc(wsz);
|
void *wsp = chCoreAlloc(wsz);
|
||||||
if (wsp == NULL)
|
if (wsp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return (sys_thread_t)chThdCreateStatic(wsp, wsz, prio, (tfunc_t)thread, arg);
|
return (sys_thread_t)chThdCreateStatic(wsp, wsz, prio, (tfunc_t)thread, arg);
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "mailboxes.h"
|
#include "mailboxes.h"
|
||||||
|
#include "memcore.h"
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "mempools.h"
|
#include "mempools.h"
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
|
|
@ -27,17 +27,60 @@
|
||||||
#ifndef _HEAP_H_
|
#ifndef _HEAP_H_
|
||||||
#define _HEAP_H_
|
#define _HEAP_H_
|
||||||
|
|
||||||
|
#if CH_USE_HEAP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Module dependancies check.
|
||||||
|
*/
|
||||||
|
#if !CH_USE_MEMCORE && !CH_USE_MALLOC_HEAP
|
||||||
|
#error "CH_USE_HEAP requires CH_USE_MEM"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
|
||||||
|
#error "CH_USE_HEAP requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct memory_heap MemoryHeap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Memory heap block header.
|
||||||
|
*/
|
||||||
|
struct heap_header {
|
||||||
|
union {
|
||||||
|
struct heap_header *h_next; /**< @brief Next block in free list. */
|
||||||
|
MemoryHeap *h_heap; /**< @brief Block owner heap. */
|
||||||
|
};
|
||||||
|
size_t h_size; /**< @brief Size of the memory block. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure describing a memory heap.
|
||||||
|
*/
|
||||||
|
struct memory_heap {
|
||||||
|
memgetfunc_t h_provider; /**< @brief Memory blocks provider for
|
||||||
|
this heap. */
|
||||||
|
struct heap_header h_free; /**< @brief Free blocks list header. */
|
||||||
|
#if CH_USE_MUTEXES
|
||||||
|
Mutex h_mtx; /**< @brief Heap access mutex. */
|
||||||
|
#else
|
||||||
|
Semaphore h_sem; /**< @brief Heap access semaphore. */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void heap_init(void);
|
void heap_init(void);
|
||||||
void *chHeapAlloc(size_t size);
|
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size);
|
||||||
|
void *chHeapAlloc(MemoryHeap *heapp, size_t size);
|
||||||
void chHeapFree(void *p);
|
void chHeapFree(void *p);
|
||||||
size_t chHeapStatus(size_t *sizep);
|
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* CH_USE_HEAP */
|
||||||
|
|
||||||
#endif /* _HEAP_H_ */
|
#endif /* _HEAP_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -18,22 +18,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file mem.h
|
* @file memcore.h
|
||||||
* @brief Low level memory manager macros and structures.
|
* @brief Core memory manager macros and structures.
|
||||||
* @addtogroup coremem
|
* @addtogroup memcore
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MEM_H_
|
#ifndef _MEMCORE_H_
|
||||||
#define _MEM_H_
|
#define _MEMCORE_H_
|
||||||
|
|
||||||
#if CH_USE_COREMEM
|
#if CH_USE_MEMCORE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Memory alignment type.
|
* @brief Memory alignment type.
|
||||||
*/
|
*/
|
||||||
typedef void *align_t;
|
typedef void *align_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Memory get function.
|
||||||
|
* @note This type must be assignment compatible with the @p chMemAlloc()
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
typedef void *(*memgetfunc_t)(size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Alignment mask constant.
|
* @brief Alignment mask constant.
|
||||||
*/
|
*/
|
||||||
|
@ -42,20 +49,26 @@ typedef void *align_t;
|
||||||
/**
|
/**
|
||||||
* @brief Alignment helper macro.
|
* @brief Alignment helper macro.
|
||||||
*/
|
*/
|
||||||
#define MEM_ALIGN_SIZE(p) (((size_t)(p) + ALIGN_MASK) & ~ALIGN_MASK)
|
#define MEM_ALIGN_SIZE(p) (((size_t)(p) + MEM_ALIGN_MASK) & ~MEM_ALIGN_MASK)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns whatever a pointer or memory size is aligned to
|
||||||
|
* the type @p align_t.
|
||||||
|
*/
|
||||||
|
#define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void mem_init(void);
|
void core_init(void);
|
||||||
void *chMemAlloc(size_t size);
|
void *chCoreAlloc(size_t size);
|
||||||
void *chMemAllocI(size_t size);
|
void *chCoreAllocI(size_t size);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CH_USE_COREMEM */
|
#endif /* CH_USE_MEMCORE */
|
||||||
|
|
||||||
#endif /* _MEM_H_ */
|
#endif /* _MEMCORE_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
|
@ -167,8 +167,8 @@ extern "C" {
|
||||||
Thread *chThdCreateStatic(void *wsp, size_t size,
|
Thread *chThdCreateStatic(void *wsp, size_t size,
|
||||||
tprio_t prio, tfunc_t pf, void *arg);
|
tprio_t prio, tfunc_t pf, void *arg);
|
||||||
#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP
|
#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP
|
||||||
Thread *chThdCreateFromHeap(size_t size, tprio_t prio,
|
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
||||||
tfunc_t pf, void *arg);
|
tprio_t prio, tfunc_t pf, void *arg);
|
||||||
#endif
|
#endif
|
||||||
#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS
|
#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS
|
||||||
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
|
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
|
||||||
|
|
|
@ -13,6 +13,7 @@ KERNSRC = ${CHIBIOS}/os/kernel/src/chsys.c \
|
||||||
${CHIBIOS}/os/kernel/src/chmsg.c \
|
${CHIBIOS}/os/kernel/src/chmsg.c \
|
||||||
${CHIBIOS}/os/kernel/src/chmboxes.c \
|
${CHIBIOS}/os/kernel/src/chmboxes.c \
|
||||||
${CHIBIOS}/os/kernel/src/chqueues.c \
|
${CHIBIOS}/os/kernel/src/chqueues.c \
|
||||||
|
${CHIBIOS}/os/kernel/src/chmemcore.c \
|
||||||
${CHIBIOS}/os/kernel/src/chheap.c \
|
${CHIBIOS}/os/kernel/src/chheap.c \
|
||||||
${CHIBIOS}/os/kernel/src/chmempools.c
|
${CHIBIOS}/os/kernel/src/chmempools.c
|
||||||
|
|
||||||
|
|
|
@ -28,41 +28,23 @@
|
||||||
|
|
||||||
#if CH_USE_HEAP
|
#if CH_USE_HEAP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defaults on the best synchronization mechanism available.
|
||||||
|
*/
|
||||||
|
#if CH_USE_MUTEXES
|
||||||
|
#define H_LOCK(h) chMtxLock(&(h)->h_mtx)
|
||||||
|
#define H_UNLOCK(h) chMtxUnlock()
|
||||||
|
#else
|
||||||
|
#define H_LOCK(h) chSemWait(&(h)->h_sem)
|
||||||
|
#define H_UNLOCK(h) chSemSignal(&(h)->h_sem)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !CH_USE_MALLOC_HEAP
|
#if !CH_USE_MALLOC_HEAP
|
||||||
|
|
||||||
#define MAGIC 0xF5A0
|
/**
|
||||||
#define ALIGN_TYPE void *
|
* @brief Default heap descriptor.
|
||||||
#define ALIGN_MASK (sizeof(ALIGN_TYPE) - 1)
|
*/
|
||||||
#define ALIGN_SIZE(p) (((size_t)(p) + ALIGN_MASK) & ~ALIGN_MASK)
|
static MemoryHeap default_heap;
|
||||||
|
|
||||||
struct header {
|
|
||||||
union {
|
|
||||||
struct header *h_next;
|
|
||||||
size_t h_magic;
|
|
||||||
};
|
|
||||||
size_t h_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
struct header free; /* Guaranteed to be not adjacent to the heap */
|
|
||||||
#if CH_USE_MUTEXES
|
|
||||||
#define H_LOCK() chMtxLock(&heap.hmtx)
|
|
||||||
#define H_UNLOCK() chMtxUnlock()
|
|
||||||
Mutex hmtx;
|
|
||||||
#elif CH_USE_SEMAPHORES
|
|
||||||
#define H_LOCK() chSemWait(&heap.hsem)
|
|
||||||
#define H_UNLOCK() chSemSignal(&heap.hsem)
|
|
||||||
Semaphore hsem;
|
|
||||||
#else
|
|
||||||
#error "The heap allocator requires mutexes or semaphores to be enabled"
|
|
||||||
#endif
|
|
||||||
#if CH_HEAP_SIZE > 0
|
|
||||||
union {
|
|
||||||
ALIGN_TYPE alignment;
|
|
||||||
char buffer[ALIGN_SIZE(CH_HEAP_SIZE)];
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
} heap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the allocator subsystem.
|
* @brief Initializes the allocator subsystem.
|
||||||
|
@ -70,26 +52,40 @@ static struct {
|
||||||
* @note Internal use only.
|
* @note Internal use only.
|
||||||
*/
|
*/
|
||||||
void heap_init(void) {
|
void heap_init(void) {
|
||||||
struct header *hp;
|
default_heap.h_provider = chCoreAlloc;
|
||||||
|
default_heap.h_free.h_next = NULL;
|
||||||
#if CH_HEAP_SIZE == 0
|
default_heap.h_free.h_size = 0;
|
||||||
extern char __heap_base__;
|
|
||||||
extern char __heap_end__;
|
|
||||||
|
|
||||||
hp = (void *)&__heap_base__;
|
|
||||||
hp->h_size = &__heap_end__ - &__heap_base__ - sizeof(struct header);
|
|
||||||
#else
|
|
||||||
hp = (void *)&heap.buffer[0];
|
|
||||||
hp->h_size = (&heap.buffer[ALIGN_SIZE(CH_HEAP_SIZE)] - &heap.buffer[0]) -
|
|
||||||
sizeof(struct header);
|
|
||||||
#endif
|
|
||||||
hp->h_next = NULL;
|
|
||||||
heap.free.h_next = hp;
|
|
||||||
heap.free.h_size = 0;
|
|
||||||
#if CH_USE_MUTEXES
|
#if CH_USE_MUTEXES
|
||||||
chMtxInit(&heap.hmtx);
|
chMtxInit(&default_heap.h_mtx);
|
||||||
#else
|
#else
|
||||||
chSemInit(&heap.hsem, 1);
|
chSemInit(&default_heap.h_sem, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes a memory heap.
|
||||||
|
*
|
||||||
|
* @param[out] heapp pointer to a memory heap descriptor to be initialized
|
||||||
|
* @param[in] buf heap buffer base
|
||||||
|
* @param[in] size heap size
|
||||||
|
*
|
||||||
|
* @note Both the heap buffer base and the heap size must be aligned to
|
||||||
|
* the @p align_t type size.
|
||||||
|
*/
|
||||||
|
void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) {
|
||||||
|
struct heap_header *hp;
|
||||||
|
|
||||||
|
chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit");
|
||||||
|
|
||||||
|
heapp->h_provider = NULL;
|
||||||
|
heapp->h_free.h_next = hp = buf;
|
||||||
|
heapp->h_free.h_size = 0;
|
||||||
|
hp->h_next = NULL;
|
||||||
|
hp->h_size = size - sizeof(struct heap_header);
|
||||||
|
#if CH_USE_MUTEXES
|
||||||
|
chMtxInit(&heapp->h_mtx);
|
||||||
|
#else
|
||||||
|
chSemInit(&heapp->h_sem, 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,52 +93,74 @@ void heap_init(void) {
|
||||||
* @brief Allocates a block of memory from the heap by using the first-fit
|
* @brief Allocates a block of memory from the heap by using the first-fit
|
||||||
* algorithm.
|
* algorithm.
|
||||||
* @details The allocated block is guaranteed to be properly aligned for a
|
* @details The allocated block is guaranteed to be properly aligned for a
|
||||||
* pointer data type.
|
* pointer data type (@p align_t).
|
||||||
*
|
*
|
||||||
|
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to access
|
||||||
|
* the default heap.
|
||||||
* @param[in] size the size of the block to be allocated. Note that the
|
* @param[in] size the size of the block to be allocated. Note that the
|
||||||
* allocated block may be a bit bigger than the requested
|
* allocated block may be a bit bigger than the requested
|
||||||
* size for alignment and fragmentation reasons.
|
* size for alignment and fragmentation reasons.
|
||||||
* @return A pointer to the allocated block.
|
* @return A pointer to the allocated block.
|
||||||
* @retval NULL if the block cannot be allocated.
|
* @retval NULL if the block cannot be allocated.
|
||||||
*/
|
*/
|
||||||
void *chHeapAlloc(size_t size) {
|
void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
|
||||||
struct header *qp, *hp, *fp;
|
struct heap_header *qp, *hp, *fp;
|
||||||
|
|
||||||
size = ALIGN_SIZE(size);
|
if (heapp == NULL)
|
||||||
qp = &heap.free;
|
heapp = &default_heap;
|
||||||
H_LOCK();
|
|
||||||
|
size = MEM_ALIGN_SIZE(size);
|
||||||
|
qp = &heapp->h_free;
|
||||||
|
H_LOCK(heapp);
|
||||||
|
|
||||||
while (qp->h_next != NULL) {
|
while (qp->h_next != NULL) {
|
||||||
hp = qp->h_next;
|
hp = qp->h_next;
|
||||||
if (hp->h_size >= size) {
|
if (hp->h_size >= size) {
|
||||||
if (hp->h_size < size + sizeof(struct header)) {
|
if (hp->h_size < size + sizeof(struct heap_header)) {
|
||||||
/* Gets the whole block even if it is slightly bigger than the
|
/*
|
||||||
requested size because the fragment would be too small to be
|
* Gets the whole block even if it is slightly bigger than the
|
||||||
useful */
|
* requested size because the fragment would be too small to be
|
||||||
|
* useful.
|
||||||
|
*/
|
||||||
qp->h_next = hp->h_next;
|
qp->h_next = hp->h_next;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Block bigger enough, must split it */
|
/*
|
||||||
fp = (void *)((char *)(hp) + sizeof(struct header) + size);
|
* Block bigger enough, must split it.
|
||||||
|
*/
|
||||||
|
fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size);
|
||||||
fp->h_next = hp->h_next;
|
fp->h_next = hp->h_next;
|
||||||
fp->h_size = hp->h_size - sizeof(struct header) - size;
|
fp->h_size = hp->h_size - sizeof(struct heap_header) - size;
|
||||||
qp->h_next = fp;
|
qp->h_next = fp;
|
||||||
hp->h_size = size;
|
hp->h_size = size;
|
||||||
}
|
}
|
||||||
hp->h_magic = MAGIC;
|
hp->h_heap = heapp;
|
||||||
|
|
||||||
H_UNLOCK();
|
H_UNLOCK(heapp);
|
||||||
return (void *)(hp + 1);
|
return (void *)(hp + 1);
|
||||||
}
|
}
|
||||||
qp = hp;
|
qp = hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
H_UNLOCK();
|
H_UNLOCK(heapp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* More memory is required, tries to get it from the associated provider.
|
||||||
|
*/
|
||||||
|
if (heapp->h_provider) {
|
||||||
|
hp = heapp->h_provider(size + sizeof(struct heap_header));
|
||||||
|
if (hp != NULL) {
|
||||||
|
hp->h_heap = heapp;
|
||||||
|
hp->h_size = size;
|
||||||
|
hp++;
|
||||||
|
return (void *)hp;
|
||||||
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LIMIT(p) (struct header *)((char *)(p) + \
|
#define LIMIT(p) (struct heap_header *)((uint8_t *)(p) + \
|
||||||
sizeof(struct header) + \
|
sizeof(struct heap_header) + \
|
||||||
(p)->h_size)
|
(p)->h_size)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,50 +169,59 @@ void *chHeapAlloc(size_t size) {
|
||||||
* @param[in] p the memory block pointer
|
* @param[in] p the memory block pointer
|
||||||
*/
|
*/
|
||||||
void chHeapFree(void *p) {
|
void chHeapFree(void *p) {
|
||||||
struct header *qp, *hp;
|
struct heap_header *qp, *hp;
|
||||||
|
MemoryHeap *heapp;
|
||||||
|
|
||||||
chDbgCheck(p != NULL, "chHeapFree");
|
chDbgCheck(p != NULL, "chHeapFree");
|
||||||
|
|
||||||
hp = (struct header *)p - 1;
|
hp = (struct heap_header *)p - 1;
|
||||||
chDbgAssert(hp->h_magic == MAGIC,
|
heapp = hp->h_heap;
|
||||||
"chHeapFree(), #1",
|
qp = &heapp->h_free;
|
||||||
"it is not magic");
|
H_LOCK(heapp);
|
||||||
qp = &heap.free;
|
|
||||||
H_LOCK();
|
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
|
||||||
chDbgAssert((hp < qp) || (hp >= LIMIT(qp)),
|
chDbgAssert((hp < qp) || (hp >= LIMIT(qp)),
|
||||||
"chHeapFree(), #2",
|
"chHeapFree(), #1",
|
||||||
"within free block");
|
"within free block");
|
||||||
|
|
||||||
if (((qp == &heap.free) || (hp > qp)) &&
|
if (((qp == &heapp->h_free) || (hp > qp)) &&
|
||||||
((qp->h_next == NULL) || (hp < qp->h_next))) {
|
((qp->h_next == NULL) || (hp < qp->h_next))) {
|
||||||
/* Insertion after qp */
|
/*
|
||||||
|
* Insertion after qp.
|
||||||
|
*/
|
||||||
hp->h_next = qp->h_next;
|
hp->h_next = qp->h_next;
|
||||||
qp->h_next = hp;
|
qp->h_next = hp;
|
||||||
/* Verifies if the newly inserted block should be merged */
|
/*
|
||||||
|
* Verifies if the newly inserted block should be merged.
|
||||||
|
*/
|
||||||
if (LIMIT(hp) == hp->h_next) {
|
if (LIMIT(hp) == hp->h_next) {
|
||||||
/* Merge with the next block */
|
/*
|
||||||
hp->h_size += hp->h_next->h_size + sizeof(struct header);
|
* Merge with the next block.
|
||||||
|
*/
|
||||||
|
hp->h_size += hp->h_next->h_size + sizeof(struct heap_header);
|
||||||
hp->h_next = hp->h_next->h_next;
|
hp->h_next = hp->h_next->h_next;
|
||||||
}
|
}
|
||||||
if ((LIMIT(qp) == hp)) { /* Cannot happen when qp == &heap.free */
|
if ((LIMIT(qp) == hp)) {
|
||||||
/* Merge with the previous block */
|
/*
|
||||||
qp->h_size += hp->h_size + sizeof(struct header);
|
* Merge with the previous block.
|
||||||
|
*/
|
||||||
|
qp->h_size += hp->h_size + sizeof(struct heap_header);
|
||||||
qp->h_next = hp->h_next;
|
qp->h_next = hp->h_next;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
H_UNLOCK();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
qp = qp->h_next;
|
qp = qp->h_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
H_UNLOCK(heapp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reports the heap status.
|
* @brief Reports the heap status.
|
||||||
*
|
*
|
||||||
|
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to access
|
||||||
|
* the default heap.
|
||||||
* @param[in] sizep pointer to a variable that will receive the total
|
* @param[in] sizep pointer to a variable that will receive the total
|
||||||
* fragmented free space
|
* fragmented free space
|
||||||
* @return The number of fragments in the heap.
|
* @return The number of fragments in the heap.
|
||||||
|
@ -203,19 +230,22 @@ void chHeapFree(void *p) {
|
||||||
* @note This function is not implemented when the @p CH_USE_MALLOC_HEAP
|
* @note This function is not implemented when the @p CH_USE_MALLOC_HEAP
|
||||||
* configuration option is used (it always returns zero).
|
* configuration option is used (it always returns zero).
|
||||||
*/
|
*/
|
||||||
size_t chHeapStatus(size_t *sizep) {
|
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
|
||||||
struct header *qp;
|
struct heap_header *qp;
|
||||||
size_t n, sz;
|
size_t n, sz;
|
||||||
|
|
||||||
H_LOCK();
|
if (heapp == NULL)
|
||||||
|
heapp = &default_heap;
|
||||||
|
|
||||||
|
H_LOCK(heapp);
|
||||||
|
|
||||||
sz = 0;
|
sz = 0;
|
||||||
for (n = 0, qp = &heap.free; qp->h_next; n++, qp = qp->h_next)
|
for (n = 0, qp = &heapp->h_free; qp->h_next; n++, qp = qp->h_next)
|
||||||
sz += qp->h_next->h_size;
|
sz += qp->h_next->h_size;
|
||||||
if (sizep)
|
if (sizep)
|
||||||
*sizep = sz;
|
*sizep = sz;
|
||||||
|
|
||||||
H_UNLOCK();
|
H_UNLOCK(heapp);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +261,6 @@ static Mutex hmtx;
|
||||||
#define H_LOCK() chSemWait(&hsem)
|
#define H_LOCK() chSemWait(&hsem)
|
||||||
#define H_UNLOCK() chSemSignal(&hsem)
|
#define H_UNLOCK() chSemSignal(&hsem)
|
||||||
static Semaphore hsem;
|
static Semaphore hsem;
|
||||||
#else
|
|
||||||
#error "The heap allocator requires mutexes or semaphores to be enabled"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void heap_init(void) {
|
void heap_init(void) {
|
||||||
|
@ -244,9 +272,11 @@ void heap_init(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void *chHeapAlloc(size_t size) {
|
void *chHeapAlloc(MemoryHeap *heapp, size_t size) {
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
chDbgCheck(heapp == NULL, "chHeapAlloc");
|
||||||
|
|
||||||
H_LOCK();
|
H_LOCK();
|
||||||
p = malloc(size);
|
p = malloc(size);
|
||||||
H_UNLOCK();
|
H_UNLOCK();
|
||||||
|
@ -262,7 +292,9 @@ void chHeapFree(void *p) {
|
||||||
H_UNLOCK();
|
H_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t chHeapStatus(size_t *sizep) {
|
size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
|
||||||
|
|
||||||
|
chDbgCheck(heapp == NULL, "chHeapStatus");
|
||||||
|
|
||||||
if (sizep)
|
if (sizep)
|
||||||
*sizep = 0;
|
*sizep = 0;
|
||||||
|
|
|
@ -18,33 +18,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file chmem.c
|
* @file chmemcore.c
|
||||||
* @brief Low level memory manager code.
|
* @brief Core memory manager code.
|
||||||
* @addtogroup coremem
|
* @addtogroup memcore
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ch.h>
|
#include <ch.h>
|
||||||
|
|
||||||
#if CH_USE_COREMEM
|
#if CH_USE_MEMCORE
|
||||||
|
|
||||||
#if CH_COREMEM_SIZE == 0
|
#if CH_MEMCORE_SIZE == 0
|
||||||
extern align_t __heap_base__;
|
extern align_t __heap_base__;
|
||||||
extern align_t __heap_end__;
|
extern align_t __heap_end__;
|
||||||
#else
|
#else
|
||||||
align_t buffer[ALIGN_SIZE(CH_MEM_SIZE) / sizeof(align_t)];
|
align_t buffer[ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static align_t *nextmem;
|
static align_t *nextmem;
|
||||||
static align_t *endmem;
|
static align_t *endmem;
|
||||||
|
|
||||||
void mem_init(void) {
|
/**
|
||||||
#if CH_COREMEM_SIZE == 0
|
* @brief Low level memory manager initialization.
|
||||||
|
*
|
||||||
|
* @note Internal use only.
|
||||||
|
*/
|
||||||
|
void core_init(void) {
|
||||||
|
#if CH_MEMCORE_SIZE == 0
|
||||||
nextmem = &__heap_base__;
|
nextmem = &__heap_base__;
|
||||||
endmem = &__heap_end__;
|
endmem = &__heap_end__;
|
||||||
#else
|
#else
|
||||||
nextmem = &buffer[0];
|
nextmem = &buffer[0];
|
||||||
endmem = &buffer[ALIGN_SIZE(CH_MEM_SIZE) / sizeof(align_t)];
|
endmem = &buffer[ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +86,7 @@ void *chCoreAlloc(size_t size) {
|
||||||
void *chCoreAllocI(size_t size) {
|
void *chCoreAllocI(size_t size) {
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
size = ALIGN_SIZE(size);
|
size = MEM_ALIGN_SIZE(size);
|
||||||
if (nextmem + size > endmem)
|
if (nextmem + size > endmem)
|
||||||
return NULL;
|
return NULL;
|
||||||
p = nextmem;
|
p = nextmem;
|
||||||
|
@ -89,6 +94,6 @@ void *chCoreAllocI(size_t size) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CH_USE_COREMEM */
|
#endif /* CH_USE_MEMCORE */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
|
@ -61,6 +61,9 @@ void chSysInit(void) {
|
||||||
port_init();
|
port_init();
|
||||||
scheduler_init();
|
scheduler_init();
|
||||||
vt_init();
|
vt_init();
|
||||||
|
#if CH_USE_MEMCORE
|
||||||
|
core_init();
|
||||||
|
#endif
|
||||||
#if CH_USE_HEAP
|
#if CH_USE_HEAP
|
||||||
heap_init();
|
heap_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -124,6 +124,8 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new thread allocating the memory from the heap.
|
* @brief Creates a new thread allocating the memory from the heap.
|
||||||
*
|
*
|
||||||
|
* @param[in] heapp heap from which allocate the memory or NULL for the
|
||||||
|
* default heap
|
||||||
* @param[in] size size of the working area to be allocated
|
* @param[in] size size of the working area to be allocated
|
||||||
* @param[in] prio the priority level for the new thread
|
* @param[in] prio the priority level for the new thread
|
||||||
* @param[in] pf the thread function
|
* @param[in] pf the thread function
|
||||||
|
@ -139,11 +141,12 @@ Thread *chThdCreateStatic(void *wsp, size_t size,
|
||||||
* @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
|
* @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled
|
||||||
* in @p chconf.h.
|
* in @p chconf.h.
|
||||||
*/
|
*/
|
||||||
Thread *chThdCreateFromHeap(size_t size, tprio_t prio, tfunc_t pf, void *arg) {
|
Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size,
|
||||||
|
tprio_t prio, tfunc_t pf, void *arg) {
|
||||||
void *wsp;
|
void *wsp;
|
||||||
Thread *tp;
|
Thread *tp;
|
||||||
|
|
||||||
wsp = chHeapAlloc(size);
|
wsp = chHeapAlloc(heapp, size);
|
||||||
if (wsp == NULL)
|
if (wsp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
tp = chThdInit(wsp, size, prio, pf, arg);
|
tp = chThdInit(wsp, size, prio, pf, arg);
|
||||||
|
|
|
@ -32,29 +32,36 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frequency of the system timer that drives the system ticks. This also
|
* @brief System tick frequency.
|
||||||
* defines the system tick time unit.
|
* @details Frequency of the system timer that drives the system ticks. This
|
||||||
|
* setting also defines the system tick time unit.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
|
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
|
||||||
#define CH_FREQUENCY 1000
|
#define CH_FREQUENCY 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constant is the number of system ticks allowed for the threads before
|
* @brief Round robin interval.
|
||||||
* preemption occurs. This option is only meaningful if the option
|
* @details This constant is the number of system ticks allowed for the
|
||||||
* @p CH_USE_ROUNDROBIN is also active.
|
* threads before preemption occurs. Setting this value to zero
|
||||||
|
* disables the round robin mechanism.
|
||||||
|
*
|
||||||
|
* @note Disabling round robin makes the kernel more compact and generally
|
||||||
|
* faster but forbids multiple threads at the same priority level.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
|
||||||
#define CH_TIME_QUANTUM 20
|
#define CH_TIME_QUANTUM 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
|
* @brief Nested locks.
|
||||||
|
* @details If enabled then the use of nested @p chSysLock() / @p chSysUnlock()
|
||||||
* operations is allowed.<br>
|
* operations is allowed.<br>
|
||||||
* For performance and code size reasons the recommended setting is to leave
|
* For performance and code size reasons the recommended setting
|
||||||
* this option disabled.<br>
|
* is to leave this option disabled.<br>
|
||||||
* You can use this option if you need to merge ChibiOS/RT with external
|
* You may use this option if you need to merge ChibiOS/RT with
|
||||||
* libraries that require nested lock/unlock operations.
|
* external libraries that require nested lock/unlock operations.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_NESTED_LOCKS) || defined(__DOXYGEN__)
|
||||||
|
@ -62,23 +69,18 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the kernel performs the round robin scheduling algorithm
|
* @brief Managed RAM size.
|
||||||
* on threads of equal priority.
|
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||||
* @note The default is @p TRUE.
|
* then the whole available RAM is used. The core memory is made
|
||||||
*/
|
* available to the heap allocator and/or can be used directly through
|
||||||
#if !defined(CH_USE_ROUNDROBIN) || defined(__DOXYGEN__)
|
* the simplified core memory allocator.
|
||||||
#define CH_USE_ROUNDROBIN TRUE
|
*
|
||||||
#endif
|
* @note In order to let the OS manage the whole RAM the linker script must
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of RAM bytes to use as system heap. If set to zero then the whole
|
|
||||||
* available RAM is used as system heap.
|
|
||||||
* @note In order to use the whole RAM as system heap the linker script must
|
|
||||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||||
* @note Requires @p CH_USE_HEAP.
|
* @note Requires @p CH_USE_COREMEM.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_HEAP_SIZE) || defined(__DOXYGEN__)
|
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
|
||||||
#define CH_HEAP_SIZE 0
|
#define CH_MEMCORE_SIZE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -86,8 +88,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then time efficient rather than space efficient code is used
|
* @brief OS optimization.
|
||||||
* when two possible implementations exist.
|
* @details If enabled then time efficient rather than space efficient code
|
||||||
|
* is used when two possible implementations exist.
|
||||||
|
*
|
||||||
* @note This is not related to the compiler optimization options.
|
* @note This is not related to the compiler optimization options.
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
|
@ -96,18 +100,20 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled defines a CPU register to be used as storage for the global
|
* @brief Exotic optimization.
|
||||||
* @p currp variable. Caching this variable in a register can greatly
|
* @details If defined then a CPU register is used as storage for the global
|
||||||
* improve both space and time efficiency of the generated code. Another side
|
* @p currp variable. Caching this variable in a register greatly
|
||||||
* effect is that one less register has to be saved during the context switch
|
* improves both space and time OS efficiency. A side effect is that
|
||||||
* resulting in lower RAM usage and faster code.
|
* one less register has to be saved during the context switch
|
||||||
|
* resulting in lower RAM usage and faster context switch.
|
||||||
|
*
|
||||||
* @note This option is only usable with the GCC compiler and is only useful
|
* @note This option is only usable with the GCC compiler and is only useful
|
||||||
* on processors with many registers like ARM cores.
|
* on processors with many registers like ARM cores.
|
||||||
* @note If this option is enabled then ALL the libraries linked to the
|
* @note If this option is enabled then ALL the libraries linked to the
|
||||||
* ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
|
* ChibiOS/RT code <b>must</b> be recompiled with the GCC option @p
|
||||||
* -ffixed-@<reg@>.
|
* -ffixed-@<reg@>.
|
||||||
* @note This option must be enabled in the Makefile, it is listed here for
|
* @note This option must be enabled in the Makefile, it is listed here for
|
||||||
* documentation.
|
* documentation only.
|
||||||
*/
|
*/
|
||||||
#if defined(__DOXYGEN__)
|
#if defined(__DOXYGEN__)
|
||||||
#define CH_CURRP_REGISTER_CACHE "reg"
|
#define CH_CURRP_REGISTER_CACHE "reg"
|
||||||
|
@ -118,7 +124,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the @p chThdWait() function is included in the kernel.
|
* @brief Threads synchronization APIs.
|
||||||
|
* @details If enabled then the @p chThdWait() function is included in
|
||||||
|
* the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
|
||||||
|
@ -126,7 +135,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Semaphores APIs are included in the kernel.
|
* @brief Semaphores APIs.
|
||||||
|
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
@ -134,8 +145,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then the threads are enqueued on semaphores by priority rather
|
* @brief Semaphores queuing mode.
|
||||||
* than FIFO order.
|
* @details If enabled then the threads are enqueued on semaphores by
|
||||||
|
* priority rather than in FIFO order.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE. Enable this if you have special requirements.
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -144,8 +157,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Semaphores the @p chSemWaitSignal() API is included
|
* @brief Atomic semaphore API.
|
||||||
* in the kernel.
|
* @details If enabled then the semaphores the @p chSemWaitSignal() API
|
||||||
|
* is included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -154,7 +169,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Mutexes APIs are included in the kernel.
|
* @brief Mutexes APIs.
|
||||||
|
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
|
||||||
|
@ -162,7 +179,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Conditional Variables APIs are included in the kernel.
|
* @brief Conditional Variables APIs.
|
||||||
|
* @details If enabled then the conditional variables APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_MUTEXES.
|
* @note Requires @p CH_USE_MUTEXES.
|
||||||
*/
|
*/
|
||||||
|
@ -171,7 +191,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Conditional Variables APIs are included in the kernel.
|
* @brief Conditional Variables APIs with timeout.
|
||||||
|
* @details If enabled then the conditional variables APIs with timeout
|
||||||
|
* specification are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_CONDVARS.
|
* @note Requires @p CH_USE_CONDVARS.
|
||||||
*/
|
*/
|
||||||
|
@ -180,7 +203,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Event flags APIs are included in the kernel.
|
* @brief Events Flags APIs.
|
||||||
|
* @details If enabled then the event flags APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
|
||||||
|
@ -188,8 +213,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the @p chEvtWaitXXXTimeout() functions are included in
|
* @brief Events Flags APIs with timeout.
|
||||||
* the kernel.
|
* @details If enabled then the events APIs with timeout specification
|
||||||
|
* are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_EVENTS.
|
* @note Requires @p CH_USE_EVENTS.
|
||||||
*/
|
*/
|
||||||
|
@ -198,7 +225,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Synchronous Messages APIs are included in the kernel.
|
* @brief Synchronous Messages APIs.
|
||||||
|
* @details If enabled then the synchronous messages APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
@ -206,7 +236,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled then messages are served by priority rather than in FIFO order.
|
* @brief Synchronous Messages queuing mode.
|
||||||
|
* @details If enabled then messages are served by priority rather than in
|
||||||
|
* FIFO order.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE. Enable this if you have special requirements.
|
* @note The default is @p FALSE. Enable this if you have special requirements.
|
||||||
* @note Requires @p CH_USE_MESSAGES.
|
* @note Requires @p CH_USE_MESSAGES.
|
||||||
*/
|
*/
|
||||||
|
@ -215,8 +248,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the Asynchronous Messages (Mailboxes) APIs are included
|
* @brief Mailboxes APIs.
|
||||||
* in the kernel.
|
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||||
|
* included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -225,7 +260,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the I/O queues APIs are included in the kernel.
|
* @brief I/O Queues APIs.
|
||||||
|
* @details If enabled then the I/O queues APIs are included in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_SEMAPHORES.
|
* @note Requires @p CH_USE_SEMAPHORES.
|
||||||
*/
|
*/
|
||||||
|
@ -234,9 +271,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the memory heap allocator APIs are included in the kernel.
|
* @brief Core Memory Manager APIs.
|
||||||
|
* @details If enabled then the core memory manager APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_MUTEXES or @p CH_USE_SEMAPHORES.
|
*/
|
||||||
|
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
#define CH_USE_MEMCORE TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Heap Allocator APIs.
|
||||||
|
* @details If enabled then the memory heap allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note Requires @p CH_USE_COREMEM and either @p CH_USE_MUTEXES or
|
||||||
|
* @p CH_USE_SEMAPHORES.
|
||||||
* @note Mutexes are recommended.
|
* @note Mutexes are recommended.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
|
||||||
|
@ -244,18 +296,24 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled enforces the use of the C-runtime @p malloc() and @p free()
|
* @brief C-runtime allocator.
|
||||||
* functions as backend for the system heap allocator.
|
* @details If enabled the the heap allocator APIs just wrap the C-runtime
|
||||||
|
* @p malloc() and @p free() functions.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
* @note Requires @p CH_USE_HEAP.
|
* @note Requires @p CH_USE_HEAP.
|
||||||
|
* @note The C-runtime may or may not require @p CH_USE_COREMEM, see the
|
||||||
|
* appropriate documentation.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
|
||||||
#define CH_USE_MALLOC_HEAP FALSE
|
#define CH_USE_MALLOC_HEAP FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the memory pools allocator APIs are included in the
|
* @brief Memory Pools Allocator APIs.
|
||||||
* kernel.
|
* @details If enabled then the memory pools allocator APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
|
||||||
|
@ -263,8 +321,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If specified then the dynamic threads creation APIs are included in the
|
* @brief Dynamic Threads APIs.
|
||||||
* kernel.
|
* @details If enabled then the dynamic threads creation APIs are included
|
||||||
|
* in the kernel.
|
||||||
|
*
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
* @note Requires @p CH_USE_WAITEXIT.
|
* @note Requires @p CH_USE_WAITEXIT.
|
||||||
*/
|
*/
|
||||||
|
@ -277,8 +337,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled then the checks on the API functions input
|
* @brief Debug option, parameters checks.
|
||||||
|
* @details If enabled then the checks on the API functions input
|
||||||
* parameters are activated.
|
* parameters are activated.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
|
||||||
|
@ -286,9 +348,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled then all the assertions in the kernel code are
|
* @brief Debug option, consistency checks.
|
||||||
* activated. This includes consistency checks inside the kernel, runtime
|
* @details If enabled then all the assertions in the kernel code are
|
||||||
* anomalies and port-defined checks.
|
* activated. This includes consistency checks inside the kernel,
|
||||||
|
* runtime anomalies and port-defined checks.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
|
||||||
|
@ -296,8 +360,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled the context switch circular trace buffer is
|
* @brief Debug option, trace buffer.
|
||||||
|
* @details If enabled then the context switch circular trace buffer is
|
||||||
* activated.
|
* activated.
|
||||||
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
|
||||||
|
@ -305,25 +371,37 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled a runtime stack check is performed.
|
* @brief Debug option, stack checks.
|
||||||
|
* @details If enabled then a runtime stack check is performed.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
* @note The stack check is performed in a architecture/port dependent way. It
|
* @note The stack check is performed in a architecture/port dependent way. It
|
||||||
* may not be implemented at all.
|
* may not be implemented or some ports.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
#define CH_DBG_ENABLE_STACK_CHECK FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled the threads working area is filled with a byte
|
* @brief Debug option, stacks initialization.
|
||||||
* pattern when a thread is created.
|
* @details If enabled then the threads working area is filled with a byte
|
||||||
|
* value when a thread is created. This can be useful for the
|
||||||
|
* runtime measurement of the used stack.
|
||||||
|
*
|
||||||
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_FILL_THREADS FALSE
|
#define CH_DBG_FILL_THREADS FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug option, if enabled a field is added to the @p Thread structure that
|
* @brief Debug option, threads profiling.
|
||||||
|
* @details If enabled then a field is added to the @p Thread structure that
|
||||||
* counts the system ticks occurred while executing the thread.
|
* counts the system ticks occurred while executing the thread.
|
||||||
|
*
|
||||||
|
* @note The default is @p TRUE.
|
||||||
|
* @note This debug option is defaulted to TRUE because it is required by
|
||||||
|
* some test cases into the test suite.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
|
||||||
#define CH_DBG_THREADS_PROFILING TRUE
|
#define CH_DBG_THREADS_PROFILING TRUE
|
||||||
|
@ -334,38 +412,46 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User fields added to the end of the @p Thread structure.
|
* @brief Threads descriptor structure hook.
|
||||||
|
* @details User fields added to the end of the @p Thread structure.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_FIELDS \
|
#define THREAD_EXT_FIELDS \
|
||||||
struct { \
|
struct { \
|
||||||
/* Add thread custom fields here.*/ \
|
/* Add threads custom fields here.*/ \
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User initialization code added to the @p chThdInit() API.
|
* @brief Threads initialization hook.
|
||||||
* @note It is invoked from within @p chThdInit().
|
* @details User initialization code added to the @p chThdInit() API.
|
||||||
|
*
|
||||||
|
* @note It is invoked from within @p chThdInit() and implicitily from all
|
||||||
|
* the threads creation APIs.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_INIT) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_INIT(tp) { \
|
#define THREAD_EXT_INIT(tp) { \
|
||||||
/* Add thread initialization code here.*/ \
|
/* Add threads initialization code here.*/ \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User finalization code added to the @p chThdExit() API.
|
* @brief Threads finalization hook.
|
||||||
|
* @details User finalization code added to the @p chThdExit() API.
|
||||||
|
*
|
||||||
* @note It is inserted into lock zone.
|
* @note It is inserted into lock zone.
|
||||||
|
* @note It is also invoked when the threads simply return in order to
|
||||||
|
* terminate.
|
||||||
*/
|
*/
|
||||||
#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
|
#if !defined(THREAD_EXT_EXIT) || defined(__DOXYGEN__)
|
||||||
#define THREAD_EXT_EXIT(tp) { \
|
#define THREAD_EXT_EXIT(tp) { \
|
||||||
/* Add thread finalization code here.*/ \
|
/* Add threads finalization code here.*/ \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Code inserted inside the idle thread loop immediately after an interrupt
|
* @brief Idle Loop hook.
|
||||||
* resumed execution.
|
* @details This hook is continuously invoked by the idle thread loop.
|
||||||
*/
|
*/
|
||||||
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
|
||||||
#define IDLE_LOOP_HOOK() { \
|
#define IDLE_LOOP_HOOK() { \
|
||||||
|
|
|
@ -7,6 +7,15 @@
|
||||||
Removed the old EMAC driver, updated the uIP WEB demo to use the new
|
Removed the old EMAC driver, updated the uIP WEB demo to use the new
|
||||||
driver model.
|
driver model.
|
||||||
- NEW: Added a simple lwIP demo (web server) for the AT91SAM7X.
|
- NEW: Added a simple lwIP demo (web server) for the AT91SAM7X.
|
||||||
|
- NEW: Centralized memory heap manager. This simple allocator implements a
|
||||||
|
sbrk()-like API: chCoreAlloc(). The other allocators now use this manager
|
||||||
|
in order to get memory blocks.
|
||||||
|
- NEW: The heap allocator has been modified, now it is possible to have
|
||||||
|
multiple heaps. The default heap gets its memory from the new heap manager.
|
||||||
|
- CHANGE: Because the changes in the allocators some API prototypes changed:
|
||||||
|
chHeapAlloc(), chHeapStatus(), chThdCreateFromHeap().
|
||||||
|
- CHANGE: Because the changes in the allocators some configuration options
|
||||||
|
changed, see the template chconf.h file.
|
||||||
- CHANGE: renamed ./demos/ARM7-AT91SAM7X-WEB-GCC in ARM7-AT91SAM7X-UIP-GCC.
|
- CHANGE: renamed ./demos/ARM7-AT91SAM7X-WEB-GCC in ARM7-AT91SAM7X-UIP-GCC.
|
||||||
|
|
||||||
*** 1.3.2 ***
|
*** 1.3.2 ***
|
||||||
|
|
|
@ -59,11 +59,7 @@ static char *tokp;
|
||||||
* Static working areas, the following areas can be used for threads or
|
* Static working areas, the following areas can be used for threads or
|
||||||
* used as temporary buffers.
|
* used as temporary buffers.
|
||||||
*/
|
*/
|
||||||
WORKING_AREA(waT0, THREADS_STACK_SIZE);
|
union test_buffers test;
|
||||||
WORKING_AREA(waT1, THREADS_STACK_SIZE);
|
|
||||||
WORKING_AREA(waT2, THREADS_STACK_SIZE);
|
|
||||||
WORKING_AREA(waT3, THREADS_STACK_SIZE);
|
|
||||||
WORKING_AREA(waT4, THREADS_STACK_SIZE);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pointers to the spawned threads.
|
* Pointers to the spawned threads.
|
||||||
|
@ -73,7 +69,7 @@ Thread *threads[MAX_THREADS];
|
||||||
/*
|
/*
|
||||||
* Pointers to the working areas.
|
* Pointers to the working areas.
|
||||||
*/
|
*/
|
||||||
void * const wa[5] = {waT0, waT1, waT2, waT3, waT4};
|
void * const wa[5] = {test.waT0, test.waT1, test.waT2, test.waT3, test.waT4};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Console output.
|
* Console output.
|
||||||
|
|
17
test/test.h
17
test/test.h
|
@ -47,6 +47,17 @@ struct testcase {
|
||||||
void (*execute)(void);
|
void (*execute)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union test_buffers {
|
||||||
|
struct {
|
||||||
|
WORKING_AREA(waT0, THREADS_STACK_SIZE);
|
||||||
|
WORKING_AREA(waT1, THREADS_STACK_SIZE);
|
||||||
|
WORKING_AREA(waT2, THREADS_STACK_SIZE);
|
||||||
|
WORKING_AREA(waT3, THREADS_STACK_SIZE);
|
||||||
|
WORKING_AREA(waT4, THREADS_STACK_SIZE);
|
||||||
|
};
|
||||||
|
uint8_t buffer[WA_SIZE * 5];
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -94,11 +105,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Thread *threads[MAX_THREADS];
|
extern Thread *threads[MAX_THREADS];
|
||||||
extern WORKING_AREA(waT0, THREADS_STACK_SIZE);
|
extern union test_buffers test;
|
||||||
extern WORKING_AREA(waT1, THREADS_STACK_SIZE);
|
|
||||||
extern WORKING_AREA(waT2, THREADS_STACK_SIZE);
|
|
||||||
extern WORKING_AREA(waT3, THREADS_STACK_SIZE);
|
|
||||||
extern WORKING_AREA(waT4, THREADS_STACK_SIZE);
|
|
||||||
extern void * const wa[];
|
extern void * const wa[];
|
||||||
extern bool_t test_timer_done;
|
extern bool_t test_timer_done;
|
||||||
|
|
||||||
|
|
|
@ -70,27 +70,34 @@ static msg_t thread(void *p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CH_USE_HEAP
|
#if CH_USE_HEAP
|
||||||
|
|
||||||
|
static MemoryHeap heap1;
|
||||||
|
|
||||||
static char *dyn1_gettest(void) {
|
static char *dyn1_gettest(void) {
|
||||||
|
|
||||||
return "Dynamic APIs, threads creation from heap";
|
return "Dynamic APIs, threads creation from heap";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dyn1_setup(void) {
|
||||||
|
|
||||||
|
chHeapInit(&heap1, test.buffer, sizeof(union test_buffers));
|
||||||
|
}
|
||||||
|
|
||||||
static void dyn1_execute(void) {
|
static void dyn1_execute(void) {
|
||||||
size_t n, sz;
|
size_t n, sz;
|
||||||
void *p1;
|
void *p1;
|
||||||
tprio_t prio = chThdGetPriority();
|
tprio_t prio = chThdGetPriority();
|
||||||
|
|
||||||
/* Test skipped if the heap is already fragmented. */
|
(void)chHeapStatus(&heap1, &sz);
|
||||||
if ((n = chHeapStatus(&sz)) == 1) {
|
|
||||||
/* Starting threads from the heap. */
|
/* Starting threads from the heap. */
|
||||||
threads[0] = chThdCreateFromHeap(THD_WA_SIZE(THREADS_STACK_SIZE),
|
threads[0] = chThdCreateFromHeap(&heap1, THD_WA_SIZE(THREADS_STACK_SIZE),
|
||||||
prio-1, thread, "A");
|
prio-1, thread, "A");
|
||||||
threads[1] = chThdCreateFromHeap(THD_WA_SIZE(THREADS_STACK_SIZE),
|
threads[1] = chThdCreateFromHeap(&heap1, THD_WA_SIZE(THREADS_STACK_SIZE),
|
||||||
prio-2, thread, "B");
|
prio-2, thread, "B");
|
||||||
/* Allocating the whole heap in order to make the thread creation fail.*/
|
/* Allocating the whole heap in order to make the thread creation fail.*/
|
||||||
(void)chHeapStatus(&n);
|
(void)chHeapStatus(&heap1, &n);
|
||||||
p1 = chHeapAlloc(n);
|
p1 = chHeapAlloc(&heap1, n);
|
||||||
threads[2] = chThdCreateFromHeap(THD_WA_SIZE(THREADS_STACK_SIZE),
|
threads[2] = chThdCreateFromHeap(&heap1, THD_WA_SIZE(THREADS_STACK_SIZE),
|
||||||
prio-3, thread, "C");
|
prio-3, thread, "C");
|
||||||
chHeapFree(p1);
|
chHeapFree(p1);
|
||||||
|
|
||||||
|
@ -106,14 +113,13 @@ static void dyn1_execute(void) {
|
||||||
test_assert_sequence(2, "AB");
|
test_assert_sequence(2, "AB");
|
||||||
|
|
||||||
/* Heap status checked again.*/
|
/* Heap status checked again.*/
|
||||||
test_assert(3, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(3, chHeapStatus(&heap1, &n) == 1, "heap fragmented");
|
||||||
test_assert(4, n == sz, "heap size changed");
|
test_assert(4, n == sz, "heap size changed");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct testcase testdyn1 = {
|
const struct testcase testdyn1 = {
|
||||||
dyn1_gettest,
|
dyn1_gettest,
|
||||||
NULL,
|
dyn1_setup,
|
||||||
NULL,
|
NULL,
|
||||||
dyn1_execute
|
dyn1_execute
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
|
|
||||||
#define SIZE 16
|
#define SIZE 16
|
||||||
|
|
||||||
|
static MemoryHeap test_heap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page test_heap_001 Allocation and fragmentation test
|
* @page test_heap_001 Allocation and fragmentation test
|
||||||
*
|
*
|
||||||
|
@ -66,74 +68,73 @@ static char *heap1_gettest(void) {
|
||||||
return "Heap, allocation and fragmentation test";
|
return "Heap, allocation and fragmentation test";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void heap1_setup(void) {
|
||||||
|
|
||||||
|
chHeapInit(&test_heap, test.buffer, sizeof(union test_buffers));
|
||||||
|
}
|
||||||
|
|
||||||
static void heap1_execute(void) {
|
static void heap1_execute(void) {
|
||||||
void *p1, *p2, *p3;
|
void *p1, *p2, *p3;
|
||||||
size_t n, sz;
|
size_t n, sz;
|
||||||
|
|
||||||
/* Test skipped if the heap is already fragmented. */
|
/* Test skipped if the heap is already fragmented. */
|
||||||
if ((n = chHeapStatus(&sz)) == 1) {
|
(void)chHeapStatus(&test_heap, &sz);
|
||||||
test_print("--- Size : ");
|
test_print("--- Size : ");
|
||||||
test_printn(sz);
|
test_printn(sz);
|
||||||
test_println(" bytes, not fragmented");
|
test_println(" bytes");
|
||||||
|
|
||||||
/* Same order */
|
/* Same order */
|
||||||
p1 = chHeapAlloc(SIZE);
|
p1 = chHeapAlloc(&test_heap, SIZE);
|
||||||
p2 = chHeapAlloc(SIZE);
|
p2 = chHeapAlloc(&test_heap, SIZE);
|
||||||
p3 = chHeapAlloc(SIZE);
|
p3 = chHeapAlloc(&test_heap, SIZE);
|
||||||
chHeapFree(p1); /* Does not merge */
|
chHeapFree(p1); /* Does not merge */
|
||||||
chHeapFree(p2); /* Merges backward */
|
chHeapFree(p2); /* Merges backward */
|
||||||
chHeapFree(p3); /* Merges both sides */
|
chHeapFree(p3); /* Merges both sides */
|
||||||
test_assert(1, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(1, chHeapStatus(&test_heap, &n) == 1, "heap fragmented");
|
||||||
|
|
||||||
/* Reverse order */
|
/* Reverse order */
|
||||||
p1 = chHeapAlloc(SIZE);
|
p1 = chHeapAlloc(&test_heap, SIZE);
|
||||||
p2 = chHeapAlloc(SIZE);
|
p2 = chHeapAlloc(&test_heap, SIZE);
|
||||||
p3 = chHeapAlloc(SIZE);
|
p3 = chHeapAlloc(&test_heap, SIZE);
|
||||||
chHeapFree(p3); /* Merges forward */
|
chHeapFree(p3); /* Merges forward */
|
||||||
chHeapFree(p2); /* Merges forward */
|
chHeapFree(p2); /* Merges forward */
|
||||||
chHeapFree(p1); /* Merges forward */
|
chHeapFree(p1); /* Merges forward */
|
||||||
test_assert(2, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(2, chHeapStatus(&test_heap, &n) == 1, "heap fragmented");
|
||||||
|
|
||||||
/* Small fragments handling */
|
/* Small fragments handling */
|
||||||
p1 = chHeapAlloc(SIZE + 1);
|
p1 = chHeapAlloc(&test_heap, SIZE + 1);
|
||||||
p2 = chHeapAlloc(SIZE);
|
p2 = chHeapAlloc(&test_heap, SIZE);
|
||||||
chHeapFree(p1);
|
chHeapFree(p1);
|
||||||
test_assert(3, chHeapStatus(&n) == 2, "invalid state");
|
test_assert(3, chHeapStatus(&test_heap, &n) == 2, "invalid state");
|
||||||
p1 = chHeapAlloc(SIZE);
|
p1 = chHeapAlloc(&test_heap, SIZE);
|
||||||
test_assert(4, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(4, chHeapStatus(&test_heap, &n) == 1, "heap fragmented");
|
||||||
chHeapFree(p2);
|
chHeapFree(p2);
|
||||||
chHeapFree(p1);
|
chHeapFree(p1);
|
||||||
test_assert(5, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(5, chHeapStatus(&test_heap, &n) == 1, "heap fragmented");
|
||||||
|
|
||||||
/* Skip fragment handling */
|
/* Skip fragment handling */
|
||||||
p1 = chHeapAlloc(SIZE);
|
p1 = chHeapAlloc(&test_heap, SIZE);
|
||||||
p2 = chHeapAlloc(SIZE);
|
p2 = chHeapAlloc(&test_heap, SIZE);
|
||||||
chHeapFree(p1);
|
chHeapFree(p1);
|
||||||
test_assert(6, chHeapStatus(&n) == 2, "invalid state");
|
test_assert(6, chHeapStatus(&test_heap, &n) == 2, "invalid state");
|
||||||
p1 = chHeapAlloc(SIZE * 2); /* Skips first fragment */
|
p1 = chHeapAlloc(&test_heap, SIZE * 2); /* Skips first fragment */
|
||||||
chHeapFree(p1);
|
chHeapFree(p1);
|
||||||
chHeapFree(p2);
|
chHeapFree(p2);
|
||||||
test_assert(7, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(7, chHeapStatus(&test_heap, &n) == 1, "heap fragmented");
|
||||||
|
|
||||||
/* Allocate all handling */
|
/* Allocate all handling */
|
||||||
(void)chHeapStatus(&n);
|
(void)chHeapStatus(&test_heap, &n);
|
||||||
p1 = chHeapAlloc(n);
|
p1 = chHeapAlloc(&test_heap, n);
|
||||||
test_assert(8, chHeapStatus(&n) == 0, "not empty");
|
test_assert(8, chHeapStatus(&test_heap, &n) == 0, "not empty");
|
||||||
chHeapFree(p1);
|
chHeapFree(p1);
|
||||||
|
|
||||||
test_assert(9, chHeapStatus(&n) == 1, "heap fragmented");
|
test_assert(9, chHeapStatus(&test_heap, &n) == 1, "heap fragmented");
|
||||||
test_assert(10, n == sz, "size changed");
|
test_assert(10, n == sz, "size changed");
|
||||||
}
|
|
||||||
else {
|
|
||||||
test_print("--- Size : ");
|
|
||||||
test_printn(sz);
|
|
||||||
test_println(" bytes, fragmented, test skipped");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct testcase testheap1 = {
|
const struct testcase testheap1 = {
|
||||||
heap1_gettest,
|
heap1_gettest,
|
||||||
NULL,
|
heap1_setup,
|
||||||
NULL,
|
NULL,
|
||||||
heap1_execute
|
heap1_execute
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
* variables are explicitly initialized in each test case. It is done in order
|
* variables are explicitly initialized in each test case. It is done in order
|
||||||
* to test the macros.
|
* to test the macros.
|
||||||
*/
|
*/
|
||||||
static MAILBOX_DECL(mb1, waT0, MB_SIZE);
|
static MAILBOX_DECL(mb1, test.waT0, MB_SIZE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page test_mbox_001 Queuing and timeouts
|
* @page test_mbox_001 Queuing and timeouts
|
||||||
|
@ -77,7 +77,7 @@ static char *mbox1_gettest(void) {
|
||||||
|
|
||||||
static void mbox1_setup(void) {
|
static void mbox1_setup(void) {
|
||||||
|
|
||||||
chMBInit(&mb1, (msg_t *)waT0, MB_SIZE);
|
chMBInit(&mb1, (msg_t *)test.waT0, MB_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mbox1_execute(void) {
|
static void mbox1_execute(void) {
|
||||||
|
|
|
@ -63,8 +63,8 @@ static void notify(void) {}
|
||||||
* variables are explicitly initialized in each test case. It is done in order
|
* variables are explicitly initialized in each test case. It is done in order
|
||||||
* to test the macros.
|
* to test the macros.
|
||||||
*/
|
*/
|
||||||
static INPUTQUEUE_DECL(iq, waT0, TEST_QUEUES_SIZE, notify);
|
static INPUTQUEUE_DECL(iq, test.waT0, TEST_QUEUES_SIZE, notify);
|
||||||
static OUTPUTQUEUE_DECL(oq, waT0, TEST_QUEUES_SIZE, notify);
|
static OUTPUTQUEUE_DECL(oq, test.waT1, TEST_QUEUES_SIZE, notify);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @page test_queues_001 Input Queues functionality and APIs
|
* @page test_queues_001 Input Queues functionality and APIs
|
||||||
|
|
Loading…
Reference in New Issue