Skip to content

Commit

Permalink
[freertos] Add better configuration management
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Apr 11, 2021
1 parent ad2ef4b commit 0daed77
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 121 deletions.
220 changes: 129 additions & 91 deletions ext/aws/FreeRTOSConfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,119 +35,157 @@ your application. */
#include <modm/architecture/utils.hpp>
#include <modm/platform/device.hpp>

/* Define to trap errors during development. */
#define configASSERT( x ) { modm_assert((x), "freertos", __FILE__, MODM_STRINGIFY(__LINE__)); }

// declared in modm:platform:clock
#ifdef __cplusplus
extern "C" uint32_t SystemCoreClock;
#else
extern uint32_t SystemCoreClock;
#endif

#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION {{ ("m0" not in core) | int }}
#define configUSE_TICKLESS_IDLE 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( {{ options["::frequency"] }} )
#define configMAX_PRIORITIES 5
#define configMINIMAL_STACK_SIZE 128
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 10
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5


#define configTICK_RATE_HZ ( {{ frequency }} )
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE 0 // modm provides heap
#define configAPPLICATION_ALLOCATED_HEAP 1

/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
// used by modm:platform:clock for modm::Clock::increment(): vApplicationTickHook()
#define configUSE_TICK_HOOK 1
#define configCHECK_FOR_STACK_OVERFLOW 1
#define configUSE_MALLOC_FAILED_HOOK 0 // modm provides heap assertions
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0

/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_STATS_FORMATTING_FUNCTIONS 0

/* Co-routine related definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 1

/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 3
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE

/* Define to trap errors during development. */
#define configASSERT( x ) { modm_assert((x), "freertos.assert", __FILE__, MODM_STRINGIFY(__LINE__)); }

/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0

/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 1


/* __NVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 4

/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configKERNEL_INTERRUPT_PRIORITY (((1u << __NVIC_PRIO_BITS) - 1u) << (8u - __NVIC_PRIO_BITS))

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler


/* A header file that overwrites with local project settings. */
#if __has_include(<FreeRTOSConfigLocal.h>)
#include <FreeRTOSConfigLocal.h>
# include <FreeRTOSConfigLocal.h>
#endif


/* Required config by FreeRTOS and defaulted by modm */

/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#ifndef configMAX_SYSCALL_INTERRUPT_PRIORITY
# define configMAX_SYSCALL_INTERRUPT_PRIORITY (__NVIC_PRIO_BITS << (8u - __NVIC_PRIO_BITS))
#endif

#ifndef configMINIMAL_STACK_SIZE
# define configMINIMAL_STACK_SIZE 128
#endif
#ifndef configMAX_PRIORITIES
# define configMAX_PRIORITIES 5
#endif
#ifndef configUSE_PREEMPTION
# define configUSE_PREEMPTION 1
#endif
#ifndef configUSE_IDLE_HOOK
# define configUSE_IDLE_HOOK 0
#endif
#ifndef configUSE_16_BIT_TICKS
# define configUSE_16_BIT_TICKS 0
#endif

/* Defaulted by FreeRTOS but changed by modm */

#ifndef configUSE_MUTEXES
# define configUSE_MUTEXES 1
#endif
#ifndef configUSE_RECURSIVE_MUTEXES
# define configUSE_RECURSIVE_MUTEXES 1
#endif
#ifndef configUSE_COUNTING_SEMAPHORES
# define configUSE_COUNTING_SEMAPHORES 1
#endif
#ifndef configQUEUE_REGISTRY_SIZE
# define configQUEUE_REGISTRY_SIZE 10
#endif
#ifndef configENABLE_BACKWARD_COMPATIBILITY
# define configENABLE_BACKWARD_COMPATIBILITY 0
#endif
#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS
# define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
#endif
#ifndef configCHECK_FOR_STACK_OVERFLOW
# define configCHECK_FOR_STACK_OVERFLOW 1
#endif

/* The timers module relies on xTaskGetSchedulerState(). */
#ifndef configUSE_TIMERS
# define configUSE_TIMERS 1
#endif
#ifndef configTIMER_TASK_PRIORITY
# define configTIMER_TASK_PRIORITY 3
#endif
#ifndef configTIMER_QUEUE_LENGTH
# define configTIMER_QUEUE_LENGTH 10
#endif
#ifndef configTIMER_TASK_STACK_DEPTH
# define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
#endif

/* Optional functions all enabled. */
#ifndef INCLUDE_vTaskPrioritySet
# define INCLUDE_vTaskPrioritySet 1
#endif
#ifndef INCLUDE_uxTaskPriorityGet
# define INCLUDE_uxTaskPriorityGet 1
#endif
#ifndef INCLUDE_vTaskDelete
# define INCLUDE_vTaskDelete 1
#endif
#ifndef INCLUDE_vTaskSuspend
# define INCLUDE_vTaskSuspend 1
#endif
#ifndef INCLUDE_xTaskDelayUntil
# define INCLUDE_xTaskDelayUntil 1
#endif
#ifndef INCLUDE_vTaskDelay
# define INCLUDE_vTaskDelay 1
#endif
#ifndef INCLUDE_xTaskGetIdleTaskHandle
# define INCLUDE_xTaskGetIdleTaskHandle 1
#endif
#ifndef INCLUDE_xTaskAbortDelay
# define INCLUDE_xTaskAbortDelay 1
#endif
#ifndef INCLUDE_xQueueGetMutexHolder
# define INCLUDE_xQueueGetMutexHolder 1
#endif
#ifndef INCLUDE_xSemaphoreGetMutexHolder
# define INCLUDE_xSemaphoreGetMutexHolder 1
#endif
#ifndef INCLUDE_xTaskGetHandle
# define INCLUDE_xTaskGetHandle 1
#endif
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
# define INCLUDE_uxTaskGetStackHighWaterMark 1
#endif
#ifndef INCLUDE_uxTaskGetStackHighWaterMark2
# define INCLUDE_uxTaskGetStackHighWaterMark2 1
#endif
#ifndef INCLUDE_eTaskGetState
# define INCLUDE_eTaskGetState 1
#endif
#ifndef INCLUDE_xTaskResumeFromISR
# define INCLUDE_xTaskResumeFromISR 1
#endif
#ifndef INCLUDE_xTimerPendFunctionCall
# define INCLUDE_xTimerPendFunctionCall 1
#endif
#ifndef INCLUDE_xTaskGetSchedulerState
# define INCLUDE_xTaskGetSchedulerState 1
#endif
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
# define INCLUDE_xTaskGetCurrentTaskHandle 1
#endif

#endif /* FREERTOS_CONFIG_H */
Expand Down
70 changes: 70 additions & 0 deletions ext/aws/freertos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# FreeRTOS

Amazon FreeRTOS is an open source, real-time operating system (RTOS) for
microcontrollers in small, low-power devices.

This module provides the latest FreeRTOS LTS release integrated with modm:

- Chooses the right Cortex-M port for the target.
- Variable tick rate integrated with `modm::Clock` via `modm:platform:clock`.
- Dynamic memory provided by the `modm:platform:heap` module with thread-safe
locking of Newlib's `malloc/free`.
- Assertions integrated into the `modm:architecture:assert` interface.
- Interrupt handling integrated with CMSIS NVIC functions.

Note that we recommend using the FreeRTOS API directly and only if you write
threaded code that also runs on other platforms (x86 simulators for example)
should you consider using the API defined in `modm:processing:rtos` module.


## Configuration

This module generates a `FreeRTOSConfig.h` config file for modm integration with
these settings:

- `configASSERT(x)` implemented with `modm_assert(x, "freertos")`.
- `configCPU_CLOCK_HZ` implemented with CMSIS `SystemCoreClock`.
- `configTICK_RATE_HZ` set to `modm:freertos:frequency` or 1kHz on Cortex-M0.
- `configSUPPORT_DYNAMIC_ALLOCATION = 1` as implemented by `modm:platform:heap`.
- `configUSE_TICK_HOOK = 1` used by `modm:platform:clock` to provide `modm::Clock`.

In addition we define these overwritable default settings:

- `configMAX_SYSCALL_INTERRUPT_PRIORITY` = `(__NVIC_PRIO_BITS << (8u - __NVIC_PRIO_BITS))`

- `configMINIMAL_STACK_SIZE` = 128
- `configMAX_PRIORITIES` = 5
- `configUSE_PREEMPTION` = 1
- `configUSE_IDLE_HOOK` = 0
- `configUSE_16_BIT_TICKS` = 0

- `configUSE_MUTEXES` = 1
- `configUSE_RECURSIVE_MUTEXES` = 1
- `configUSE_COUNTING_SEMAPHORES` = 1
- `configQUEUE_REGISTRY_SIZE` = 10
- `configNUM_THREAD_LOCAL_STORAGE_POINTERS` = 5
- `configCHECK_FOR_STACK_OVERFLOW` = 1

- `configUSE_TIMERS` = 1
- `configTIMER_TASK_PRIORITY` = 3
- `configTIMER_QUEUE_LENGTH` = 10
- `configTIMER_TASK_STACK_DEPTH` = `configMINIMAL_STACK_SIZE`

All other config settings are unchanged by modm and are defaulted by FreeRTOS
itself, please refer to the [FreeRTOS Config documentation][config] to
understand what each of these do.

To change a configuration setting, define a `<FreeRTOSConfigLocal.h>` file,
which is included *before* the optional settings, so you can overwrite them
easily.

An example `<FreeRTOSConfigLocal.h>` file:

```c
// Use a bigger minimal stack size
#define configMINIMAL_STACK_SIZE 256
// Longer timer queue
#define configTIMER_QUEUE_LENGTH 20
```
[config]: https://www.freertos.org/a00110.html
43 changes: 18 additions & 25 deletions ext/aws/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -71,41 +71,31 @@ the config macros, then redefine them with your options, for example:

def init(module):
module.name = "freertos"
module.description = """\
# a:FreeRTOS
Amazon FreeRTOS port for modm to be used with via the `modm:processing:rtos` module.
## Custom Configuration
This module defines a default FreeRTOS config. If you need to change a
configuration setting, then you can define a `FreeRTOSConfigLocal.h` file, which
is included *after* at the end of the config. You must therefore first `#undef`
the config macros, then redefine them with your options, for example:
```c
#undef configCHECK_FOR_STACK_OVERFLOW
#define configCHECK_FOR_STACK_OVERFLOW 0
```
"""
module.description = FileReader("freertos.md")

def prepare(module, options):
device = options[":target"]
core = device.get_driver("core")
if not (core and core["type"].startswith("cortex-m")):
return False

module.add_option(
NumericOption(
name="frequency",
description="Context switch frequency in Hz",
minimum=1, maximum=1000,
default=1000))
if "m0" not in core:
def validate_frequency(freq):
if (1000 % freq > 1):
raise ValueError("FreeRTOS frequency must cleanly divide 1kHz for modm::Clock!")
module.add_option(
NumericOption(
name="frequency",
description="Context switch frequency in Hz",
validate=validate_frequency,
minimum=4, maximum=1000,
default=1000))

module.depends(
":architecture:assert",
":cmsis:device",
":platform:clock")
":platform:clock",
":platform:heap")

module.add_submodule(FreeRTOS_TCP())

Expand All @@ -114,7 +104,10 @@ def prepare(module, options):
def build(env):
# Figure out the core and correct path in portable/
core = env[":target"].get_driver("core")["type"]
env.substitutions = {"core": core}
env.substitutions = {
"core": core,
"frequency": env.get("frequency", 1000)
}
path = core.replace("cortex-m", "ARM_CM").replace("+", "").replace("fd", "f").upper()
path = path.replace("CM7F", "CM7/r0p1") # use subfolder for M7
path = "freertos/FreeRTOS/Source/portable/GCC/{}".format(path)
Expand Down
2 changes: 1 addition & 1 deletion repo.lb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ from os.path import normpath

# Check for miminum required lbuild version
import lbuild
min_lbuild_version = "1.16.1"
min_lbuild_version = "1.17.0"
if StrictVersion(getattr(lbuild, "__version__", "0.1.0")) < StrictVersion(min_lbuild_version):
print("modm requires at least lbuild v{}, please upgrade!\n"
" pip3 install -U lbuild".format(min_lbuild_version))
Expand Down
Loading

0 comments on commit 0daed77

Please sign in to comment.