5

I'm working with an embedded C compiler (ARM cortex-m3 chip) and it seems to initialize the wrong value to a struct. Why does this happen? If it's an alignment issue, shouldn't the compiler know to align an int32u to a 4-byte boundary?

Note: the printf merely throws bytes out of the serial port. There is no stdio.h implementation on this chip.

typedef struct
{
    int32u startTime; 
    int16u length;
    int32u offTime;
} Cycle;

Cycle cycle = 
{
    315618000, 
    1200,
    0
};


void init()
{
   printf("\r\nInitialized! Cycle Start: %d", cycle.startTime);

   cycle.startTime = 315618000;
   cycle.length = 1200;

   printf(" Cycle Start: %d", cycle.startTime);

}

Output: Initialized! Cycle Start: 631237200 Cycle Start: 315618000

Note:: This NOT a printf issue. The debugger verifies the value in memory as 631237200 as well.

4

3 回答 3

1

[Edit] My suggested below that sizeof(int) == 2 is likely not the issue as " Cycle Start: %d", cycle.startTime readily prints out values > 64k. I suspect a padding issue. But the lower recommendation about printf() apply, even though they do not explain this issue.


The initialization of cycle in effect does a cycle.startTime = 315618000. Your int/unsigned size is likely 2, therefore the initialization overflows. Instead:

Cycle cycle = {
  315618000LU, 
  1200,
  0
  };

Your printf() should also use the matching format specifier for uint32_t

#include <inttypes.h>
printf("Cycle Start: %" PRIu32 "\n", cycle.startTime);
printf("Length     : %" PRIu16 "\n", cycle.length);
于 2013-08-23T16:13:59.683 回答
1

In some embedded systems, static initialization is not set up to happen automatically. This goes against C specifications, but sometimes that's the way it is. Note that this may be true for both data and bss segments i.e. you may find that uninitialized statics may NOT be initialized to zero either.

The solution to this is, unfortunately, system specific. You may find something in your complier system documentation that lets you invoke the initialization of the static elements.

于 2013-08-23T16:29:50.180 回答
0

You could probably find out what is happening by viewing the assembly code. I don't know if your compiler is GCC. If it is the -S flag should produce an assembly file named as the input file but with a .s extension.

With that you should be able to view what values are being assigned to the global structure variable.

Another thing that could be wrong is the printf function. If you did not use a function prototype that declares it as a varargs function like int printf(const char *fmt, ...) then the call will be done wrong.

On at least one architecture I know of, all vararg entries have maximum alignment because the function does not know what it is getting. Normal functions pass values on the stack with the declared type alignment. If printf does not have a prototype the C language will assume all arguments are int and try to pass them that way. Meanwhile the printf function itself will be trying to pull arguments as varargs and it could easily slip by a few bytes here and there.

于 2013-08-23T16:30:01.333 回答