Which registers does the IDE set?

I am playing a bit around with programming registers in the Arduino. And I noticed that the Arduino has somewhere some code that sets some registers in the Arduino by defaultAt least the "TCCR0A – Timer/Counter Control Register A" has been set for the millis() function I think.

Is my assumption correct? And if I am correct, where can I find a list of this? Or better disable it.

I know I can override a setting in the setup by writing new values to a register, but I don´t like to undo things in code.

Lots of under the hood register manipulation goes on.

Unless you have a need, let sleeping dogs lie.

If you want to learn about the registers, read the data sheet for that controller.

Any IDE should not alter registers (MCU internal setting), unless there is a debug script executed doing so.

Potentially: your Arduino boots and starts and this code changes registers.
When debugging code, e.g. to look for a register set and not the default reset value anymore: there was code executed which has done the change. You have to understand which code is executed before you do the observation (e.g. the startup code, code before your breakpoint).

I cannot imagine that the IDE itself changes registers (it would need to connect and execute code to do so, hard to believe this happens).

Locate main.cpp on your PC. For AVR, it's shown below. Next locate the function init() (use e.g. grep) and check it out.

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

On my Windows system for AVR, the files are
C:\Users\sterretje\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino\main.cpp
C:\Users\sterretje\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino\wiring.c

You can repeat for initVariant() though I could not find it for AVR.

Write your own main() :wink: Place this in your sketch; it will iverride the existing one. There will be no need for setup() and loop()

void main()
{
}

That from the main() is of course a good idea. Thank you.

The thing is that I want to control some of the registers, for specific tasks . Therefor I would like to have a list of register settings done by the IDE/Main.cpp. Have the luxury of the right settings for USB/Serial connection, but able to use own interrupt for brown out detection. To make an example.

Perhaps I want to have the good stuff from both world. The control of the hardware like other development environments, but the easiness of the Arduino IDE. :wink:

None of the hardware on an AVR is "protected" in any sense. So you can always completely overwrite registers to a new value (at the possible expense of having some arduino feature stop working correctly.)

Brownout is not a good example. There is no "brownout interrupt"; only a HW reset whose trigger level is controlled by fuses, rather than registers. All you can really do is turn off the brownout detection in order to achieve lower power in sleep modes.

By default, on an AVR, the initialization code sets up timer0 to cause the periodic interrupt, all the other timers in anticipation of PWM output, and the ADC in anticipation of Analog input. But for the exact details, you'll have to look at the source code; there can be a lot of variation depending on exact CPU type, and which libraries or functions are included (for example, a direct-USB Arduino (like Leonardo) will include (usb)Serial functions regardless of whether they're used by the sketch, because they're needed to implement the "reset for new sketch upload" functionality over USB, while a UART-based Arduino (Uno) will only include (uart) Serial functions if you actually USE "Serial" in the sketch.)

I grabbed the brown out as a quick example without reading the datasheet.

I think I ask too much here by eating from to. Arduino IDE is perfect for small project and gets good results in here, not to patronize it. I want to have easiness for things set like serial port, but in depth with other settings or save size. Or I should help in the project, or use another development tool, or accept how this works.

Reverse engineering is not what I prefer. It costs time and is quite prone for errors, and I rather had a document or setting in the IDE to select options. I debugged/read some code to found out about Timer0 and what delay() exactly does.

Yes, you have to keep in mind that the "target audience" for Arduino is people that stay withing the Arduino framework. All the documentation is aimed at them, and there isn't really any "internals documentation." (although, if you step into the broader space of 3rd party "cores" for some of the new chips (say, MegaTinyCore), you can find quite a lot of recorded discussion /thoughts as the developers struggle with "which timer makes most sense here" and similar.)

On the bright side:
Arduino rarely touches the hardware that it doesn't use. Want to use the Analog Comparator, SPI, TWI? They haven't been touched unless you loaded a relevant library.
The amount of code you have to "reverse engineer" by "read the source" is actually quite small. People new to the Arduino code tend to think that the core is some overreaching mass of bloated code, when in fact it's a very lightweight scaffold. I mean, the "init()" function on an Uno is a total of 80 bytes (less than 40 instructions.)

And you can always ask specific questions here. You may get a certain number of "why would you want to do that?" responses, which can be ignored even when they're sensible, but usually there is someone else who is interested in the internals.

(it gets messier if you're dealing with one of the RF-enabled cores that runs Arduino on top of MbedOS on top of a vendor SDK :frowning: )

If you want granular control over how much the IDE configures, you don;t want to be using the official core. or using core API functuions. some Arduino functions hide a HUGE amount of complexity.

Pick any pin that has PWM, and make a very tight loop calling digitalWrite() on it. Make it digital write something 1000000 times (it writes to a volatile register hence it cannot be optimized away). Then time how long thatt takes.

Measure (with serial timestamps or a stopwatch - ideally disable millis entirely) how long it takes. Repeat with a pin with no PWM.

Then repeat with each digitalWrite() (whether high or low) replaced with

PINx |= 1<< n;

where x is letter of the port and n is bit of port.

If on a post-2016 AVR, instead:

VPORTx.PINx |= 1<<n;

The last one, at 16 MHz, would 10000000 iterations in a bit over a half second.

(if the loop didn'[t have a couter, that's a 4 cycle loop, adding a downcounting 32-bit number and that'll probly be like clocks per loop? Maybe 6. So 10-12 clocks. 1m iterations in under a second,

The other two are.... a different story. I think digitalWrite() on a pin well endowed take >10 times that, >5times for a pin with no PWM.

I think the others are are maybe 5-10x that.