Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update toolchain to fix pgm_read_float_unaligned #8091

Merged
merged 3 commits into from
Jun 4, 2021

Conversation

earlephilhower
Copy link
Collaborator

Fixes #8083

@dok-net
Copy link
Contributor

dok-net commented Jun 1, 2021

@earlephilhower I can't quite make up a sketch where accessing unaligned data directly fails, with PROGMEM and all, it just always gives the right values :-( Do you have some code to test that pgm_read_xxx even makes a difference?

@earlephilhower
Copy link
Collaborator Author

Make sure the exception handler is disabled. The code in the original bug fails w/master and passes w/this. Also use pgm_read_xxx_aligned or pgm_read_xxx_unaligned to ensure you pull in the expected version of the macros.

@dok-net
Copy link
Contributor

dok-net commented Jun 1, 2021

Here is one that works with this PR, and proves that master doesn't work. It's less synthetic in that it doesn't fabricate an array in RAM, but puts the constants into PROGMEM. If one adds const to the constants structure instance, the compiler optimizations outsmart the test and then it proves nothing. That is, master still fails in the pgm_read_float_unaligned call, but one can access constants.pi directly ;-)

static const uint8_t pi_array[] PROGMEM = { 42, 0xdb, 0x0f, 0x49, 0x40 };
static struct __attribute__((__packed__)) {
	uint8_t pad = 42;
	float pi = PI;
	double pi_d = PI;
} constants PROGMEM;

void setup()
{
	Serial.begin(74880);
	while (!Serial);
	delay(500);
	Serial.println("pgmread");
	float pi = PI;
	Serial.println(pi, 6);
	for (int i = 0; i < 4; ++i)
		Serial.println(*((uint8_t*)&pi + i), 16);
	Serial.println(pgm_read_float_unaligned((float*)&pi_array[1]), 6);
	Serial.println(pgm_read_float_unaligned(&constants.pi), 6);
	//Serial.println(pgm_read_double_unaligned(&constants.pi_d), 11);
}

void loop()
{

}

@earlephilhower
Copy link
Collaborator Author

By exceptions I meant HW exceptions, not C++ exceptions. The menu name is "Non 32-bit access" or something similar. The default now may include a HW exception handler to (very, very) slowly emulate the misaligned reads.

The examples in the main bug cover the failure case, even though they use RAM. ROM or not, the misalignment is the real problem (since float = 32b = natural read from anywhere, double = 64 bit = 2x32b natural reads from anywhere). You can't do non-32b aligned float reads (w/o the HW exception handler) from anywhere.

@d-a-v d-a-v merged commit 114a726 into esp8266:master Jun 4, 2021
@earlephilhower earlephilhower deleted the pgmreadfloatfix branch June 4, 2021 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pgm_read_float_unaligned() ignores the second word
3 participants