4. Main Function

This section analyzes the key points of the main() function which instantiates the execution of the freeRTOS scheduler.

4.1. The Key Points of the Main Function

The main() function is responsible for the following actions:

  1. The following function must be called before any other configuration related to system clocks. It is the lowest level function. More specifically, it switches to the internal 16MHz RC oscillator (RC16M), restarts the external 16 MHz crystal (XTAL16M) and may wait for it to settle. It also sets the DIVN clock divider which provides the 16 MHz clock source to various hardware blocks of the device, regardless of the system clock source. It then sets up the low power clock, according to the value of the dg_configUSE_LP_CLK macro in the config/custom_config_qspi.h header file. This function must be called only once, before the freeRTOS scheduler is started.

Code Snippet:

/* Basic clock initialization */

cm_clk_init_low_level();

Note

One case where the system does not wait for the settling of the XTAL16M, is when both the external 32kHz crystal is selected as low power clock (#define dg_configUSE_LP_CLK  LP_CLK_32768) and it has explicitly defined not to wait for the settling of the crystal, that is, pm_set_wakeup_mode(false). The hardware blocks that require the XTAL16M to properly work are the BLE, USB and the UART peripheral.


  1. The next step is to create the task named system_init() that is responsible for initializing the system (see the System Initialization Function section). In this freeRTOS task we should also define all the application tasks. In this tutorial we have defined one application task named prvTemplateTask.

Code Snippet:

status = OS_TASK_CREATE("SysInit",           /* The text name assigned to the task; for debug only, not used by the kernel. */
             system_init,                    /* The System Initialization task. */
             ( void * ) 0,                   /* The parameter passed to the task. */
             configMINIMAL_STACK_SIZE * OS_STACK_WORD_SIZE,
                                             /* The number of bytes to allocate to the stack of the task. */
             OS_TASK_PRIORITY_HIGHEST,       /* The priority assigned to the task. */
             xHandle );                      /* The task handle */
OS_ASSERT(status == OS_TASK_CREATE_SUCCESS);
  1. After creating all the required freeRTOS tasks, it’s time to start running the scheduler which is responsible for controlling and executing all the previous defined tasks, according to their priorities.

Code Snippet:

/* Start the tasks and timer running. */

vTaskStartScheduler();