Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[freertos] allow use FreeRTOS without heap dependency #750

Merged
merged 2 commits into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/processing/rtos.hpp>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <freertos/task.h>

using namespace modm::platform;

/**
* This example uses four threads to check if task switching works correctly.
*
* It also check if the FreeRTOS TCP stack can be compiled.
* No TCP functionality in this example (yet).
*
* What to expect?
* ---------------
* - All our LEDs blinking at different rates, about 3 to 4 Hz
Expand All @@ -38,27 +37,43 @@ using namespace modm::platform;
*/

// ----------------------------------------------------------------------------
SemaphoreHandle_t semaphore = nullptr;
StaticSemaphore_t semaphoreBuffer;

template <typename Gpio, int SleepTime>
class P: modm::rtos::Thread
class P
{
char c;
uint8_t i = 0;
volatile float a = 10.f;
TaskHandle_t task;
StaticTask_t taskBuffer;
StackType_t stack[1024/4];
public:
P(char c): Thread(2,1<<10), c(c) {}
P(char c): c(c)
{
xTaskCreateStatic(
[](void* obj) { reinterpret_cast<P*>(obj)->run(); },
"anon",
(1024 / 4),
this,
2,
stack,
&taskBuffer);
}

void run()
{
Gpio::setOutput();
while (true)
{
sleep(SleepTime * MILLISECONDS);
vTaskDelay(SleepTime * (configTICK_RATE_HZ / 1000.0));

Gpio::toggle();
{
static modm::rtos::Mutex lm;
modm::rtos::MutexGuard m(lm);
xSemaphoreTake(semaphore, portMAX_DELAY);
MODM_LOG_INFO << char(i + c);
xSemaphoreGive(semaphore);
}
i = (i+1)%10;
a *= 3.141f;
Expand All @@ -70,12 +85,14 @@ P< Board::LedRed, 260 > p1('0');
P< Board::LedGreen, 260 + 10 > p2('a');
P< Board::LedBlue, 260 + 20 > p3('A');


// ----------------------------------------------------------------------------
int
main()
{
Board::initialize();
modm::rtos::Scheduler::schedule();

semaphore = xSemaphoreCreateMutexStatic(&semaphoreBuffer);
vTaskStartScheduler();

return 0;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<library>
<extends>modm:nucleo-f429zi</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_f429zi/freertos_plus_tcp</option>
<option name="modm:build:build.path">../../../build/nucleo_f429zi/freertos_static</option>
</options>
<modules>
<module>modm:processing:rtos</module>
<module>modm:freertos:tcp</module>
<module>modm:freertos</module>
<module>modm:build:scons</module>
</modules>
</library>
4 changes: 2 additions & 2 deletions ext/aws/FreeRTOSConfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ your application. */
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( {{ frequency }} )
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION {{ 0 if with_heap else 1 }}
#define configSUPPORT_DYNAMIC_ALLOCATION {{ 1 if with_heap else 0 }}
// used by modm:platform:clock for modm::Clock::increment(): vApplicationTickHook()
#define configUSE_TICK_HOOK 1

Expand Down
3 changes: 2 additions & 1 deletion ext/aws/freertos.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ 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`.
- `configSUPPORT_DYNAMIC_ALLOCATION = 1` only if used with `modm:platform:heap`.
- `configSUPPORT_STATIC_ALLOCATION = 1` only if used without `modm:platform:heap`.
- `configUSE_TICK_HOOK = 1` used by `modm:platform:clock` to provide `modm::Clock`.

In addition we define these overwritable default settings:
Expand Down
28 changes: 28 additions & 0 deletions ext/aws/modm_port.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ void vApplicationStackOverflowHook(TaskHandle_t /*pxTask*/, char *pcTaskName)
modm_assert(false, "freertos.stack", "FreeRTOS detected a stack overflow!", pcTaskName);
}

%% if with_heap
// ----------------------------------------------------------------------------
// Make the Newlib heap thread-safe with FreeRTOS

Expand Down Expand Up @@ -64,6 +65,33 @@ void vPortFree(void *pv)
traceFREE(pv, 0);
}
}
%% else
#if configUSE_TIMERS == 1
static StaticTask_t timers_task_storage;
static StackType_t timers_task_stack_storage[configTIMER_TASK_STACK_DEPTH];
extern "C"
void vApplicationGetTimerTaskMemory(StaticTask_t** ppxTimerTaskTCBBuffer,
StackType_t** ppxTimerTaskStackBuffer,
uint32_t* pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer = &timers_task_storage;
*ppxTimerTaskStackBuffer = timers_task_stack_storage;
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
#endif

static StaticTask_t idle_task_storage;
static StackType_t idle_task_stack_storage[configMINIMAL_STACK_SIZE];
extern "C"
void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer,
StackType_t** ppxIdleTaskStackBuffer,
uint32_t* pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer = &idle_task_storage;
*ppxIdleTaskStackBuffer = idle_task_stack_storage;
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
%% endif

%% if with_debug
#include <modm/debug.hpp>
Expand Down
6 changes: 3 additions & 3 deletions ext/aws/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ def prepare(module, options):
module.depends(
":architecture:assert",
":cmsis:device",
":platform:clock",
":platform:heap")
":platform:clock")

module.add_submodule(FreeRTOS_TCP())

Expand All @@ -95,7 +94,8 @@ def build(env):
env.substitutions = {
"core": core,
"frequency": env.get("frequency", 1000),
"with_debug": env.has_module(":debug")
"with_debug": env.has_module(":debug"),
"with_heap": env.has_module(":platform:heap"),
}
path = core.replace("cortex-m", "ARM_CM").replace("+", "").replace("fd", "f").upper()
path = path.replace("CM7F", "CM7/r0p1") # use subfolder for M7
Expand Down
2 changes: 1 addition & 1 deletion src/modm/processing/rtos/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def prepare(module, options):
return False

if options[":target"].identifier["platform"] not in ["hosted"]:
module.depends(":freertos")
module.depends(":freertos",":platform:heap")

return True

Expand Down