CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

union struct problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bilko



Joined: 17 Oct 2003
Posts: 24
Location: Dorset, UK

View user's profile Send private message

union struct problem
PostPosted: Mon Aug 29, 2011 2:56 am     Reply with quote

I maybe being stupid but ..... the following code seems to compile to nonsense
Using PCD

Code:

typedef union {
   struct {
      //As written by software
      uint16      Addr;
      unsigned    byteCount   :10;
      unsigned    BSTALL      :1;
      unsigned    DTSEN      :1;
      unsigned    n28         :2;
      unsigned    DTS         :1;
      unsigned    UOWN      :1;
   } softBits;
   struct {
      //As written by software
      uint16      Addr;
      uint16      config;
   } soft;
   struct {
      //As written by hardware
      uint16      Addr;
      unsigned    byteCount   :10;
      unsigned    PID         :4;
      unsigned    DTS         :1;
      unsigned    UOWN      :1;
   } hardbits;
} usbBdType;

typedef struct {
   usbBdType   rx[2];
   usbBdType   tx[2];
} usbBdEpType;

#define   usbBDTaddr   0x2000
usbBdEpType   usbBDT[16];
#LOCATE usbBDT=usbBDTaddr


The following seems to compile correctly:
Quote:

.................... usbBDT[0].rx[0].soft.Addr=&Uep0RxBuf[0];
041CA: MOV #AF8,W4
041CC: MOV W4,2000


BUT does the following make any sense to anybody??
Quote:

.................... usbBDT[0].rx[0].softbits.byteCount=0x10;
041DA: MOV #FC00,W0
041DC: AND 2
041DE: MOV #10,W0
041E0: IOR 2
jeremiah



Joined: 20 Jul 2010
Posts: 1327

View user's profile Send private message

PostPosted: Mon Aug 29, 2011 6:51 am     Reply with quote

It depends on what PIC you are using (you didn't specify what PIC or what compiler rev you are using).

The 2nd and 3rd instruction you listed there do look kinda pointless, but depending on what the rest of the instructions you don't show do, it might be ok.

#FC00 looks to be a mask value for all of the data fields except for byteCount. The other instructions just put the value of #2 in the byteCount field.

The:
041DC: AND 2
041DE: MOV #10,W0

Look like they are just extra, but that's without knowing the PIC, the compiler revision, and the rest of your program. It could just be a generic way of handling data going into a bitfield in a struct, which is overkill for most scenarios but necessary for some other edge case. That's just speculation on my part, though.

The one that looks ok looks better because you are copying to a bit field that is already 16 bits, so it has a cleaner instruction methodology.
bilko



Joined: 17 Oct 2003
Posts: 24
Location: Dorset, UK

View user's profile Send private message

PostPosted: Mon Aug 29, 2011 9:04 am     Reply with quote

FWIW it's a PIC24FJ256GB110
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Aug 29, 2011 4:24 pm     Reply with quote

I don't know the PIC24 or it's hardware, but I've seen lot of assembler code for other processors and to me the code looks all right.

The code is incomplete, but address 2 is containing usbBDT[0].
The first two instructions use the value 0xFC00 as a filter to set the lower 10 bits to zero, i.e. the ByteCount part.
Then the instructions 3 and 4 are used to load the value 0x10 into ByteCount.

The code is cryptic, but this is about the best you can expect. Working with bitfields results in efficient RAM use but requires a lot more code to set and extract the data. Aligning the bitfields to 8-bit boundaries will result in more efficient code.
bilko



Joined: 17 Oct 2003
Posts: 24
Location: Dorset, UK

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 5:12 am     Reply with quote

usbBDT[0] is at address 0x2000
(see the #LOCATE in the code)
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 8:03 am     Reply with quote

Some of the above comments show a certain unawareness to PIC24 instruction set.

Actually the compiler is accessing data memory location 0x0002 (an SFR address!) instead of 0x2002. It's obviously a PCD bug, it can be still reproduced with most recent V4.124.

The problem arises, if the variable is located in the 0x2000 to 0x21FF range and specific operations, in this case mask operations for bitfields are performed. The compiler erroneously acesses the variable with near data space instructions, stripping upper address bits.

If you locate the variable at 0x2200, the problem disappears.

You should file a bug report to CCS support.
bilko



Joined: 17 Oct 2003
Posts: 24
Location: Dorset, UK

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 8:44 am     Reply with quote

Wilco, thank you.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group