Skip to content

pgm_read_float alignment issue when reading from an array of floats #6590

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

Closed
6 tasks done
maxint-rd opened this issue Oct 3, 2019 · 0 comments · Fixed by #6593
Closed
6 tasks done

pgm_read_float alignment issue when reading from an array of floats #6590

maxint-rd opened this issue Oct 3, 2019 · 0 comments · Fixed by #6593

Comments

@maxint-rd
Copy link

maxint-rd commented Oct 3, 2019

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12E]
  • Core Version: [2.5.2 (may-20-2019, installed via board manager]
  • Development Env: [Arduino IDE]
  • Operating System: [Windows]

Settings in IDE

  • Module: [Generic ESP8266 Module]
  • Flash Mode: [dout (compatible)]
  • Flash Size: [4MB (3M SPIFFS)]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz]
  • Upload Using: [SERIAL]
  • Upload Speed: [512000] (serial upload only)

Problem Description

My MmlMusic library reads tone frequencies as float values from a PROGMEM array. It worked fine for ESP8266 core version 2.5.0, but failed in cores version 2.5.1 and 2.5.2
Using the defines mentioned in issue #5628 fixed the problem, but I guess it's better to use pgm_read_float_aligned() as mentioned in pull #5692 . The default define uses the _unaligned version, but as I noticed then the floats are not properly read from the PROGMEM array.
This issue is about compatibility. The Arduino library works fine on ATmega and ATtiny MCU's.
See the sketch below for more detailed info.

MCVE Sketch

#include <Arduino.h>

const float aftTest[] = {1.23, 2.34, 3.45};
const float aftTestPGM[] PROGMEM = {1.23, 2.34, 3.45};

void setup() {
  float ftTest=0.0;
  Serial.begin(115200);  
  Serial.println("\nTesting pgm_read_float");
  Serial.print("mem array:");
  ftTest=aftTest[1];
  Serial.println(ftTest);       // should print 2.34
// uncomment to fix pgm_read_float issue
//  #define pgm_read_float(addr)            pgm_read_float_aligned(addr)
  ftTest = pgm_read_float(&aftTestPGM[1]);
  Serial.print("pgm array:");
  Serial.println(ftTest);       // should print 2.34, but prints silly large number
}

void loop() {
}

Debug Messages

Testing pgm_read_float (unfixed)
mem array:2.34
pgm array:1075167872.00
Testing pgm_read_float (fixed)
mem array:2.34
pgm array:2.34
@maxint-rd maxint-rd changed the title pgm_read_float allignment issue when reading from an array of floats pgm_read_float alignment issue when reading from an array of floats Oct 3, 2019
earlephilhower added a commit to earlephilhower/Arduino that referenced this issue Oct 3, 2019
Fixes esp8266#6590

The ASM block that implements the read-uint32-unaligned returns a
uint32_t.  The old code was doing a cast like `(float)(uint32_t ret)
which actually goes and creates a new float of the positive uint value
(approx, of course due to exponent and sign bits) which is not correct.

C and C++ don't have a concise way to convert the bits in a register
from int to float interpretation, so avoid the whole issue by making a
new function which uses the same ASM block as the read-uint32-unaligned,
just make the destination and return values as floats.
earlephilhower added a commit that referenced this issue Oct 3, 2019
Fixes #6590

The ASM block that implements the read-uint32-unaligned returns a
uint32_t.  The old code was doing a cast like `(float)(uint32_t ret)
which actually goes and creates a new float of the positive uint value
(approx, of course due to exponent and sign bits) which is not correct.

C and C++ don't have a concise way to convert the bits in a register
from int to float interpretation, so avoid the whole issue by making a
new function which uses the same ASM block as the read-uint32-unaligned,
just make the destination and return values as floats.
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 a pull request may close this issue.

1 participant