Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


How to manage tasks to manage I2C communication and the generation of a PWM signal

Posted by josantoniojl on February 19, 2019


This is my first time using FREERTOS, the project I'm doing is the information retrieval of the LIS3DH sensor (i2c) and the control of 3 servomotors. The program is working correctly on while cycle. However I have to use the FREERTOS system for task management. I don't know which is the best way to create tasks. What should i do? 1. Generate a task that performs everything I have programmed 2. Generate an i2c task and another PWM task 3. Generate a time interruption that manages a semaphore and at the same time i2c communication.

Is there an example of creating an i2c task on the STM32 nucleo card?

How to manage tasks to manage I2C communication and the generation of a PWM signal

Posted by rtel on February 20, 2019

You question is a bit open to be able to give a definitive suggestion, but basically have two options (this is really oversimplifying):

1) If you are not sending or receiving much data, and the task that does the sending and receiving is a low priority (so not starving more important tasks while the I2C transactions are in progress), then you can just use ST's polling I2C driver inline in whichever function needs to do the I2C reads.

2) If you need higher throughput, or your application can't be blocked while I2C transactions are in progress, then have the task start an I2C transaction then block on something like a direct to task notification (which means the task is not using and CPU time and other tasks can run) until either an interrupt controller or DMA controlled I2C operation completes - then when the operation is complete, unblock the task that was waiting for it. This is more complex, but I think ST have callbacks in their drivers that would allow you to do this.

Then of course there are alternatives that are neither fully polling or fully blocking....

How to manage tasks to manage I2C communication and the generation of a PWM signal

Posted by richarddamon on February 20, 2019

Number 1 may be a reasonable starting point, create a task which just has all your existing working code, and put it in as a low priority task, initially not using much in the way of FreeRTOS and then you can incrementally improve things as you go. It is not the way you want to end up, in particular you want to get rid of as many 'busy wait loops' as possible out of the code.

As to Number 2, I find that making a task to handle I2C isn't the best division. I tend to make a task for each thing that waits for some asyncronous input or that is on a distint timing interval. Being an I2C master, you don't need to make that a seperate task as everything happens in a basically syncronous manner. It may well make sense to have a task that reads from the I2C sensor at some rate and leaves/sends the data for some other task(s) to use.

How to manage tasks to manage I2C communication and the generation of a PWM signal

Posted by josantoniojl on February 20, 2019

Hi, I performed two tasks, one for obtaining values and the second for the control of servomotors, that works perfectly. The priority level of the i2c task is high while that of the motors is above normal.

However, I don't know if they have a recommendation for you to perform better task management. I was thinking about using a semaphore but I'm not sure how to use it.


void I2Communication(void const * argument) { /* USER CODE BEGIN I2Communication */

/* Infinite loop / for(;;) { HALI2CMemRead (&hi2c1, SLAVEI2CADD,0x28, 1,(uint8t *)OUTXL, 1, 100); HALI2CMemRead (&hi2c1, SLAVEI2CADD,0x29, 1,(uint8t *)OUTXH, 1, 100); HALI2CMemRead (&hi2c1, SLAVEI2CADD,0x2A, 1,(uint8t *)OUTYL, 1, 100); HALI2CMemRead (&hi2c1, SLAVEI2CADD,0x2B, 1,(uint8t *)OUTYH, 1, 100); HALI2CMemRead (&hi2c1, SLAVEI2CADD,0x2C, 1,(uint8t *)OUTZL, 1, 100); HALI2CMemRead (&hi2c1, SLAVEI2CADD,0x2D, 1,(uint8t *)OUTZH, 1, 100); // Registre OUTZH x = ((OUTXH[0]<<8)|OUTXL[0]); y = ((OUTYH[0]<<8)|OUTYL[0]); z = ((OUTZH[0]<<8)|OUTZL[0]); osDelay(500); } / USER CODE END I2Communication */ }

void PWMControl(void const * argument) { /* USER CODE BEGIN PWMControl / / Infinite loop / for(;;) { TIM2->CCR1=x; TIM2->CCR2=y; TIM2->CCR4=z; osDelay(500); } / USER CODE END PWMControl */ } ~~~

[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS v10.2.0 is available for immediate download. MIT licensed, and including RISC-V and ARMv8-M (Cortex-M33) demos.

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


FreeRTOS and other embedded software careers at AWS.

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Cadence Tensilica Cortes

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers





STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner