I2C1 and DMA corrupt memory? [STM32L152]

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
Post Reply
l0wside
Posts: 5
Joined: Mon Dec 09, 2019 8:56 am
Been thanked: 1 time

I2C1 and DMA corrupt memory? [STM32L152]

Post by l0wside »

Hello all,
being quite new both to ChibiOS and STM32 (but with several years of experience on MSP430), I am extremely reluctant to call the effect I am seeing here a bug, but it is hugely annoying. Maybe someone can point me in the right direction?
Setup: ChibiOS 19.1.3, ARM GCC 9.2.1 (from ARM site), STM32L152 Nucleo Board with Si7021 attached.
I am cyclically (every 5s) reading the latest data from the sensor via I2C, which is basically working all fine. The relevant parts of the code look like this:
Global variable declaration:

Code: Select all

#define WASIZE_HUM 128
#define AVERAGING_SAMPLES 20

/* Array of last read values, used for averaging. Contains raw data */
volatile struct {
   uint16_t index;
   uint16_t samples_to_init; /* counts down to zero until buffer is full */
   uint16_t hum_values[AVERAGING_SAMPLES];
   uint16_t hum_temp_values[AVERAGING_SAMPLES];
} hum_data;
volatile uint8_t i2c_data[3];
const uint8_t SI7020_MEASURE_HUM_HOLD = 0xE5;
I2CDriver *hum_i2c_driver;
uint8_t hum_i2c_address;

Thread function:

Code: Select all

static THD_WORKING_AREA(wa_thread_hum, WASIZE_HUM);
static THD_FUNCTION(thread_hum, arg) {
   (void)arg;
   ...
   while(true) {
      i2cAcquireBus(hum_i2c_driver);
      /* Measure humidity */
      i2c_result = i2cMasterTransmitTimeout(hum_i2c_driver, hum_i2c_address, &SI7020_MEASURE_HUM_HOLD, 1, i2c_data, 3, TIME_MS2I(I2C_MAXTIME));
      ...
      i2cReleaseBus(hum_i2c_driver);
      ...
   }
}   

After [font=Courier New]i2cMasterTransmitTimeout()[/font], i2c_data contains plausible data which matches what I see on the logic analyzer. So far, so good.
BUT: I see more or less random changes in [font=Courier New]hum_temp_values[/font]. See attached screenshots. Strangely enough, the affected memory is quite a bit away: [font=Courier New]i2c_data[/font] is at [font=Courier New]0x20000aec[/font], while the affected memory is at [font=Courier New]0x20000b48[/font] (or in the vicinity, the pattern is not always the same).
With the debugger, I have tracked down the effect to this piece of code in [font=Courier New]hal_i2c_lld.c[/font]:

Code: Select all

  dp->CR2 |= I2C_CR2_ITEVTEN;
  dp->CR1 |= I2C_CR1_START;

  /* Waits for the operation completion or a timeout.*/
  return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);

Not being too familiar with STM32 (which is one of the reasons I chose ChibiOS), I assume that [font=Courier New]dp->CR1 |= I2C_CR1_START;[/font] starts the I2C/DMA transaction. When I step over the [font=Courier New]return()[/font], the effect is visible.

Any help is appreciated. Thank you!
Attachments
after.png
before.png
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: I2C1 and DMA corrupt memory? [STM32L152]

Post by Giovanni »

Hi,

The function osalThreadSuspendTimeoutS() is where the thread goes to sleep waiting for operation complete, it uses a lot of stack for storing thread context information.

Are you sure it is not just a stack overflow? I would check that. In addition you could try to use the driver without DMA, this could give another hint about the problem.

Also make sure to enable the debug options in chconf.h: assertions, checks, state checker and stack checker. Those can find a lot of latent problems.

Giovanni
l0wside
Posts: 5
Joined: Mon Dec 09, 2019 8:56 am
Been thanked: 1 time

Re: I2C1 and DMA corrupt memory? [STM32L152]

Post by l0wside »

Ciao Giovanni,
sei veloce come un fulmine. Grazie mille!

With stack checking enabled, this is what ChibiOS throws:

Code: Select all

Program received signal SIGINT, Interrupt.
0x08002d10 in chSysHalt (reason=0x8005530 "stack overflow") at P:/Chibi/ChibiOS_19.1.3/os/rt/src/chsys.c:206
206     ch.dbg.panic_msg = reason;


Increasing the thread´s stack size solves the problem.

Thanks again,

Max
Post Reply