Unexpected behavior if the pin number argument

/ The Arduino’s digitalRead, digitalWrite, and pinMode functions will have
// unexpected behavior if the pin number argument happens to be greater than
// NUM_DIGITAL_PINS. We protect users of our library from that.

Dear All I have found above comments from Zumo32U4ProximitySensors.cpp can you please more elaborate the how it happen unexpected behavior of the arduino pin

Thanks

Hello.

You can see the source code for the Arduino digitalRead, digitalWrite, and pinMode functions in wiring_digital.c in the official Arduino AVR core. Each of those functions contains lines like the following:

uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);

The digitalPinTo* macros, which are defined in Arduino.h, use the pin number as the array index without doing any bounds checking:

#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )

Therefore, if the pin number is too large, those macros will read from some unrelated part of flash memory and return invalid results, which can cause the digitalRead, digitalWrite, and pinMode functions to operate on some unexpected pin that you did not specify. You might think that digitalRead does not modify anything so it should be safe, but it actually turns off PWM on the pin it is operating on.

–David

Is it important to check bounds checking

What do you mean by “pin number is too large”

if pi number loo large it has protect by array index see hear pins_arduino.h
What should be the reason to use large pin number I mean out of the microcontroller pin number



const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
	PD, /* 0 */
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PB, /* 8 */
	PB,
	PB,
	PB,
	PB,
	PB,
	PC, /* 14 */
	PC,
	PC,
	PC,
	PC,
	PC,
};

if (port == NOT_A_PIN) return;

Could you please point out operation of large number in Zumo32U4 Where it can happened with Zumo32U4. I mean which piece of code in Zumo32U4

I do not see anything in the code you posted that looks like a bounds check. If you accidentally pass an invalid pin number to pinMode, it will calculate some invalid addresses in program memory, read some bytes from those addresses with pgm_read_byte, and then make decisions based on those invalid bytes. Comparing one of those invalid bytes to NOT_A_PIN does not help much, because the invalid bytes read from the program memory can be any value between 0 and 255.

The bounds checking in Zumo32U4ProximitySensors.cpp helps prevent unexpected behavior if a user of the library accidentally uses invalid pin numbers, but it is not something you generally need to worry about in your own code if you make sure your pin numbers are right.

–David

Dear David
In the case of PWM
Is it possible to change pin input output while PWM is running and without effecting it . Therefore i believe PWM off situation would not issue that much

Can you elaborate more about bounds checking by using a example your code and how it implemented that Arduino do not have

Thanks in advanced

I do not understand your question about PWM. My point about digitalRead still stands: calling it with invalid pin numbers is not safe because it could change the configuration of a random pin.

You can see an example of bounds checking a few lines below the comment you quoted in your first post:

if (pin < NUM_DIGITAL_PINS)

–David

I am telling that PWM off is not a issue when calling digitalWrire() because it is not need to write to the pin while PWM is ruing right?

Of course you probably would not intentionally call digitalWrite on a pin using PWM unless you actually wanted to turn off PWM on that pin. The bounds checking is to help prevent a mistake in your code from affecting an unrelated pin.

–David

1 Like