SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

gp7
Posts: 17
Joined: Fri Oct 14, 2022 1:52 pm
Has thanked: 10 times

SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby gp7 » Fri Oct 14, 2022 5:33 pm

Hi All,

I have to admit I'm a newbie to Chibios but hope someone may be able to assist with debugging a project I am working on.
There are several threads within the project and some of them configured to communicate via I2C. I am debugging with a GDB debug configuration in STM32CubeIDE. Following the Debug Guide I have set CH_DBG_SYSTEM_STATE_CHECK and CH_DBG_ENABLE_CHECKS. CH_CFG_USE_MUTEXES is also set to TRUE.

The main thread calls some setup functions for the I2C and other devices and then should enter the main loop.
However it looks as though main gets stuck in state "WTMTX" from within setup functions I have traced the code to be waiting on a mutex for one of the I2C buses but I'm uncertain of how to work out why a mutex isn't gained.

All my calls to send or receive on I2C are as follows:

i2cAcquireBus(&m_driver);
auto status = i2cMasterTransmitTimeout(&m_driver,
m_mux_addr,
buf,
sizeof(buf),
rxbuf, //need this non zero otherwise assert.
0,
TIME_MS2I(5));
i2cReleaseBus(&m_driver);


There's no other threads running on i2c during setup so why would Acquire be failing? Interestingly when I switch to -02 in compiler options the code appears to get past setup and into the main loop.. Does anyone have any suggestions as to why I can't get the Mutex on the i2c and how I might find out what is preventing access. Could this be due to an ISR?

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby Giovanni » Fri Oct 14, 2022 6:13 pm

Hi,

Are assertions and state checker enabled in chconf.h? those can catch lots of errors.

Giovanni

gp7
Posts: 17
Joined: Fri Oct 14, 2022 1:52 pm
Has thanked: 10 times

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby gp7 » Sat Oct 15, 2022 6:17 pm

Hi Giovanni,

had already assertions enabled but not the state check. I have tried again with state check and assertions now turned on. I can set breakpoints beyond the point where the i2c buses are getting setup but intermittently the setup fails. When it does fail main thread is in WTMTX and idle is CURRENT. It does look as though my issue may be timing related. I have 3 batches of i2c devices to setup. When I place 1ms delay between the individual calls then I am able to step over the i2c initialisations which no longer produce errors. If there is anything else I discover then I will post it here.

Thank you.

gp7
Posts: 17
Joined: Fri Oct 14, 2022 1:52 pm
Has thanked: 10 times

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby gp7 » Mon Oct 17, 2022 12:54 pm

I am still seeing intermittent issues with Mutex objects. It looks as though there may be some non thread-safe code in my application. It's part of a library shared with a microprocessor that is not running chibios. I am wondering whether it may be possible to use std::mutex to secure access to the shared library code. Are there any reasons that the std::mutex would not work within a chibios project?

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby Giovanni » Mon Oct 17, 2022 2:14 pm

Hi,

std::mutex are not related to ChibiOS mutexes. You need to use ChibiOS-provided mechanisms everywhere.

Giovanni

User avatar
alex31
Posts: 374
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 38 times
Been thanked: 61 times
Contact:

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby alex31 » Mon Oct 17, 2022 3:13 pm

gp7 wrote:I am wondering whether it may be possible to use std::mutex to secure access to the shared library code. Are there any reasons that the std::mutex would not work within a chibios project?


Hello, yes, there is a good reason : std::mutex use the underlying layer of the operating system, pthread for linux and osx, windows thread for windows, but nothing is done for arm-none-eabi platform since this layer is not known, can be non existent in bare metal programming, or dependent to the RTOS that you use, can be ChibiOS, FreeRTOS, or anything the toolchain cannot know about.

If you use C++, you can encapsulate ChibiOS mutex in a very simple RAII class where you delegate the unlock call to the constructor :

Code: Select all

class Lock
{
public:
  Lock(mutex_t &_mtx) : mtx(_mtx) {chMtxLock(&mtx);};
  ~Lock() {chMtxUnlock(&mtx);};
private:
  mutex_t &mtx;
};


Alexandre

gp7
Posts: 17
Joined: Fri Oct 14, 2022 1:52 pm
Has thanked: 10 times

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby gp7 » Thu Oct 20, 2022 6:22 pm

Thanks Giovanni, alex31, for your responses.

I am looking at the i2c config files. I currently have two configs. One I inherited in my code and one based on how play embedded suggest i2c configuration.

const I2CConfig m_i2cfg1 = {0x30A0A7FB, 0, 0};
const I2CConfig m_i2cfg2 = {
STM32_TIMINGR_PRESC(15U) |
STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) |
STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),
0,
0
};

i2cStart(&I2CD1, &m_i2cfg2);
i2cStart(&I2CD2, &m_i2cfg2);


When I run my code with i2cfg1 I manage to call i2cMasterTransmitTimeout 4 times:

1. setup i2c mux
2. set mux channel for first sensor
3. send data to sensor
4. read data from sensor
(works to here)
5. set mux channel for second sensor

On the fifth call there is a lock. i2cp->state == I2C_LOCKED. If I run again and pause the code pauses at chSysHalt and i2cp->state is now I2C_SMB_ALERT.

From what I can see m_i2cfg2 works out as follows (please correct me if I'm wrong):

//15U << 28 | 4U < 20 | 2U << 16 | 15U << 8 | 21U << 0
//15 x 268435456 + 4 x 1048576 + 2 x 65536 + 15 x 256 + 21
//4026531840+4194304+131072+3840+21
//F0420F15₁₆

I will go through the bus initialisation section of the IC manual and check(It matches the .IOC file from CubeMX. In the meantime could a missing ACK place the bus into a locked state?
Last edited by gp7 on Thu Oct 20, 2022 7:00 pm, edited 1 time in total.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby Giovanni » Thu Oct 20, 2022 6:48 pm

Hi,

I2C_LOCKED means that the driver got some error, in order to exit from that state you need to stop() and start() again.

The real question is the reason for that error, it could be speed, noise, insufficient pull-ups and others.

Giovanni

gp7
Posts: 17
Joined: Fri Oct 14, 2022 1:52 pm
Has thanked: 10 times

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby gp7 » Fri Oct 21, 2022 1:36 pm

When reading data from my slave devices it looks as though Hold Master may be preventing the MCU from accessing the clock line. I need to investigate further.

gp7
Posts: 17
Joined: Fri Oct 14, 2022 1:52 pm
Has thanked: 10 times

Re: SMT32G474- i2cAcquireBus not getting Mutex when built with -O0 compiler option

Postby gp7 » Fri Oct 21, 2022 5:49 pm

How is it possible to determine if my stack is corrupt?
I can step through code in my main loop that I have protected with a mutex and the pointer jumps from the start of a function, to the middle, then back to a previous point before ending at VectorF4.
No other threads except idle are running.

My makefile contains:

ifeq ($(USE_PROCESS_STACKSIZE),)
USE_PROCESS_STACKSIZE = 0x800
endif

ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
USE_EXCEPTIONS_STACKSIZE = 0x400
endif
Last edited by gp7 on Fri Oct 21, 2022 5:54 pm, edited 1 time in total.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 22 guests