cancel
Showing results for 
Search instead for 
Did you mean: 

MCU stuck when convert point to double

nicekwell
Associate II

There is a array:

uint8_t dat[8] = {0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x5e, 0x40};

It means a double variable data in memery. The value is 123.45.

This code can be run in my computer:

int main(int argc, char *argv[])

{

  uint8_t dat[] = {0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x5e, 0x40};

  double test = *((double*)dat);

  printf("%.3f\r\n", test);

  return 0;

}

It will put: 123.450

But on stm32f103rct6. It will stuck when I run this:

 double test = *((double*)dat);

But use float will not stuck:

 float test = *((float*)dat);

So, how can I convert memery to double rightly on stm32f103? (I use stm32cubeide)

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
Piranha
Chief II

As Jan said, most likely the problem is the lack of proper alignment. That can be solved by making a buffer to be of a double type. Or even better by implementing a union, which forces the alignment to the largest element and also seamlessly converts the data.

View solution in original post

11 REPLIES 11
Ozone
Lead

> This code can be run in my computer: ...

> But on stm32f103rct6. It will stuck when I run this: ...

Do you know what endianess means ?

>  uint8_t dat[] = {0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x5e, 0x40};

>  double test = *((double*)dat);

Are you aware of the IEEE754 ?

I am sorry. I'm not sure what you mean.

I need transport data between PC and MCU. MCU send memery data and PC restore it to value. Also PC send memery data and MCU restore it.

I use python on PC. There is "pack" and "unpack" in python to convert between variable and memery.

On MCU, I use point to convert. And it works well. Such as:

  1. var to memery: (uint8_t*)(&var)
  2. memery to var: *((float*)dat), *((uint32_t*)dat), ......All types works well except double.

How do you know it sticks exactly on that line which performs the conversion?

What does "stuck"exactly mean? Hardfault?

Single-step in debugger disasm view and note which instruction causes it to go to hardfault if that was the case.

JW

I translated and mabey I know what you mean.

Both linux(64bit PC) and stm32 are little-endian.

Both linux(64bit PC) and stm32 takes 8 bytes of double.

Actually I can assign any type in python to adapt stm32.

Read the "Floating Point" section here: https://en.wikipedia.org/wiki/Endianness

Use ASCII text, i.e. strings. that saves you all the hassle and is easily portable.

Don't complicate things unnecessarily.

It is a hardfault. ​

0693W000008xdW6QAI.gif

Single step in disassembler view, to view which instruction caused the hardfault and what was the content of registers at that moment.

A wild guess, compiler used LDRD wich requires that the array be 64-bit aligned.

JW

Piranha
Chief II

As Jan said, most likely the problem is the lack of proper alignment. That can be solved by making a buffer to be of a double type. Or even better by implementing a union, which forces the alignment to the largest element and also seamlessly converts the data.

Using ASCII is actually the most ineffective and fragile way to transfer data. ARM and x86 are both little endian, therefore doesn't need an endianess conversion. And even, when some byte or word swapping is necessary, it's again far more effective and simpler than printing and parsing ASCII texts.

Forcing two computers, which both operate with binary data, to "talk" between them in a human written language is a deeply flawed concept as a whole!