System Setup (sl_main)#
System Setup (sl_main)
Main Init memory#
Main memory init provides a function to do permanent memory allocations:
sli_allocate_permanent_memory()
Handlers can be registered for the following events using the Event Handler API provided by the Event Handler component:
driver_permanent_allocation -> sli_driver_permanent_allocation()
service_permanent_allocation -> sli_service_permanent_allocation()
stack_permanent_allocation -> sli_stack_permanent_allocation()
internal_permanent_allocation -> sli_internal_permanent_allocation()
After the handlers are called, the function app_permanent_memory_alloc() is called to allocate permanent memory blocks for the application.
This ensures an optimal RAM placement for efficient memory usage.
Overview#
The sl_main component manages the initialization phase of SiSDK embedded firmware. This component aggregates, organizes and executes all the different steps required for initializing the firmware so that every component in your .slcp file and their dependencies are in a ready state for proper execution. Application developers may also initialize different parts of their application by re-implementing hooks that are called at key points within the sl_main initialization sequence.
Configuration#
The only configurations available to sl_main are for the start task in:
sl_main_start_task_config.h
This header files offer a few configurations for sl_main when using an RTOS. They use the CMSIS Configuration Wizard Annotations that can be rendered by Simplicity Studio to set graphically the configuration settings value.
Here is a list of the available configurations:
SL_MAIN_START_TASK_STACK_SIZE_BYTES allows to configure the stack size for the start task. The default value of 4096 bytes.
SL_MAIN_ENABLE_START_TASK_PRIORITY_CHANGE allows the start task to change it's priority after the initialization process is done.
Note
The new priority will take effect just before the call to
app_init()
. The start task will always start at maximum priority (osPriorityRealtime7
) regardless of this configuration option.
SL_MAIN_START_TASK_PRIORITY Sets the priority of the start task after initialization is done.
@note This configuration is only available when
SL_MAIN_ENABLE_START_TASK_PRIORITY_CHANGE is set to 1.
The start task will always start at maximum priority (`osPriorityRealtime7`)
regardless of this configuration option.
Main Init#
Main Init provides a function for initializing the system and the products:
This function calls a hardcoded sequence of functions that are executed in order.
This function is called the second stage init, it calls a set of functions that are automatically generated and located in autogen/sl_event_handler.c
. Handlers can be registered for the following events using the Event Handler API provided by the Event Handler component:
platform_init -> sl_platform_init()
driver_init -> sl_driver_init()
service_init -> sl_service_init()
stack_init -> sl_stack_init()
internal_app_init -> sl_internal_app_init()
These events are fired in the order listed above when sl_main_init()
is called. If an RTOS is included in the project the sl_main_second_stage_init function will be called after the OS kernel is started.
Main Kernel#
Main Kernel component provides an API to:
sl_main_kernel_start(): Starts the kernel
sl_main_start_task_should_continue(): Determines if the start task should continue after the initialization process is done. (templated main only)
sl_main_kernel_start() function calls a function that is automatically generated and located in $autogen/sl_event_handler.c
. Handlers can be registered for the following events using the Event Handler API provided by the Event Handler component:
kernel_start -> sl_kernel_start()
The event is fired when sl_main_kernel_start()
is called.
sl_main_kernel_start() is called automatically by the main re-target from main_retarget.c. Users should not call this API themselves.
sl_main_start_task_should_continue() returns false by default to stop the start task after the initialization process is done. It can be redefined by the user to allow the start task to continue executing after the initialization process is done. Keep in mind that this function is called in the templated main function provided by sl_main, if you removed the call to sl_main_start_task_should_continue
in your main function then re-implementing this function will have no effect.
@note By default, when using Micrium OS, the start task's resources — such as
its stack and Task Control Block (TCB) — are not released upon task exit,
which can result in a memory leak. To avoid this, enable Micrium OS garbage
collection. Note that enabling garbage collection may significantly increase
both RAM and flash usage.
The following code snippet shows how to implement this function to allow the start task to continue:
bool sl_main_start_task_should_continue(void)
{
return true; // start task will continue after initialization.
}
Main Process Action#
Main Process Action component provides a function for running the products from a super loop:
This function calls a set of functions that are automatically generated and located in $autogen/sl_event_handler.c
. Handlers can be registered for the following events using the Event Handler API provided by the Event Handler component:
platform_process_action -> sli_platform_process_action()
service_process_action -> sli_service_process_action()
stack_process_action -> sli_stack_process_action()
internal_app_process_action -> sli_internal_app_process_action()
These events are fired in the order listed above when sl_main_process_action()
is called.
Usage example in baremetal application:
#include "sl_component_catalog.h"
#include "sl_main_init.h"
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif
#include "sl_main_process_action.h"
int main(void)
{
// Initialize Silicon Labs device, system, service(s) and protocol stack(s).
// Note that if the kernel is present, the start task will be started and software
// component initialization will take place there.
sl_main_init();
// User provided code
app_init();
while (1) {
// Silicon Labs components process action routine
// must be called from the super loop.
sl_main_process_action();
// User provided code. Application process.
app_process_action();
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
// Let the CPU go to sleep if the system allows it.
sl_power_manager_sleep();
#endif
}
#endif // SL_CATALOG_KERNEL_PRESENT
}
In RTOS applications, this API is never called:
#include "sl_main_init.h"
#include "sl_main_kernel.h"
int main(void)
{
// In case of RTOS, only the second stage (initialize stage) would be performed.
sl_main_second_stage_init();
// User provided code
app_init();
while (1) {
}
#endif // SL_CATALOG_KERNEL_PRESENT
}
Functions#
User-defined function for initializing application memory allocations.
Actions to perform periodically from the main loop.
Start the kernel.
User-defined function to determine if the start task should continue.
User-defined function for pre-clock app initialization.
User-defined function for early app initialization.
User-defined function for app initialization.
User-defined function to process a baremetal action periodically.
Main entry function calling key platform modules initialization functions.
Internal function used to aggregate driver, services stacks and internal apps initialization function.
Function Documentation#
app_permanent_memory_alloc#
void app_permanent_memory_alloc (void )
User-defined function for initializing application memory allocations.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
Note
Will be automatically called after silicon labs platform and stacks components are initialized.
sl_main_process_action#
void sl_main_process_action (void )
Actions to perform periodically from the main loop.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
Note
(1) For baremetal applications, this function is called from the main function in an infinite loop.
(2) For RTOS applications, after configuring the start task to continue executing, this function is called from the main function in an infinite loop.
sl_main_kernel_start#
void sl_main_kernel_start (void )
Start the kernel.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
sl_main_start_task_should_continue#
bool sl_main_start_task_should_continue (void )
User-defined function to determine if the start task should continue.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
Returns
true if the start task should continue, false otherwise.
Note
By default the start task should not continue, but this function can be re-implemented to force the start task to continue running.
app_init_pre_clock#
void app_init_pre_clock (void )
User-defined function for pre-clock app initialization.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
This function is called from sli_main_init():
Before essential infrastructure components are initialized (memory management, clock, oscillators, interrupt management, etc.).
app_init_early#
void app_init_early (void )
User-defined function for early app initialization.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
This function is called from sli_main_init():
After essential infrastructure components are initialized (memory management, clock, oscillators, interrupt management, etc.).
Before initializing the kernel (if RTOS-based application)
Before the call to sl_main_second_stage_init() doing the other SiSDK modules initilization (e.g. drivers, services, stacks) This function allows the user to perform early initialization required by his application before other SiSDK modules initializations.
app_init#
void app_init (void )
User-defined function for app initialization.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
This function is called from main():
After all SiSDKs modules have been initialized (e.g. memory management, clock, oscillators, interrupt management, drivers, services, stacks).
After initializing and starting the kernel (if RTOS-based application) This function allows the user to perform any initialization required by his application after all SiSDK modules initializations.
app_process_action#
void app_process_action (void )
User-defined function to process a baremetal action periodically.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
Only used when the firmware type is baremetal. This function will be called every iteration of the main loop.
sl_main_init#
void sl_main_init (void )
Main entry function calling key platform modules initialization functions.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
This function allows the application to perform an early initialization from within the function app_init_early().
sl_main_second_stage_init#
void sl_main_second_stage_init (void )
Internal function used to aggregate driver, services stacks and internal apps initialization function.
Type | Direction | Argument Name | Description |
---|---|---|---|
void | N/A |
In a baremetal application, this function is called from sl_main_init(). If a kernel is present, this function will be automatically called after Silicon Labs platform and stacks components are initialized. These components init functions will be executed from the start task context.