1 FreeRTOS or Not, Is that a question?
1.1 Before starting, whether FreeRTOS to be used or not , shall be balanced first. It is easy to start the code straitforward. Let me call it , strait-coding.
Do what we think , and wrting codes what it should. That is more logical and easy to understand. For most design, that is enough, especilly for ARM-M0+ core with limited memory and fix number of peripherals.
Take a tour for github of cypressco , most sample-codesare bareP-metal codes. Provide direct hint on how to use the mentioned API.
1.2 For CY8PROTO-062 Dev board, rich in peripheral and relative large memory available. More shall be digged. The FreeRTOS by AWS provides another choice. That would be useful if more complex logical is included.
2. RTOS
2.1 More reference of FreeRTOS can be got from https://freertos.org/ or https://aws.amazon.com/freertos/?nc1=h_ls . In general , it is freeware. But there are still commercial service for large entity for enterprise version. Sort of like Windriver which is acquired by Intel. FreeRTOS is now brand with Amazon , and no longer independent FreeRTOS , that shall be AWS freeRTOS.
That would be a blow to uCos II, once successful product , now disappear from most vendor library list.
Another emerging RTOS is rtThread, it can be got from Keil MDK with rtthread nano. But with much larger ecosystem and plugin libraries. But need more time to learn and there have been bugs now and then. For such new CY8PROTO-062 Dev board, it is not officially supported. But for stm32 brand owners, definitely worth a try.
2.2 AWS FreeRTOS can be used in nearly every brand, and the list is expanding. With similar code style and workflow, porting is much a piece of cake.
For CY8PROTO-062 Dev board , the capsense demo is supplied with two version, with FreeRTOS and without FreeRTOS. Just enough to compare.
3. Capsense Demo Comparation
3.1 Capsense in loop polling,
Normal coding is as flows,
The main part is attached for reference,
int main(void)
{
cy_status status;
cy_rslt_t result;
/* Initialize the device and board peripherals */
result = cybsp_init();
/* Board init failed. Stop program execution */
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Enable global interrupts */
__enable_irq();
initialize_led();
initialize_capsense_tuner();
status = initialize_capsense();
if(CYRET_SUCCESS != status)
{
/* Halt the CPU if CapSense initialization failed */
CY_ASSERT(0);
}
/* Start first scan */
Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
for(;;)
{
if(CY_CAPSENSE_NOT_BUSY == Cy_CapSense_IsBusy(&cy_capsense_context))
{
/* Process all widgets */
Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
/* Process touch input */
process_touch();
/* Establishes synchronized operation between the CapSense
* middleware and the CapSense Tuner tool.
*/
Cy_CapSense_RunTuner(&cy_capsense_context);
/* Start next scan */
Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
}
}
}
3.2 Capsense FreeRTOS
In freeRTOS, just create RTOS thread, then start all the choosen task. The flowchat is simple as in the main(). The for loop is empty, since the RTOS take over the task-handling.
int main(void)
{
cy_rslt_t result;
/* Initialize the device and board peripherals */
result = cybsp_init();
/* Board init failed. Stop program execution */
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
/* Enable global interrupts */
__enable_irq();
/* Create the queues. See the respective data-types for details of queue
* contents
*/
led_command_data_q = xQueueCreate(SINGLE_ELEMENT_QUEUE,
sizeof(led_command_data_t));
capsense_command_q = xQueueCreate(SINGLE_ELEMENT_QUEUE,
sizeof(capsense_command_t));
/* Create the user tasks. See the respective task definition for more
* details of these tasks.
*/
xTaskCreate(task_capsense, "CapSense Task", TASK_CAPSENSE_STACK_SIZE,
NULL, TASK_CAPSENSE_PRIORITY, NULL);
xTaskCreate(task_led, "Led Task", TASK_LED_STACK_SIZE,
NULL, TASK_LED_PRIORITY, NULL);
/* Start the RTOS scheduler. This function should never return */
vTaskStartScheduler();
/*~~~~~~~~~~~~~~~~~~~~~ Should never get here! ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* RTOS scheduler exited */
/* Halt the CPU if scheduler exits */
CY_ASSERT(0);
for(;;)
{
}
}In this case two tasks are created, one is task_led to blink led, another is task_capsense to detect the touch of capsensors.
In tasks , you can make independant design loop as in task_led,
void task_led(void* param)
{
cyhal_pwm_t pwm_led;
bool led_on = true;
BaseType_t rtos_api_result;
led_command_data_t led_cmd_data;
/* Suppress warning for unused parameter */
(void)param;
/* Configure the TCPWM for driving led */
cyhal_pwm_init(&pwm_led, CYBSP_USER_LED, NULL);
cyhal_pwm_set_duty_cycle(&pwm_led, GET_DUTY_CYCLE(LED_MAX_BRIGHTNESS),
PWM_LED_FREQ_HZ);
cyhal_pwm_start(&pwm_led);
/* Repeatedly running part of the task */
for(;;)
{
/* Block until a command has been received over queue */
rtos_api_result = xQueueReceive(led_command_data_q, &led_cmd_data,
portMAX_DELAY);
/* Command has been received from queue */
if(rtos_api_result == pdTRUE)
{
switch(led_cmd_data.command)
{
/* Turn on the LED. */
case LED_TURN_ON:
{
if (!led_on)
{
/* Start PWM to turn the LED on */
cyhal_pwm_start(&pwm_led);
led_on = true;
}
break;
}
/* Turn off LED */
case LED_TURN_OFF:
{
if(led_on)
{
/* Stop PWM to turn the LED off */
cyhal_pwm_stop(&pwm_led);
led_on = false;
}
break;
}
/* Update LED brightness */
case LED_UPDATE_BRIGHTNESS:
{
if (led_on)
{
uint32_t brightness = (led_cmd_data.brightness < LED_MIN_BRIGHTNESS) ?
LED_MIN_BRIGHTNESS : led_cmd_data.brightness;
/* Drive the LED with brightness */
cyhal_pwm_set_duty_cycle(&pwm_led, GET_DUTY_CYCLE(brightness),
PWM_LED_FREQ_HZ);
}
break;
}
/* Invalid command */
default:
{
/* Handle invalid command here */
break;
}
}
}
/* Task has timed out and received no data during an interval of
* portMAXDELAY ticks.
*/
else
{
/* Handle timeout here */
}
}
}
4. FreeRTOS with AWS IoT
As in https://aws.amazon.com/freertos/?nc1=h_ls , FreeRTOS provides everything you need to easily program connected microcontroller-based devices and collect data from them for IoT applications. You can get started by choosing a FreeRTOS-qualified microcontroller from the AWS Partner Device Catalog.
The following diagram shows how FreeRTOS is important to AWS IoT. Normal polling can make it but not so secure and reliable.
FreeRTOS core handle stacks, thread-management, memory allocation and destroy, each of which is challenge to coding.
But , now it is safe and easy. use combination of two lines, it will go fine.
xTaskCreate(task_led, "Led Task", TASK_LED_STACK_SIZE, NULL, TASK_LED_PRIORITY, NULL);
vTaskStartScheduler();So, it is recommendated to use freeRTOS with AWS IoT. The sooner ,the better.

