Reading I2C sensor on stm32h723 and FreeRTOS got stuck

Dear All,

I am new to FreeRTOS and busy with a project. This is a large project and at this moment the code got stuck at the moment that the data from a I2C sensor is received. I have put the code so far on github on the foolowing link: GitHub - Gerardnhaiyi/stm32h723

The init runs fine, but as soon run is active it got stuck at ‘osMessageQueueGet’
Init and run are placed below, de complete code with these methods can be viewed at the link.

#include "cmsis_os.h"
#include "xLDRefpres.hpp"
#include "stm32h7xx_hal.h"

/********************************************************************************************************************************
 *	Method name:			xLDRefpres::xLDRefpres
 *
 *	Method Description:		constructor
 *
 *	Entry:					adress			I2C adress of the device
 *							resetPortIn		port of the reset pin
 *							resetPinIn		pin of the reset pin
 *
 *	exit:					None
 *
 ********************************************************************************************************************************/
xLDRefpres::xLDRefpres(uint8_t adress, I2C_HandleTypeDef &hi2cIn, DMA_HandleTypeDef &dmaReciveIn, DMA_HandleTypeDef &dmaSendIn, GPIO_TypeDef *resetPortIn, uint16_t resetPinIn) :
	busAdress( adress ), resetPort(resetPortIn), resetPin(resetPinIn), dmaRecv(dmaReciveIn), dmaSend(dmaSendIn), hi2c(hi2cIn)
{
	toISR = osMessageQueueNew(1, IN_BUFFER_SIZE, &toISR_attributes);
	fromISR = osMessageQueueNew(NR_MAX_INPUT_MESSAGES, OUT_BUFFER_SIZE, &fromISR_attributes);
//	toISR = xQueueCreate( 1, IN_BUFFER_SIZE );
//	fromISR = xQueueCreate( NR_MAX_INPUT_MESSAGES, OUT_BUFFER_SIZE );
	Reset();
}

/********************************************************************************************************************************
 *	Method name:			xLDRefpres::run
 *
 *	Method Description:		waits for data to be received and than error checks it and parses the data.
 *
 *	Entry:					None
 *
 *	exit:					None
 *
 ********************************************************************************************************************************/
void xLDRefpres::run(dataStorage& ds)
{
	uint8_t buffer[IN_BUFFER_SIZE] = {0};
//	if ( xQueueReceive( fromISR, buffer, portMAX_DELAY ) == pdTRUE )
	if ( osMessageQueueGet( fromISR, buffer, NULL, portMAX_DELAY ) == pdTRUE )
	{
		uint32_t pressureIn = 0;
		uint32_t temperatureIn = 0;
		//data: status, PD-pressure <15:8>, PD-pressure <7:0>, PD-temperature <15:8>, PD-temperature <7:0>
		if (!parsStatus(buffer[0]))
		{
			pressureIn = buffer[1]<<8 | buffer[2];		//16bit
			temperatureIn = buffer[3]<<8 | buffer[4]; 	//16bit
			pressure = ((pressureIn - MBA_PRESURE)/sensetivetyPresure)+mesuringRangeStart;
			temperature = ((temperatureIn - MBA_TEMP)*SENSETIVETY_TEMP)+MBA_UNIT_TEMP;

			ds.setFloatValueName(paramNames::REFERENCE_PRESSURE_LAST_PRESSURE, pressure);
			ds.setFloatValueName(paramNames::REFERENCE_PRESSURE_LAST_TEMPERATURE, temperature);
		}
	} //if ( xQueueReceive( fromISR, buffer, portMAX_DELAY ) == pdTRUE )
}

I am sure I am doing something wrong, but I don’t know what I do wrong here.
I hope someone can help me to get this to work.

thanks,
Gerard

1 Like

Is this interrupt firing - stm32h723/Core/Src/sensors/xLDRefpres.cpp at main · Gerardnhaiyi/stm32h723 · GitHub? You can put a breakpoint there to confirm.

I have to test that tomorrow at the shop. I will let you know.
So I should use the xQueueSendToBackFromISR and not the osMessageQueuePut?

regards,
Gerard

the “os” functions are NOT from FreeRTOS, but are wrappers provided by the vendor. Inside an ISR, you need to call FreeRTOS routines that end with “FromISR”. Unless osMessageQueuePut checks if it is in an ISR and calls the right FreeRTOS Queue function is it not usable in an ISR (One of the issues with using a wrapper is you need to understand the limitations of that wrapper), Note, the handle used in the os functions might not be the native FreeRTOS handle so might not be usable for FreeRTOS native calls.

The advantage of using a wrapper like that is that you can change your OS easier. The disadvantage is you are stuck with all the largest set of limits over all targeted OSes.

Do not mix the two. Just to narrow down the issue, I’d suggest to use native FreeRTOS APIs.

1 Like

I have changed all to the native FreeRTOS APIs, I just tested the interrupt, but it doesn’t firing somehow.

BTW I wouldn’t do a relatively slow I2C transaction inside an ISR.
Usually a task is notified and handles/starts the I2C transfer.

Then we need to debug why that is not firing. Did you enable this interrupt?

I turned on DMA for the I2C and I turned on EXTI 7 with rising edge send an EndOfConversion signal.

I am not familiar with DMA on this hardware. I’d suggest to contact ST to get this interrupt working.

ok, thanks for your help

could it be the case that the clock source of your peripheral is not enabled?