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:
1) 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 portSUPPRESSTICKSAND_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.
2) With the MSP430X FreeRTOS port, is it necessary to put the portYIELDFROMISR call as the very last statement in an interrupt service routine? What happens if it is not the last statement?
3) 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 portENABLEINTERRUPTS() uint8t saved_UCB1IE = UCB1IE;
UCB1IE &= ~(UCNACKIE+UCSTPIE+UCSTTIE); \
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:
uint8t save1UCB1IE = UCB1IE; // Fix for MSP430F5335 Errata USCI39
UCB1IE &= ~(UCNACKIE+UCSTPIE+UCSTTIE); // Disable self clearing interrupts
_nooperation(); // nop as recommended in USCI39
_bisSRregister(LPM3bits+GIE); // Enter LPM3 and make sure GIE is set
_nooperation(); // nop between eint and dint.
portDISABLEINTERRUPTS(); // disable all interrupts
UCB1IE |= save1UCB1IE; // 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...
Ref why optimisation could make a difference:
The code will run faster and use less stack. Faster execution would mean less probability of timing related errors on the serial bus - are you handling all error conditions on the bus? Less stack would mean less likely to see a stack overflow - do you have configCHECKFORSTACK_OVERFLOW set to 2?
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 portSUPPRESSTICKSAND_SLEEP
Are you using tickless mode when the issue described above occurs?
In our default Cortex-M tickless implementations there are pre and post sleep macros that can be used to abort going into tickless mode:
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
__asm volatile( "dsb" );
__asm volatile( "wfi" );
__asm volatile( "isb" );
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
The macros are provided by the application, or removed completely if the application doesn't provide them. To abort tickless entry xModifiableIdleTime is just set to 0 in the pre sleep macro.
With the MSP430X FreeRTOS port, is it necessary to put the portYIELDFROMISR call as the very last statement
In that port the yield will occur immediately, so it is best to have it at the end of the ISR. It would probably be ok to have it somwhere other than the ISR, but code that appears after the yield is not going to execute until the task that was running when the interrupt was taken is once again the task in the Running state.
Are there any plans to add a fix for the MSP430F5335 Errata USCI39
I was not aware of the errata, but will look it up.