compile/optimize error?

NikoTeen

Well-known member
hi,
in my program for a Teensy 3.2 I see effects which I only can explain by errors in compiling/optimization.

Mainly there are two problems, both happen in an interrupt routine:
1) a function call is not executed
2) part of code is not executed

With problem 2 the program behaves differently if just compiling with a different optimize setting.

I have done a detailed analysis for both problems and have a test setup to reproduce the effects.

In the attachment there are all program files for a Teensy 3.2 and a detailled description of effects and a method to reproduce these effects
  • SpracheOregondec_Forum.zip, all program files
  • AnalysisOregonDecodeBehaviour-Forum.pdf, detailled description of effects and how to reproduce them

The data files to run the program can be copied from dropbox via the following links:
https://www.dropbox.com/s/3dx2hdm3banfwko/OregonSignal_1.zip?dl=0
https://www.dropbox.com/s/9k3gakr9fyqn3l0/OregonSignal_2.zip?dl=0

My configuration:
- Windows 10, 32 bit
- Arduino IDE 1.8.12 with latest Teensyduino
- Teensy 3.2

I hope that somebody takes the time to run the test program and convince himself that there really is a problem/error with compilation and/or optimization.
 
@NikoTeen - I am not sure I have it in me today to go through a complicated sketch with Wave files, as I don't have anything setup to handle wave files at the moment... As I mentioned in another thread today, usually the most complicated sounds my sketches make is a beep or two...

But I thought I would mention I don't see any zip files here...

The other thing I would mention, is often times in the past when I ran into strange issues with optimizations, it was often due to some obscure bug in my code.
Things like:

a) I overran or underran an array and when the code is optimized one way that part I overwrote was not important, but when code was rearranged the thing that got wiped was important. Sometimes like a return address or...

b) Some variables that can change elsewhere were not marked as volatile. When compiled one way the code still worked. When optimized the system said, this condition will never happen and removed the code.

...
 
Sorry for the missing attachment.
Now they are here.

KurtE,
the sketch is not working with wav files. The files are needed as external input to the comparator in the T3.2. The effects described happen within an interrupt routine which is triggered by the comparator.
To run the sketch the wav files just shall be replayed with an audio program, and the line out or headphone output is fed via a logic chip, e.g. SN7400, to the comparator input.
At the end of the pdf document it is described how to do it.
For replay of the wav files I am using audacity.exe. But any other audio program should do it as well.
 

Attachments

  • SpracheOregondec_Forum.zip
    7.6 KB · Views: 42
  • AnalysisOregonDecodeBehaviour-Forum.pdf
    197 KB · Views: 47
Thanks.
Some questions. may be not related to the issue:
1) Why does it use a comparator - the input is digital?
2) what is this "digitalwritefast.H" stuff ? Teensy supports digitWriteFast out of the box, without includes.
3) Why this include - there is the slow digitalWrite() used in the code?
 
Hint: LTO can be buggy or have strange effects. Don't use it if you have issues. LTO is a good way to make a program NOT work :)
Without deep analysis, I can say: That code is too complicated.

Keep it simple!!

- use digitalWriteFast (ConstantPinNumber, val)
- Don't play with registers and overcompilcated stuff. I think there is no need to use the comparator. Use attachInterrupt() on a pin. (pinMode() input before)
You can do all this without this overcomplicated things... The 7400 is digital. (a schmitt-trigger may be better)
- what is this digitalwrite(reg +x, ...) stuff for? Do you really need it?
 
Last edited:
Why does it use a comparator - the input is digital?
For testing and to reconstruct the effects replaying the wav file generates a clean digital signal which will not need a comparator.
But the real application gets the output of a 433 MHz receiver which not only sees the pure digital sensor signal. There is a lot of other signals on the air. There are many small spikes, high, medium and low ones, on the output of the receiver. The Teensy comparator contains a filter which suppresses small spikes. This feature reduces the number of interrupts.

Decoding of weather sensor data is only one part of the planned project.
Finally the Teensy shall decode weather data, control a GSM module, and play speach from a SD card. Decoding and playing speach both need frequent interrupts. Therefore I use the comparator to get a better signal, with less interrupts from the 433 MHz receiver, to reduce processing load for decode.
The problem is not the comparator. It is the processing of interrupts from the comparator when distorting signals are coming from the receiver.

what is this "digitalwritefast.H" stuff ? Teensy supports digitWriteFast out of the box, without includes
I did not know this. Thank you, I will use it.
But btw, the digitalWrite() statements in the code only are inserted to observe program execution with a logic analyzer. They have no influence on program execution, except somewhat elongated interrupt processing. The outputs on the Serial Monitor are the same with and without the digitalWrite() statements.

You can do all this without this overcomplicated things... The 7400 is digital. (a schmitt-trigger may be better)
OK, the 7400 just was available at hand. The only purpose is making a digital high/low signal from the +-1V signal coming out of the headphone connector. This way the wav files can be used to test program behaviour and to reproduce the described effects.
 
Hint: LTO can be buggy or have strange effects. Don't use it if you have issues. LTO is a good way to make a program NOT work
Well, in a former post I got this answer too.
But in this case it is necessary to compile with LTO in order to get correct results.
Without LTO every second data set is missed and switching between data buffers (there are four) does not happen.
 
hi, problem 1 is solved.
The code was initially written for an Arduino controller.
The decoder class has been transfered to Teensy code without any modification.
In C++ for Arduino the type char is signed, but in C++ for ARM char is unsigned!
The return type of function decode() in OregonDecodeV3_2.h is char. Therefore the condition in the second line of
Code:
dc=decode(width);
if (dc==-1) resetDecoder();
never will be true, i.e. never a call to resetDecoder().

Problem 2 still is open.
But now I will change all types char, word, etc. to int8_t, uint16_t, etc. Perhaps there are more such effects in the code.
 
Hi,
both problems now have settled down.
As already posted, problem 1 was a matter of char being unsigned for ARM but signed for Arduino.
Now problem 2 is solved too. It was a char array overflow.

Compilation without LTO now works fine.

Thank you for your time and tipps.

NikoTeen
 
I have no access to the compile line because I am compiling from the Arduino/Teensyduino IDE.
But nevertheless, what does it mean: -Wextra?
 
I believe it simply turns on additional compiler warnings. Some of them are probably mentioned in:
https://gcc.gnu.org/onlinedocs/gcc-...lect-Options.html#C_002b_002b-Dialect-Options

The first thing I would do, if you have not already done it, is to tell compiler to output all compiler warnings.

Go to file menu, click on preferences, and one of the things in dialog is compiler warnings: make sure all is chosen.

I have not looked lately

Note: I also turn on verbose output for compiles in same dialog, so you can see the generated command lines.
And for example one compile file for a T4 looks something like:
Code:
"C:\\arduino-1.8.12\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -std=gnu++14 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=152 -DARDUINO=10812 -DARDUINO_TEENSY40 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_766275/pch" "-IC:\\arduino-1.8.12\\hardware\\teensy\\avr\\cores\\teensy4" "C:\\arduino-1.8.12\\hardware\\teensy\\avr\\cores\\teensy4\\HardwareSerial1.cpp" -o "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_766275\\core\\HardwareSerial1.cpp.o"

You can add the -Wextra by editing the platform.txt file (in my case this is at <Where areduino is installed>/hardware/teensy/avr/platform.txt

and edit and change the c++ lines to something like:
Code:
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{build.toolchain}{build.command.g++}" -c {build.flags.optimize} {build.flags.common} {build.flags.dep} {build.flags.cpp} {build.flags.cpu} {build.flags.defs} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DF_CPU={build.fcpu} -D{build.usbtype} -DLAYOUT_{build.keylayout} "-I{build.path}/pch" {includes} "{source_file}" [COLOR="#FF0000"]-Wextra [/COLOR]-o "{object_file}"

With this you can then do another build and see all of the new warnings. Note: I am seeing lots of message in the core area mainly with unused parameters. Like:
Code:
In file included from C:\arduino-1.8.12\hardware\teensy\avr\cores\teensy4\WProgram.h:50:0,

                 from C:\arduino-1.8.12\hardware\teensy\avr\cores\teensy4\Arduino.h:6,

                 from C:\arduino-1.8.12\hardware\teensy\avr\cores\teensy4\HardwareSerial.cpp:33:

C:\arduino-1.8.12\hardware\teensy\avr\cores\teensy4\avr_emulation.h:81:41: warning: unused parameter 'val' [-Wunused-parameter]

  inline SPCRemulation & operator = (int val) __attribute__((always_inline)) {

                                         ^

C:\arduino-1.8.12\hardware\teensy\avr\cores\teensy4\avr_emulation.h:142:42: warning: unused parameter 'val' [-Wunused-parameter]

  inline SPCRemulation & operator |= (int val) __attribute__((always_inline)) {

                                          ^

C:\arduino-1.8.12\hardware\teensy\avr\cores\teensy4\avr_emulation.h:199:42: warning: unused parameter 'val' [-Wunused-parameter]

  inline SPCRemulation & operator &= (int val) __attribute__((always_inline)) {
Again there are a reasonable number of these that maybe we should go through and mark the code to say yes we know that these are unused...
 
Again there are a reasonable number of these that maybe we should go through and mark the code to say yes we know that these are unused...
In C code you would need something like
Code:
int foo (int a, int b __attribute__ ((unused)))
{
}

In C++ you can also just eliminate the name:
Code:
int foo (int a, int)
{
}
 
Back
Top