Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

How to use taskENTER_CRITICAL()

Posted by jeanalban on March 3, 2015

Hello everybody,

I created two tasks: vCore_Loop (uxPriority = 4, launched every 5ms) and vScreen_Loop (uxPriority = 3, launched every 1ms).

vScreen_Loop communicates with a graphical screen via I2C. This low-priority task is often swapped by vCore_Loop task. My problem happens when vScreen_Loop is swapped during an I2C communication: my I2C driver creates an error because the communication is badly interrupted.

To solve this trouble, I added taskENTERCRITICAL(); and taskEXITCRITICAL(); between the beggining and the end of the I2C communication function, to be sure that this region will not be swapped by the RTOS scheduler.

To my surprise it did not affect the task swapping, vScreen_Loop is still swapped by vCore_Loop during the I2C communication. Do you have any ideas of why?

note: if the I2C communication function is called by the high-priority task vCore_Loop I have no troubles.

Thanks a lot for your help!

Jean


How to use taskENTER_CRITICAL()

Posted by rtel on March 4, 2015

To solve this trouble, I added taskENTERCRITICAL(); and taskEXITCRITICAL();

That might not be a good solution if the I2C communication takes a long time as it will [excepting the rest of your post] prevent context switches or interrupts occuring while the I2C communication is in process. That is a particular problem if the I2C communication is itself using interrupts - which it probably is - as the interrupts will not execute. A neater and more real time friendly solution would be to have a DMA handle the I2C communication.

To my surprise it did not affect the task swapping, vScreenLoop is still swapped by vCoreLoop during the I2C communication. Do you have any ideas of why?

My guess would be that the I2C driver is enabling interrupts directly, without using the taskENTER/EXIT_CRITICAL() macros. The macros will count interrupt enable/disable nesting, but the nesting count will only work if the macros are used in all cases that interrupts are disabled/enabled. If the I2C driver enables interrupts directly then they will become enabled even though the nesting count is not 0.

  • NOTE - many FreeRTOS ports do not disable interrupts globally, as my reply would infer, but just disables a subset of interrupts.

Regards.


How to use taskENTER_CRITICAL()

Posted by jeanalban on March 4, 2015

"That might not be a good solution if the I2C communication takes a long time as it will"

Yes I know, but for the moment I want something without interrupt. So I did not set any I2C interrupts in my code. Each time the microprocessor communicate via I2C it waits for the slave with something like while(!i2cmessageis_received). I know it's not real-time friendly but I have to do that to achieve my tests.

"My guess would be that the I2C driver is enabling interrupts directly"

I think that my I2C driver don't generates interrupts because I don't enable them. So it's strange that the task is swapped between taskENTER_CRITICAL() macros. But maybe it comes from low-end I2C interruptions I can't manage...

(note: I use a STM32F427)


How to use taskENTER_CRITICAL()

Posted by heinbali01 on March 5, 2015

Hi Jean,

Are you using an i2c library from ST, like e.g. stm32f4xxhali2c.c ? And are you using the DMA-variants of those functions?

Remember that a lighter way of preventing task switching is vTaskSuspend/vTaskResume.

I don't know why you still observe task-switches after calling taskENTER_CRITICAL. But what I do know is that i2c is a robust protocol that is resistant to delays.

You wrote:

because the ( i2c ) communication is badly interrupted

What exactly do you mean with that? Maybe some data corruption takes place when you get an interrupt at the wrong moment?

Or is your STM32F4xx a slave in the protocol? In that case I could understand that you don't want any interruption.

Regards.


How to use taskENTER_CRITICAL()

Posted by jeanalban on March 6, 2015

Hi Hein,

Yes I use the i2c library stm32f4xx_i2c.c but i'm not using any DMA variant.

My i2c communication is badly interrupted because I send a message to the slave, then I wait for the slave multiple answers, and during this messages reception the task is swapped. When the task returns in the i2c function after the swap, the function still wait for the slave answer but this answer is already send: this is my problem with the while(!i2cmessageis_received)

My I2C is configured as the master.

I hope it's clear! Thanks


How to use taskENTER_CRITICAL()

Posted by richard_damon on March 6, 2015

I am not familiar with that part, but I am very surprised at your claimed data loss, as the master controls the timing of the I2C bus, and every I2C Controller I know will hold the cycle until you take the data. (If it is SMD compliant and you get swapped out for a long time, then it would abort the cycle).

Holding up the processor while you do the I2C transaction is VERY inefficient for the processor, this would be an ideal use of interrupts and letting everything else run while you are getting the results and then resuming. If the rest of your system is really that relaxed in requirements, then you probably don't really need an RTOS, but can just turn your program into the simple big while loop type of implementation.

One solution to your problem, if you can't figure out where you are getting swapped out, is to boost your priority to be above every other task, then nothing can take over.


How to use taskENTER_CRITICAL()

Posted by jeanalban on March 10, 2015

Hi Richard,

When I set a higher priority it's working fine.

I don't understand why I loss datas wy the task is a low priority. I was holding the processor during the I2C transaction in order to quickly test the I2C communication and make a robust configuration the slave, but now I have to switch to a real time communication and use interrupts.

Thanks for all your help and see you soon! Jean


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists