Author Topic: This is an armclang bug, isn't it? [It wasn't]  (Read 735 times)

0 Members and 1 Guest are viewing this topic.

Offline emece67

  • Frequent Contributor
  • **
  • Posts: 418
  • Country: es
This is an armclang bug, isn't it? [It wasn't]
« on: August 27, 2021, 01:59:51 pm »
Hi,

I do have a struct (inside a class pin_) with 5 members, 1 byte each, something like:
Code: [Select]
struct pin_::conf_t {
  enum mode_t : uint8_t {
    GP_IN = 0,
    GP_OUT,
    ALTERNATE,
    ANALOG
  };

  enum type_t : uint8_t {
    PUSH_PULL = 0,
    OPEN_DRAIN
  };

  enum speed_t : uint8_t {
    LOW_SPEED = 0,
    MEDIUM_SPEED,
    HIGH_SPEED,
    VERY_HIGH_SPEED
  };

  enum pull_t : uint8_t {
    PULL_NONE = 0,
    PULL_UP,
    PULL_DOWN
  };

  enum function_t : uint8_t {
    AF0 = 0, AF1, AF2, AF3, AF4, AF5, AF6, AF7,
    AF8, AF9, AF10, AF11, AF12, AF13, AF14, AF15
  };

  mode_t      mode;
  type_t      type;
  speed_t     speed;
  pull_t      pull;
  function_t  function;
};

Then I do have a method in class pin_ that takes one of such structs and configures the corresponding pin_:
Code: [Select]
void pin_::configure(conf_t const& conf) const;
Then I call such method with a literal parameter:
Code: [Select]
    configure({
      .mode     = conf_t::GP_OUT,
      .type     = conf_t::PUSH_PULL,
      .speed    = conf_t::LOW_SPEED,
      .pull     = conf_t::PULL_NONE,
      .function = conf_t::AF0
    });
and I get a HardFault.

The reason of the HardFault is that the compiled code that sets the parameters for the method call:

generates a STR r0, [sp, #0x29] instruction that, being the offset odd, tries an unaligned memory access.

This only happens when all 5 bytes of the struct evaluate to 0. To fix this I changed the length of the 1st member of the struct from uint8_t to uint32_t.

It's me or this is definitely a compiler bug?

Regards.

NOTE: armclang is the 6.16 version that comes with Keil 5.34



« Last Edit: August 27, 2021, 10:33:21 pm by emece67 »
Information must flow.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: This is an armclang bug, isn't it?
« Reply #1 on: August 27, 2021, 04:39:38 pm »
I'd say this is a bug. I see nothing wrong with this code.

Does it do the same if instead of a literal parameter you create a structure on the stack and pass that?
Alex
 

Offline emece67

  • Frequent Contributor
  • **
  • Posts: 418
  • Country: es
Re: This is an armclang bug, isn't it?
« Reply #2 on: August 27, 2021, 07:13:19 pm »
Doing this:
Code: [Select]
    conf_t  conf;

    conf.mode     = conf_t::GP_OUT;
    conf.type     = conf_t::PUSH_PULL;
    conf.speed    = conf_t::LOW_SPEED;
    conf.pull     = conf_t::PULL_NONE;
    conf.function = conf_t::AF0;

    configure(conf);
shows the same behaviour. BUT, if the 1st member of the struct to be initialized happens not to be conf.mode, say:
Code: [Select]
    conf_t  conf;

    conf.function = conf_t::AF0;
    conf.mode     = conf_t::GP_OUT;
    conf.type     = conf_t::PUSH_PULL;
    conf.speed    = conf_t::LOW_SPEED;
    conf.pull     = conf_t::PULL_NONE;

    configure(conf);
then it works.
Information must flow.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 8227
  • Country: us
    • Personal site
Re: This is an armclang bug, isn't it?
« Reply #3 on: August 27, 2021, 08:19:14 pm »
What MCU/core you are targeting?

According to this https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_sam1444138667173.htm:
Quote
-munaligned-access is the default for architectures that support unaligned accesses to data. This default applies to all architectures supported by Arm Compiler 6, except Armv6‑M, and Armv8‑M without the Main Extension.

So if you are targeting Cortex-M4/M7, then it will default to unaligned access, so it has to be enabled in the core. Or pass -mno-unaligned-access flag.
Alex
 
The following users thanked this post: emece67, I wanted a rude username, DiTBho

Offline emece67

  • Frequent Contributor
  • **
  • Posts: 418
  • Country: es
Re: This is an armclang bug, isn't it?
« Reply #4 on: August 27, 2021, 10:32:45 pm »
What MCU/core you are targeting?

Quote
-munaligned-access is the default for architectures that support unaligned accesses to data. This default applies to all architectures supported by Arm Compiler 6, except Armv6‑M, and Armv8‑M without the Main Extension.

So if you are targeting Cortex-M4/M7, then it will default to unaligned access, so it has to be enabled in the core. Or pass -mno-unaligned-access flag.

That's it!

It is an stm32l432kc, with an M4 and, thus, supporting unaligned accesses. In any case a few days back I actively disabled unaligned access in the SCB   |O
Information must flow.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf