5 years, 1 month ago.

F429ZI example Nucleo_sinewave_output with crashes with mbed-os

Hello,

I added an Ticker to the DAC output in order to guarantee consistent output of the DAC. (see modified example). It works fine with mbed. However, it crashes with mbed-os. It crashes immediately after the first write to the DAC.

#include "mbed.h"

Ticker dac_rate_timer;                      // Used for DAC

#if !DEVICE_ANALOGOUT
#error You cannot use this example as the AnalogOut is not supported on this device.
#else
AnalogOut my_output(PA_4);
#endif



#define PI        (3.141592653589793238462)
#define AMPLITUDE (1.0)    // x * 3.3V
#define PHASE     (PI * 1) // 2*pi is one period
#define RANGE     (0x7FFF)
#define OFFSET    (0x7FFF)

// Configuration for sinewave output
#define BUFFER_SIZE (360)
uint16_t buffer[BUFFER_SIZE];

int daco_t = 0;


// Create the sinewave buffer
void calculate_sinewave(void){
  for (int i = 0; i < BUFFER_SIZE; i++) {
     double rads = (PI * i)/180.0; // Convert degree in radian
     buffer[i] = (uint16_t)(AMPLITUDE * (RANGE * (cos(rads + PHASE))) + OFFSET);
  }
}

//--------------------------------------------------------------------------------------
// ISR for updating DAC value at a fixed output rate

int dacPntr = 0;

void dac_update(void)
{ 
    dacPntr++;
    if(dacPntr >= BUFFER_SIZE) dacPntr = 0;
    my_output.write_u16(buffer[dacPntr]); // <-- causes crash on 1st write
    daco_t++; 
}

//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
int main() {
    printf("\r\nSinewave example\r\n");
    
    calculate_sinewave();
    dac_rate_timer.attach_us(&dac_update, 10); // dac update time 50uS
    
    while(1) {
        wait_ms(500); 
        printf("daco_t:         %10d\r\n", daco_t);     
        // sinewave output
        //for (int i = 0; i < BUFFER_SIZE; i++) {
        //    my_output.write_u16(buffer[i]);
        //    wait_us(10);
        //}
    }
}

crash error:

++ MbedOS Error Info ++ Error Status: 0x80020115 Code: 277 Module: 2 Error Message: Mutex lock failed Location: 0x8006A43 Error Value: 0xFFFFFFFA Current Thread: rtx_idle Id: 0x20000564 Entry: 0x8007631 StackSize: 0x200 StackMem: 0x200005F0 SP: 0x2002FF48 For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80020115 MbedOS Error Info

System will be rebooted due to a fatal error

Reboot count(=1) reached maximum, system will halt after rebooting

2 Answers

5 years, 1 month ago.

The error message says you couldn't get a mutex lock. You are attempting to override the OS mutex that is part of the RTOS . Try starting a separate thread to update the DAC and signal it via a timer. Hint: you won't be able to get around the mutex in the RTOS.

That means then that there is no way of guaranteeing a fixed DAC output rate. Perhaps DMAing data out to the DAC is possible? Would still require a timer to send out DMA data at a fixed rate...

posted by Kevin Braun 20 Feb 2019
4 years, 7 months ago.

I tried this approach: https://os.mbed.com/questions/78455/As-the-I2C-component-is-not-ISR-safe-wha/

basically move the call to my_output.write_u16() to a routine that is executed via an eventQueue call, with that thread being set to osPriorityRealtime. This does work but (despite the info in the above thread) there is an increase in jitter. My sinewave generated in the older non-rtos version had third harmonic approx -60db (quite reasonable), after the change it was only -38dB, with similar levels of fifth and 7th harmonics which were not there at all before. Not good but usable in some applications.