Hi,
I was implementing three 200kHz Buck convertors. Each Buck is phased shifted and runs every 5us and uses a zero latency interrupt from the ADC to run a fixed point 3p3z controller (software optimized). Every 10ms a SWI timer is run to calculated floating point values for soft start. The idle task just flashes a LED and performs TCP/IP and USB communications.
But I found my SWI function was sometimes hitting some of my asserts. When I looked at “ret” it was between 0 and ADC_VALUE_MAX, or it was “NaN”.
if (ret >= 0.0f && ret <= ADC_VALUE_MAX) { //ok } else { assert(ret >= 0.0f && ret <= ADC_VALUE_MAX); //hits this line }
At first I though it was because I was using floats in my HWI Buck function, so I re-wrote it to use integer maths only.
Then I realized I had to mark the HWI Buck function as “__interrupt” for the correct context saving to occur.
I’ve done all of this and still my SWI function was being corrupted so I decided to write a small test program to reproduce this error. This code doesn’t perform the buck or soft start code, but contains the bits of code that seems to cause the error. I made the SWI code run for almost 10ms and changed the HWI to run just one buck every 5us.
My test (context.zip) program uses the following version of compiler, RTOS, XDC
- Compiler version TI v5.2.2
- TI-RTOS for TivaC 2.14.4.31
- XDCtools version: 3.31.1.33_core
It has two files,
- Empty.cpp - the idle task and SWI function
- Isr.cpp – stripped down buck code
You just need to add a break point to empty.cpp at line 50 and run. This break point should be hit and you can see either you have a NaN or ret is within range.
assert(ret >= 0.0f && ret <= ADC_VALUE_MAX);
If you have a ETM then it should be very easy to see how the SWI is being corrupted, but I don’t have one ;-(
So far my possible thoughts are
- The HWI interrupt isn’t saving/restoring its context correctly, but the ASM looks ok, and I would have thought every other ARM developer would have spotted this compiler error by now.
- The SYS/BIOS is doing something strange and relies on a set of sequential ASM instructions that are being interrupted by my HWI. This might sound strange but I found this bit of code in Hwi_asm.sv7M. (not that I’m saying this code has anything to do with my problem)
; CAUTION!!! Do NOT single step thru the next instruction ; else, the processor won't arrive at pendSV thru the ; exception mechanism. msr basepri, r0 ; causes pendSV to happen nop ; 2 nops required for prefetch nop ; .endasmfunc
- Or I'm doing something wrong in setting up my HWI
I found that by changing bits of my code I can cause the corruption not to be detected. But I think this just hides the corruption, so I really want to know what is going wrong and not to change my test program to get it working (unless it’s a sys/bios patch)
Any help in this matter would be greatly appreciated.
Chris