0

I am trying to set up the internal registers of a HCS12 processor using unions. Here is the way I currently have the unions:

union byte{
    struct{
        unsigned int B0: 1;
        unsigned int B1: 1;
        unsigned int B2: 1;
        unsigned int B3: 1;
        unsigned int B4: 1;
        unsigned int B5: 1;
        unsigned int B6: 1;
        unsigned int B7: 1;
    }idv;
    unsigned int All: 8;
};

union allPurpose{
    struct {
        union byte A;
        union byte B;
    } AB;
    unsigned int D: 16;
};

The issue is that when I initialize A to 170 and B to 187 using the int All. D should be 43,707 but is 170. I know that nested unions work but for some reason it is not working. If anyone can see something wrong and can help it would be appreciated.

Edit: Here is the code that is using the union in.

HCS12.accumulator.AB.A.All=0xAA;
HCS12.accumulator.AB.B.All=0xBB;
printf("\nReg A: %d",HCS12.accumulator.AB.A.All);
printf("\nReg B: %d",HCS12.accumulator.AB.B.All);
printf("\nReg D: %d",HCS12.accumulator.D);

The Union allPurpose is just in a another structure.

Nathan
  • 1
  • 1

2 Answers2

0

You cannot assume that union byte A; and union byte B; are packed contiguously in memory.

(In fact, on modern architectures, is unlikely that they would be due to their being only one byte in size).

The specific packing arrangements are down to compiler and platform choice. A typical arrangement is 4 byte packing, meaning that your structure looks like this:

 struct {
     union byte A;
     /*Three bytes of packing*/
     union byte B;
 } AB;
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Generally this is good advice. However, HCS12 is a somewhat modern architecture that doesn't give a damn about alignment. You can read 8 bit or 16 bit accesses anywhere in memory. – Lundin Apr 03 '14 at 12:54
  • Now is there a way to set the packing arrangement to have it contiguous? – Nathan Apr 03 '14 at 13:06
  • It's not standard C. You'll have to read your compiler documentation. For example, in MSVC2012 you can use a #pragma pack directive. – Bathsheba Apr 03 '14 at 13:07
  • OK thank you for your help. I will try to find out if GNU-GCC compiler has a similar setting. – Nathan Apr 03 '14 at 13:20
0
  • First of all you should never use bit fields in embedded systems, for multiple reasons. Most likely your problems come from the bit order being poorly specified for your compiler (which is likely Codewarrior?).

    I would strongly advise to use the following 100% portable syntax instead:

    #define PEAR    (*(volatile uint8_t*)0x000Au)
    #define NOACCE  0x80u
    #define PIPOE   0x20u
    #define NECLK   0x10u
    #define LSTRE   0x08u
    #define RDWE    0x04u
    
  • You shouldn't use the default primitive data types in C (such as unsigned int) when working with embedded systems. Use uint16_t etc from stdint.h instead.

  • It doesn't make any sense to make a union of one 8 bit member and one 16 bit member. This could be the cause of the problem.

  • In general avoid using structs/unions when mapping hardware registers, because the compiler may introduce padding anywhere inside the struct. Since the HCS12 is a good core which doesn't care about alignment, this won't be an issue in your specific case however.

EDIT

Your printf code looks fishy. printf() uses argument promotion to int. Look in the debugger memory map instead. What values does it say that your variables have?

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Maybe it was the way I stated it I am not using the HCS12 for running the code. The unions are represent/simulate the HCS12 processor internal registers. – Nathan Apr 03 '14 at 13:00
  • @Nathan So you are using a PC? In that case, I'm afraid you don't have a clue about what you are doing... HCS12 is a 16-bit big endian CPU. Your average PC is a 32/64 bit little endian CPU. Your code is 100% non-portable between HCS12 and a PC. – Lundin Apr 03 '14 at 13:02
  • I am aware of that. This code is part of my program to simulate the HCS12 on a PC. Sorry that may have been my fault for the confusion. – Nathan Apr 03 '14 at 13:09
  • @Nathan You need to take a step back from the code and read up on [endianess](http://en.wikipedia.org/wiki/Endianess), to begin with. – Lundin Apr 03 '14 at 13:15