I am running FreeRTOS v8.2.2 on a MSP430F5335 based board. I am using IAR v6.30.3 It is an extremely simple application which acts as an i2c slave device and provides analog outputs. A seperate i2c master device controls the analog outputs.
I am working on adding firmware update support where the master can update the firmware in the MSP430 slave device. The first thing I did is implment the part where I send down the image. Right now, I am simply sending down the firmware in 128 byte chuncks over i2c and getting back a 8 byte confirmation message for each chunk. The master does this as fast as possible. A total of 0x10000 bytes is in the image so basically, the i2c is sending and receiving as fast as it can with no delays between.
The MSP430 application is crashing at random times, sometimes on the first i2c message and sometimes after many. Using the State Storage window in IAR CSpy, I set advanced triggers to break on address bus instruction fetchs outside of the actual program memory space. The best I can tell, the crash seems to be occuring when the xQueueGenericReceive calls VTaskSuspendAll on line 1496 in queue.c. It looks like the call is made but doesn’t seem to work correctly. The information on the State Storage Window doesn’t seem to exactly match would I would expect based on the disassembly window. I have not used the State Storage Window much in the past so I don’t have much experience with it. I can provide the IAR CSpy screeen image to anyone that is interested in the details.
I have been searching this forum and other internet info for possible solutions and have tried many things to solve the problem. Finally late last night I found something that seemed to fix the problem. I changed the optimization settings in IAR from “none” to “high, balanced”. I set up the i2c master application to continually send the 0x10000 firmware image over and over and the MSP app ran all night with no problems. I have not seen any problems today either. I changed the optimization level back to none and immediately started seeing the problem again.
Any ideas on why setting the IAR optimization level to “high balanced” would have solved the crashing problem?
Any ideas on how to fix the issue would be greatly appreciated.
From all the other attempts to fix this problem, I came across a few other FreeRTOS related questions/suggestions also:
It would be very nice if there was a simple flag added to FreeRTOS which would turn on and off the execution of the code which determines if a call is made to portSUPPRESS_TICKS_AND_SLEEP. In several of our applications we would like to simply turn off the capibility of going into low power mode if certain conditions are true and then turn it back on when desired. This would improve performance when running continuously.
With the MSP430X FreeRTOS port, is it necessary to put the portYIELD_FROM_ISR call as the very last statement in an interrupt service routine? What happens if it is not the last statement?
Are there any plans to add a fix for the MSP430F5335 Errata USCI39 in the FreeRTOS MSP430X port? Since I was using i2c so much in the above application, this was an issue I focussed on. Below is an updated version of the portENABLE_INTERRTUPTS() macro which I have been using to address the USCI39 Errata.
#define portENABLE_INTERRUPTS() uint8_t saved_UCB1IE = UCB1IE; \ UCB1IE &= ~(UCNACKIE+UCSTPIE+UCSTTIE); \ _NOP(); \ _EINT(); \ UCB1IE |= saved_UCB1IE;
Errata USC139 may (I am not positive) also be a problem when trying to enter low power mode. I used the same basic code in this case:
uint8_t save1_UCB1IE = UCB1IE; // Fix for MSP430F5335 Errata USCI39 UCB1IE &= ~(UCNACKIE+UCSTPIE+UCSTTIE); // Disable self clearing interrupts __no_operation(); // nop as recommended in USCI39 __bis_SR_register(LPM3_bits+GIE); // Enter LPM3 and make sure GIE is set __no_operation(); // nop between eint and dint. portDISABLE_INTERRUPTS(); // disable all interrupts UCB1IE |= save1_UCB1IE; // restore UCB1 interrupt enable flags
The above code only handles UCB1 since that is the only one being used in my application. A general solution in FreeRTOS would be more complicated for handling all USCI ports available. Any thoughts on possible problems with my implementation? I know that it is very undersirable as far as performance, but I am not sure what else to do. I wish TI would explain more clearly what they mean when they say “Unpredictable code execution can occur”. I wonder if the code goes off in the weeds, or is an interrupt simply missed etc…