The cause is UART initialization with init() in wiring.c. I think init() should be done before executing the constructor.
I need to recompile the C, C ++ libraries to solve the above. I built according to the following, but the library was not rebuilt. It looks like you downloaded the binary.
My hope is
I want to get the source code of the Arduino C, C ++ library and modify init () to execute the constructor.
I want to add a dummy weak function to init () and add UART initialization processing from the sketch.
The above process is considered a desirable response. Please add it to the regular version of Arduino.
I was able to analyze so far with the support of Joyal John (Arduino Support Team). Thank you!
Yoshiyuki_Koizumi:
I made the sketch below and ran the UART initialization. But Serisl doesn't work.
This is normal and expected. You should never do something like this in a constructor. Instead, add a begin() member function to the class.
Yoshiyuki_Koizumi:
I think init() should be done before executing the constructor.
That's not how it works.
Yoshiyuki_Koizumi:
I want to get the source code of the Arduino C, C ++ library
The code used depends on which board you're compiling for.
An easy trick to finding the location of the boards platform on your computer is:
Select a board from the hardware package you want to find from the Tools > Board menu
File > Examples > SPI > BarometricPressureSensor (or any other SPI example sketch)
Sketch > Show Sketch Folder
Move up folder levels until you reach the one that contains boards.txt
You'll find the core library code in the "cores" subfolder.
Yoshiyuki_Koizumi:
and modify init () to execute the constructor.
2. I want to add a dummy weak function to init () and add UART initialization processing from the sketch.
3. The above process is considered a desirable response. Please add it to the regular version of Arduino.
What about the people who don't use UART in their sketch? Wouldn't it be easier for people to just configure UART from their sketch, the way it has always been done? Why do you feel this is needed?
I want to check the program to be executed before the setup function with Serial.print. It's understandable that it's better to do it in Begin instead of in the constructor, but I think doing init () before executing the constructor will solve the problem.
This is the second problem for me.
My number one hope is Arduino's C, C ++ library source and Build environment. Building Arduino · arduino/Arduino Wiki · GitHub looks good, but I think it lacks information.
I understand that the global initialization process in C ++ is incomplete. Still, the current build of running init () after running the constructor doesn't seem to be preferable. 1. After memory initialization, 2. Initialize the hardware (init ()) and 3. I think it is better to initialize the global variables (consul tractor). I want to change my Arduino, so I need an environment for recompiling C and C ++ libraries.
"Don't use UART in their sketch?"
Weak functions that do nothing are ignored by the optimization. If you don't need to initialize the UART, don't call it. Weak initVariant () is still defined in main (). With Leonardo, you can add processing from the sketch to be performed before USB initialization. If it is UNO, there is no USB initialization, so if you describe it in setup, the result will be the same.
These are from avr-gcc and avr-libc. This is not Arduino's code, they use the industry standard open source toolchain for AVR microcontrollers. https://www.nongnu.org/avr-libc/
The C++ compiler inserts startup code, as part of C++, to call the constructors.
An embedded compiler, in general, does not touch peripherals of the chip.
That means that to have init() called before constructors, the startup code would have to partially initialize the language-oriented stuff (stack, heap, bss, copy initialized variables to RAM, etc), call user-provided code that would include the init() code, and then go on and do more language-oriented stuff (constructors.)
(some of the more complex chips do have a system_init() in their startup code, that does basic things like set up the clock, memory wait states, and stuff. But I think they try pretty hard to keep that VERY hardware-oriented, and not "connected" to compiler structures.)
Yes, the startup code is open, and you could theoretically provide and build your own crt*.o files, at the expense of being incompatible with ... nearly everything.
This is one of the problems with complex languages like C++ in deeply embedded systems.
Thank you.
I built the library, but it wasn't successful.
I'm not familiar with building libraries.
・ Build is Ubuntu
・ Downloaded and unpacked avr-libc-2.0.0.tar.bz2.
・ I ran sudo apt-get install build-essential gperf bison subversion texinfo zip automake flex libtinfo-dev pkg-config.
・ mkdir work; cd work
・ ../avr-libc-2.0.0/configure
・ Because I was scolded by
../avr-libc-2.0.0/configure --build=./config.guess --host=avr
・ I get an error
ky @ ky-VirtualBox: ~ / avr_gcc_build / work $ ../avr-libc-2.0.0/configure --build = ./config.guess --host = avr
bash: ./config.guess: No such files or directories
checking build system type ... x86_64-unknown-linux-gnu
checking host system type ... avr-unknown-none
checking if configuring for cross compile ... yes
checking if target host is avr ... yes
checking for a BSD-compatible install ... / usr / bin / install -c
checking whether build environment is sane ... yes
checking for avr-strip ... no
checking for strip ... strip
checking for a thread-safe mkdir -p ... / usr / bin / mkdir -p
checking for gawk ... no
checking for mawk ... mawk
checking whether make sets $ (MAKE) ... yes
checking whether make supports nested variables ... yes
checking for avr-gcc ... no
checking for gcc ... gcc
checking whether the C compiler works ... yes
checking for C compiler default output file name ... a.out
checking for suffix of executables ...
checking whether we are cross compiling ... no
checking for suffix of object files ... o
checking whether we are using the GNU C compiler ... yes
checking whether gcc accepts -g ... yes
checking for gcc option to accept ISO C89 ... none needed
checking whether gcc understands -c and -o together ... yes
checking for style of include used by make ... GNU
checking dependency style of gcc ... gcc3
checking for avr-as ... no
checking for as ... as
checking dependency style of gcc ... gcc3
checking for avr-ranlib ... no
checking for ranlib ... ranlib
checking for avr-ar ... no
checking for ar ... ar
configure: error: Wrong C compiler found; check the PATH!
ky @ ky-VirtualBox: ~ / avr_gcc_build / work $
・I think the settings are insufficient. What should i do?
There is no clock setting etc. in Arduino, but ini () initializes the port. I think this process is a hardware initialization process such as clock setting. It was pointed out that Arduino does not recommend initializing the hardware in the constructor, but should do it in begin. Confirmed. However, I don't think it's good for the global constructor to work before the hardware is initialized. It's not a complicated chip, but I would like to have system_init ().
If it's a weak function, you can ignore it if you don't use Arduino.
The case that the library cannot be build (no C ++ library?)
It seems that the path of avr-gcc was insufficient. Build can now be run with "sudo apt install gcc -avr".
However, libgcc.a is not created. avr/7.3.0/avr5n/libgcc.a (_tablejump2.o) is used for the constructor startup process.
Also, the extracted avr-libc-2.0.0 did not have a .cpp file. It seems that avr-libc-2.0.0 does not include the C ++ library.
Build can now be run with "sudo apt install gcc -avr".
You shouldn't need to build a complete avr-gcc and avr-libc just to get the changes you want to the startup code. Just extract the gcrt1.S file from avr-libc and figure out how to compile it for the m328 (which may be tricky, since they seem to have arranged for one source file to compile for ANY of the many AVR varieties.
You already have a usable avr-gcc and "the rest" of avr-libc.
I checked gcrt1.S of avr-libc-2.0.0. I have a question.
-Compile (uno) the above sketch, disassemble the elf, output the map file, and see how gcrt1.S is used.
-There are 26 vectors of uno (328p). There are 26 on the disassemble, but 127 on gcrt1.S.
-In disassembly, there is a constructor call process with __do_global_ctors before calling main. gcrt1.S does not have this process.
-From the map file, __do_global_ctors seems to have been imported from avr5 \ gcc.a (_ctors.o).
-It seems that lib / avr5 / crtatmega328p.o is imported from the map file as .vectors.
I don't think gcrt1.S can be used as it is. It seems that the process is being done in the build of the library.
Also, I don't understand the call to the constructor.
I want to know.
I compiled the sketches on the Arduino of microchip studio 7 and disassembled them and compared them to the Arduino disassembled.
There is a difference in the call part of the constructor.
In microchip studio 7, it seems that -flto is omitted at compile time.
Specifying optimizations will make a big difference. I wonder if microchip studio 7 is like this. I am surprised.
If you look at the ".sections" values in gcrt.S, you'll see that each part of the initialization uses a different section. This means that other source modules can add code to each of those sections. PROBABLY the C++ compiler adds the call to __do_global_ctors() in between .init5 and .init8 (hmm. Looks like .init6: Memory Sections )
It looks like, theoretically at least, you can could move a call to the arduino init() function in .init5, even within your own source code, and it would happen after the basic memory setup and before the call to the constructors, or main() (which happens in .init9) That actually seems a lot cleaner than I was expecting.
(it should also work if you added an XCALL to init() in the existing .init4 code in gcrt1.S, I think.)
I compiled the sketches on the Arduino of microchip studio 7 and disassembled them and compared them to the Arduino disassembled.
There is a difference in the call part of the constructor.
In microchip studio 7, it seems that -flto is omitted at compile time.
Specifying optimizations will make a big difference. I wonder if microchip studio 7 is like this. I am surprised.
・ Are Visual Studio Code plug-ins and Platform IO plug-ins at the same level?
・ Is it okay to attach Arduino to tools with different optimization levels?
I haven't found the Arduino linker script. I want to check the linker script, so please tell me where it is. gcrt1.S does not correspond to a specific chip.
gcrt1.S has a section definition but no code. If I write my own code in section N, will it be expanded to the .ection definition location of gcrt1.S?