Understanding Library Code


I am currently using and trying to understand the OneWire Library. This library helps to interact with devices on the 1Wire bus by Dallas.

Let pin = 2 be the digital pin of Arduino that is used.

The variables bitmask and baseReg (uint8_t) are initialized as

#define PIN_TO_BASEREG(pin)             (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin)             (digitalPinToBitMask(pin))
bitmask = PIN_TO_BITMASK(pin);
baseReg = PIN_TO_BASEREG(pin);

and setting the pin to low is done by

#define IO_REG_TYPE uint8_t
#define IO_REG_ASM asm("r30")
#define DIRECT_MODE_OUTPUT(base, mask)  ((*(base+1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask)    ((*(base+2)) &= ~(mask))
IO_REG_TYPE mask=bitmask;
volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask);	// drive output low
  • bitmask contains the position of the pin in the related registers DDRX, PORTX and PINX where X is A,B,C or D - depending on the pin and AVR used, right?
  • What does basereg contain?
  • If I do understand the code right, the line starting with "volatile" declares a pointer to an unsigned char called reg that is stored in register 30 of the AVR. But why is that register used? Is the pointer itself or its value stored there?
  • How does the DIRECT_WRITE_LOW macro work? Does (base+1) correspond to the DDR and (base+2) to the PORT register?

Could you please help me to answer these questions?

Thanks in advance!

Are you trying to understand how to use it, or how the library’s internal implementation works? You should not need to know what’s going on under the covers in order to use the library in your sketch.

Are you trying to understand how to use it, or how the library's internal implementation works? You should not need to know what's going on under the covers in order to use the library in your sketch.

I try to understand how the library's implementation works. I know what it does but I want to know why it works.

I do know that I don't need this to just run it, but I don't want to use something I don't understand :wink: Therefore I already read about (PORT-,PIN-,DDR-) registers and some AVR stuff, but nevertheless am currently stuck.

I think extasic is asking the right question :
There is a big risk in using libraries as a black box without an understanding of how they work…
I think many of the security problems we have are born there : someone quickly reuses a library not understanding how it works and especially what are its limitations.

I used the OneWire library on an ESP8266 (Wemos D1) and it was not working… Until after many hours I decided to just try another pin (GPIO12 io GPIO16)… and all of sudden it just worked. Conclusion : there are important bugs or limitations to the ESP8266 version of this library, and I don’t want to use it for development without better understanding how it works.

There is a big difference in hacking a few sketches together and serious development for mission critical devices.
Do I want to reinvent the wheel? No
Are the current libraries mature and proven? I don’t think so.

That means wanting to know how a library works is a very legitimate question. In fact a good library should self-document that, so you could quickly learn how it does the job.

This link may help: Arduino - PortManipulation

What they are doing is accessing the pins directly without using digitalRead or digitalWrite. This way it is much faster because it doesn’t involve some of the safeguards that are present in the digitalRead and digitalWrite functions. If you know what you are doing and are careful then you don’t need those safeguards and this is a much faster way to read from and write to pins.