This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C51: Word Alignment in Keil C51

How I can turn-on word alignment in Keil C51?
I have such definition of USB-descriptors for Cypress EZ-USB chip CY7C68013:

const DEVICEDSCR code TestSyncSlave_DeviceDescriptor =
{   // Device descriptor
    sizeof(DEVICEDSCR),             // 0x00 Length of this descriptor
    DEVICE_DSCR,                    // 0x01 Descriptor type
    USBSPEC,                        // 0x02 USB Specification Release Number
    VENDOR_SPECIFIC,                // 0x04 Class Code
    0x00,                           // 0x05 Sub Class Code
    0x00,                           // 0x06 Protocol
    EP0_MAX_PACKET_SIZE,            // 0x07 Maximum Endpoint 0 Packet Size
    VID_EPOS,                       // 0x08 Vendor ID
    PID_ANALYSER,                   // 0x0a Product ID
    DID_ANALYSER,                   // 0x0c DeviceBCD Device Release Number
    STRING_INDEX_MANUFACTURER,      // 0x0e Index of string descriptor describing manufacturer
    STRING_INDEX_PRODUCT,           // 0x0f Index of string descriptor describing product
    0x00,                           // 0x10 Index of string descriptor describing serial number
    0x01                            // 0x11 Number of configurations
};

///////////////////////////////////////////////////////////////////////////////
const DEVICEQUALDSCR code TestSyncSlave_DeviceQualifierDescriptor =
{   // Device Qualifier descriptor
    sizeof(DEVICEQUALDSCR),         // 0x00 Length of this descriptor
    DEVQUAL_DSCR,                   // 0x01 Descriptor type
    USBSPEC,                        // 0x02 USB Specification Release Number
    VENDOR_SPECIFIC,                // 0x04 Class Code
    0x00,                           // 0x05 Sub Class Code
    0x00,                           // 0x06 Protocol
    EP0_MAX_PACKET_SIZE,            // 0x07 Maximum Endpoint 0 Packet Size
    0x01,                           // 0x08 Number of configurations
    0x00                            // 0x09 Reserve
};

///////////////////////////////////////////////////////////////////////////////
const DEVICECONFG code TestSyncSlave_HS_Config  =
{   // Configuration when connected to a High Speed host
    {   // Configuration Descriptor
        sizeof(CONFIGDSCR),     // 0x00 bLength: Length of this descriptor
        CONFIG_DSCR,            // 0x01 Type (CONFIGURATION_DESC or CONFIGURATION_DESC)
        LSB(sizeof(DEVICECONFG)),   // 0x02 wTotalLength: Total length for this configuration
        MSB(sizeof(DEVICECONFG)),   // 0x02 wTotalLength: Total length for this configuration
        NUM_INTERFACES,         // 0x04 bNumInterfaces: Number of Interfaces
        0x01,                   // 0x05 bConfigurationValue: Number of this configuration
        0x00,                   // 0x06 iConfiguration: Index of string descriptor describing this configuration
        CONFIG_ATTRIBUTES,      // 0x07 bmAttributes: 7:AlwaysSet|6:SelfPowered|5:RemoteWakeup
        150                     // 0x08 bMaxPower: Max USB power (in 2mA units)
    },

    {   // Interface Descriptor:
        sizeof(INTRFCDSCR),     // 0x00 Size of this descriptor
        INTRFC_DSCR,            // 0x01 Type
        0x00,                   // 0x02 Number of this interface
        0x00,                   // 0x03 Alternate interface
        ENDPOINT_COUNT, // 0x04 Number of endpoints in this interface (without EP0)
        VENDOR_SPECIFIC,        // 0x05 Class Code
        0x00,                   // 0x06 Sub Class Code
        0x00,                   // 0x07 Device Protocol
        0x00,                   // 0x08 Index of string descriptor describing this interface
    },

    {
        // Endpoint Descriptors:      Type     Dir     MaxPkt  UsbEp   Poll
        {MAKE_ENDPOINT_DESCRIPTOR( EP_BULK, EP_IN,  512, 0x86,   0   )},
        {MAKE_ENDPOINT_DESCRIPTOR( EP_BULK, EP_OUT, 64,  0x01,   0   )},
        {MAKE_ENDPOINT_DESCRIPTOR( EP_BULK, EP_IN,  64,  0x81,   0   )}

    }

};
//In such definition last structure is missalignment, so I must align it...
///////////////////////////////////////////////////////////////////////////////
const DEVICECONFG code TestSyncSlave_FS_Config =
{   // Configuration when connected to a Full Speed host
    {   // Configuration descriptor
        sizeof(CONFIGDSCR),     // 0x00 Length of this descriptor
        CONFIG_DSCR,            // 0x01 Type (CONFIGURATION_DESC or OTHER_SPEED_CONFIGURATION_DESC)
        LSB(sizeof(DEVICECONFG)),   // 0x02 wTotalLength: Total length for this configuration
        MSB(sizeof(DEVICECONFG)),   // 0x02 wTotalLength: Total length for this configuration
        NUM_INTERFACES,         // 0x04 Number of Interfaces
        0x01,                   // 0x05 Number of this configuration
        0x00,                   // 0x06 Index of string descriptor describing this configuration
        CONFIG_ATTRIBUTES,      // 0x07 bmAttributes: 7:AlwaysSet|6:SelfPowered|5:RemoteWakeup
        150                     // 0x08 Max USB power (in 2mA units)
    },

    {   // Interface Descriptor:
        sizeof(INTRFCDSCR),     // 0x00 Size of this descriptor
        INTRFC_DSCR,            // 0x01 Type
        0x00,                   // 0x02 Number of this interface
        0x00,                   // 0x03 Alternate interface
        ENDPOINT_COUNT,         // 0x04 Number of endpoints in this interface (without EP0)
        VENDOR_SPECIFIC,        // 0x05 Class Code
        0x00,                   // 0x06 Sub Class Code
        0x00,                   // 0x07 Device Protocol
        0x00,                   // 0x08 Index of string descriptor describing this interface
    },
    {
        // Endpoint Descriptors:      Type     Dir     MaxPkt  UsbEp   Poll
        {MAKE_ENDPOINT_DESCRIPTOR( EP_BULK, EP_IN,  64,  0x86,   0   )},
        {MAKE_ENDPOINT_DESCRIPTOR( EP_BULK, EP_OUT, 64,  0x01,   0   )},
        {MAKE_ENDPOINT_DESCRIPTOR( EP_BULK, EP_IN,  64,  0x81,   0   )}
        }


};

EZ-USB needs that each USB-descriptor was word alignment.
How can I do this in Keil C51(any directive such as #pragma pack)?

Parents Reply Children
  • No, there aren't.

    Note that "word" and "long" have no generic size - it depends upon the implementation!

    Again, In an 8-bit processor, the word size is 8 bits.

    There is no reason on an 8-bit processor to have anything other than byte alignment - so C51 has no directives to enforce it!

    The only reason to add padding would be specific to the application - so the application (ie, you) must do it!

  • I'll remind of the link I gave earlier:
    http://www.keil.com/support/man/docs/c51/c51_ap_linkerloc.htm

    Basically, you put each descriptor variable definition into its own source file. This way the compiler puts each variable into its own section. Then you have the freedom to locate each section as you like, e.g. placing each section at a specific address. Specifying start address for each section manually isn't perfect, but at least you'll get a linker warning if sections clash due to changed variable size...

  • I think doing it in the 'C' source code with some suitable preprocessor checking would be safer...?

    Maybe this could help: http://www.keil.com/support/man/docs/c51/c51_offsetof.htm

  • Yes this more safer, than manualy setup code segments.
    Especially as after every change of code segment need check, that no overlap.

    In cypress examples, i find interest way to align on word, but only in asm:

    ;;-----------------------------------------------------------------------------
    ;; Global Variables
    ;;-----------------------------------------------------------------------------
    ;      rseg DSCR     ;; locate the descriptor table in on-part memory.
    
    CSEG   AT 100H
    
    
    DeviceDscr:
          db   DSCR_DEVICE_LEN      ;; Descriptor length
          db   DSCR_DEVICE   ;; Decriptor type
          dw   0002H      ;; Specification Version (BCD)
          db   00H        ;; Device class
          db   00H         ;; Device sub-class
          db   00H         ;; Device sub-sub-class
          db   64         ;; Maximum packet size
          dw   0B404H      ;; Vendor ID
          dw   0310H      ;; Product ID (Sample Device)
          dw   0000H      ;; Product version ID
          db   1         ;; Manufacturer string index
          db   2         ;; Product string index
          db   0         ;; Serial number string index
          db   1         ;; Number of configurations
    
     org (($ / 2) +1) * 2 
    
    DeviceQualDscr:
          db   DSCR_DEVQUAL_LEN   ;; Descriptor length
          db   DSCR_DEVQUAL   ;; Decriptor type
          dw   0002H      ;; Specification Version (BCD)
          db   00H        ;; Device class
          db   00H         ;; Device sub-class
          db   00H         ;; Device sub-sub-class
          db   64         ;; Maximum packet size
          db   1         ;; Number of configurations
          db   0         ;; Reserved
    
    

    .

  • One more time, In an 8-bit processor, the word size is 8 bits.

    You need to stop using "word" as if it has some definite, universal size - it does not!

    If you mean "16-bit alignment" or "even-address" alignment, you need to say that explicitly - otherwise you are going to cause confusion and, probably, end up in trouble.

    Have you looked into using sizeof and/or offsetof to do it in 'C'...?

  • I not see the way, how offsetof construction can help me...

  • In a similar vein to your assembler, how about something like:

    #if (offsetof(x)/2)*2 != offsetof(x)
    // Offset is odd - packing needed
    #endif
    

  • Than how put to even-aligned address first descriptor in chain? :)