trying to understand how the compiler works...

Post here first, or if you can't find a relevant section!
Post Reply
stevestrong
Posts: 1747
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

trying to understand how the compiler works...

Post by stevestrong » Sun Mar 19, 2017 9:55 am

I am still fighting to understand what is determining the compiler to mess up my code, or to generate a code which I don't expect...

Just toggling some GPIOs on maple mini clone:

Code: Select all


#include <libmaple/gpio.h>

// set pins to output the 8 bit value
#if 1
 #define write8(c) {digitalWrite(PB0, (c&BIT0)?HIGH:LOW); \
					digitalWrite(PB1, (c&BIT1)?HIGH:LOW); \
					digitalWrite(PB2, (c&BIT2)?HIGH:LOW); \
					digitalWrite(PB3, (c&BIT3)?HIGH:LOW); \
					digitalWrite(PB4, (c&BIT4)?HIGH:LOW); \
					digitalWrite(PB5, (c&BIT5)?HIGH:LOW); \
					digitalWrite(PB6, (c&BIT6)?HIGH:LOW); \
					digitalWrite(PB7, (c&BIT7)?HIGH:LOW); }
#else
 void write8(uint8_t c) {
 	digitalWrite(PB0, (c&BIT0)?HIGH:LOW);
	digitalWrite(PB1, (c&BIT1)?HIGH:LOW);
	digitalWrite(PB2, (c&BIT2)?HIGH:LOW);
	digitalWrite(PB3, (c&BIT3)?HIGH:LOW);
	digitalWrite(PB4, (c&BIT4)?HIGH:LOW);
	digitalWrite(PB5, (c&BIT5)?HIGH:LOW);
	digitalWrite(PB6, (c&BIT6)?HIGH:LOW);
	digitalWrite(PB7, (c&BIT7)?HIGH:LOW);
 }
 /* fast write
 #define write8(c) { uint32_t val = (((c^0x00FF)<<16) | c); \
					GPIOB->regs->BSRR = val; }
 */
#endif


void setup() {
  // put your setup code here, to run once:
	Serial.begin(); // USB port
	//while ( !Serial.isConnected() ) ; // wait for USB connection
	delay(6000);

	Serial.println("\n***** Port pin toggle test *****\n");
	GPIOB->regs->CRL = 0x33333333; //	// set the lower 8 bits as output
}

uint8_t c = 0;

void loop() {
  // put your main code here, to run repeatedly:
#if 1
	write8(c++);
#else
	write8(c);
	c++;
#endif
}
Problem:
In this configuration PB0..2 won't toggle at all, PB3..7 and up will toggle as I would expect from PB0..4.

Solution:
If I set either line 6 or line 47 to "#if 0", then all pins toggle as expected.

It seems that there is an unlucky combination of using several "digitalWrite()" and variable increment (c++) within a define.

Can someone explain me what is actually happening here, what am I doing wrong?
Attachments
STM32_GPIO_toggle_test.ino
(1.32 KiB) Downloaded 8 times

stevestrong
Posts: 1747
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

[SOLVED] trying to understand how the compiler works...

Post by stevestrong » Sun Mar 19, 2017 10:09 am

OK, I think that the compiler generates the following code from #define write8(i++):

Code: Select all

digitalWrite(PB0, (i&BIT0)?HIGH:LOW); i++;
digitalWrite(PB1, (i&BIT1)?HIGH:LOW); i++;
digitalWrite(PB2, (i&BIT2)?HIGH:LOW); i++;
digitalWrite(PB3, (i&BIT3)?HIGH:LOW); i++;
digitalWrite(PB4, (i&BIT4)?HIGH:LOW); i++;
digitalWrite(PB5, (i&BIT5)?HIGH:LOW); i++;
digitalWrite(PB6, (i&BIT6)?HIGH:LOW); i++;
digitalWrite(PB7, (i&BIT7)?HIGH:LOW); i++;
It just adds the variable increment after each code line.
This would explain why the bits are shifted by 3 bits (multiplied by 8), but the question is: why would the compiler do this?

Answer:
Because the compiler replaces all "i" instances by "i++"...

User avatar
ddrown
Posts: 136
Joined: Sat Jan 09, 2016 4:49 am

Re: [SOLVED] trying to understand how the compiler works...

Post by ddrown » Sun Mar 19, 2017 3:39 pm

stevestrong wrote:OK, I think that the compiler generates the following code from #define write8(i++):

Code: Select all

digitalWrite(PB0, (i&BIT0)?HIGH:LOW); i++;
digitalWrite(PB1, (i&BIT1)?HIGH:LOW); i++;
digitalWrite(PB2, (i&BIT2)?HIGH:LOW); i++;
digitalWrite(PB3, (i&BIT3)?HIGH:LOW); i++;
digitalWrite(PB4, (i&BIT4)?HIGH:LOW); i++;
digitalWrite(PB5, (i&BIT5)?HIGH:LOW); i++;
digitalWrite(PB6, (i&BIT6)?HIGH:LOW); i++;
digitalWrite(PB7, (i&BIT7)?HIGH:LOW); i++;
It just adds the variable increment after each code line.
This would explain why the bits are shifted by 3 bits (multiplied by 8), but the question is: why would the compiler do this?

Answer:
Because the compiler replaces all "i" instances by "i++"...
Yup, you got it. You can look to inline functions as another alternative.

User avatar
Rick Kimball
Posts: 1038
Joined: Tue Apr 28, 2015 1:26 am
Location: Eastern NC, US
Contact:

Re: trying to understand how the compiler works...

Post by Rick Kimball » Sun Mar 19, 2017 5:00 pm

If I'm using a macro i tend to avoid things like post increment or addition or anything other than passing a value to it.
-rick

Post Reply