-
Notifications
You must be signed in to change notification settings - Fork 2
Home
-
core/kconfig.hcontains defines to enable or disable features and other critical configurations. -
It is essential that the number of tasks in your application matches the number defined in
RK_CONF_N_USRTASKS, and the lowest effective priority value (the highest number) is defined inRK_CONF_MIN_PRIO(maximum is 31). -
Stack Sizes:
-
Stack addresses are to be aligned to an 8-byte boundary, and the stack size must be a multiple of 8. Failing to follow these rules will end up on a crash, sooner or later.
-
If you’re using application timers, the stack size of the system task that runs the callouts might need to be adjusted on
RK_CONF_TIMHANDLER_STACKSIZE. Remember, this value is in words (a word has 4 bytes). If you’re including any hooks on the IdleTask, also adjustRK_CONF_IDLE_STACKSIZE. -
As a rule of thumb, the minimal stack size for a task should be 64 WORDs if little work is performed (and FPU is not enabled).
-
If FPU is enabled and the task uses float-point unit math, 96 WORDs is the theoretical minimum. You probably need more.
-
System Stack: initial size is defined on
linker.ld, symbolMin_Stack_Size. In this case, you need to account for the depth ofmain(),kApplicationInit(), and all interrupt handlers. Assume interrupts will always add to the worst static depth, and make sure to account for nested interrupts.
-
app\application.c
#include <board.h> /* platform specific */
#include <kapi.h> /* kernel api */
#include <application.h> /* application specific */
int main(void)
{
HAL_Init(); /* board init plls, io, etc. */
otherInits(); /* 3rd party init filesystems, comm stacks etc */
/* RK0 API */
kCoreInit(); /* init minimal core interrupts for the kernel */
kInit(); /* init scheduler */
while(1)
{
/* suggested */
kErrHandler(RK_FAULT_APP_CRASH);
}
}
/*** Declare kernel objects ***/
/* -- Tasks: */
/* this convenience macro */
RK_DECLARE(t1Handle, Task1, task1StackBuf, 128)
/* expands to:
VOID Task1(VOID *args);
RK_STACK task1StackBuf[128] K_ALIGN(8);
RK_TASK_HANDLE t1Handle;
/*
/* RK_ prefixed macros don’t require a trailing ‘;’ */
/* -- Other objects: e.g., mem allocator, mesg queues, semaphores, etc.,
and any backing storage they need
*/
RK_OBJ_TYPE objInstance;
myAppType_t typeMemPool[N_BLOCKS] K_ALIGN(4);
/* Mandatory function: initialise tasks and other objects */
VOID ApplicationInit(VOID)
{
/* initialise tasks and other kernel objects */
/* low-level scheduler will start when this function returns */
/* use assertions for init calls */
/* see kapi.h */
}
/* Define Tasks */
/* all task objects must be visible for the unit which
task functions are defined */
VOID Task1(VOID* args)
{
K_UNUSE(args);
while(1)
{
/* task will run until preempted by a higher priority task,
blocking or yielding
(there is no built-in time-slice in the scheduler)
See the scheduler behaviour (Handling the scheduler section)
in the Docbook
*/
}
}-
Sections explaining the QEMU building system and its integration to VSCode on macOS, Windows, and Linux are available on the Wiki links.
-
A comprehensive Docbook explains kernel mechanisms (including the design rationale) and usage examples.
-
Besides the QEMU build (on this repository), there are builds for Nucleo boards (on a wiki page). One of these builds doesn’t assume any IDE, and there’s a project for STM32CubeIDE. These can guide you on how to structure your design.
-
Currently the kernel only compiles with ARM-GCC and needs the CMSIS-GCC interface (found in
core\inc\cmsis_gcc.h).
Copyright (C) 2025 Antonio Giacomelli | www.kernel0.org