Skip to content

EEPROM Example2_AllFunctions stalls on both the Artemis Thing Plus and ATP - possible memory alignment problem? #78

Closed
@PaulZC

Description

@PaulZC

I am loving the Artemis. It is my new favorite thing!

Subject of the issue

When running the EEPROM Example2_AllFunctions on the Artemis Thing Plus and ATP it stalls (crashes?) part way through the double (64) sequential test on both boards

Your workbench

Artemis Thing Plus and ATP
Windows Arduino IDE 1.8.10
Apollo3 Boards 1.0.15
Connected and powered via USB-C

Steps to reproduce

Run the example.

Actual behaviour

Example stalls at the EEPROM.get for the double test

32 bit tests
Size of int: 4
Location 349 should be -245000: -245000
Location 353 should be 400123: 400123
Location 298 should be -341002: -341002
Location 302 should be 241544: 241544
Size of float: 4
Location 786 should be -7.350000: -7.350000
Location 790 should be 5.220000: 5.220000

64 bit tests
Size of double: 8

Expected behaviour

This:

32 bit tests
Size of int: 4
Location 349 should be -245000: -245000
Location 353 should be 400123: 400123
Location 298 should be -341002: -341002
Location 302 should be 241544: 241544
Size of float: 4
Location 786 should be -7.350000: -7.350000
Location 790 should be 5.220000: 5.220000

64 bit tests
Size of double: 8
Location 727 should be -290.348572: -290.348572
Location 735 should be 384.957336: 384.957336

Flash Contents:
0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF

Cause and Fix

It looks like it is a memory alignment problem caused by the union of the double and the two uint32_t's

Adding attribute packed to the union seems to fix it:

void ap3_EEPROM::get(uint16_t eepromLocation, double &dataToGet)
{
  union __attribute__((packed)) { // PaulZC added __attribute__((packed))
    double lf;
    uint32_t b[2];
  } temp;
  temp.b[1] = *(uint32_t *)(AP3_FLASH_EEPROM_START + eepromLocation);     //LSB;
  temp.b[0] = *(uint32_t *)(AP3_FLASH_EEPROM_START + eepromLocation + 4); //MSB;
  dataToGet = temp.lf;
}

But here's the weird thing. This only affects the get. The update/put seems immune and yet uses the same union. It's got me confused!

Enjoy!
Paul

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions