This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
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

casting pointers

Hello!

I've bumped into the issue with casting...

main.c:
static ble_gap_addr_t addr0;
static uint16_t *p_host0;

int main(void) {
    p_host0 = (void*)&addr0.addr[0];

works fine, but...

beacon.c:
static ble_gap_addr_t addr1;
static uint16_t *p_host1;

void init_beacon(void) {
   p_host1 = (void*)&addr1.addr[0];

hungs in assignment when I call init_beacon() from main()

Where is rake?

Parents Reply Children
  • definitely it is:

    **Cortex-M0 Devices Generic User Guide

    Home > The Cortex-M0 Instruction Set > About the instruction descriptions > Address alignment

    3.3.4. Address alignment

    An aligned access is an operation where a word-aligned address is used for a word, or multiple word access, or where a halfword-aligned address is used for a halfword access. Byte accesses are always aligned. There is no support for unaligned accesses on the Cortex-M0 processor. Any attempt to perform an unaligned memory access operation results in a HardFault exception.**

  • I tried to avoid editing SDK, but the only plausible solution I see, is to switch places of struct. members and add alignment (not sure, either it is really required):

    ble_gap.h:
    
    /**@brief Bluetooth Low Energy address. */
    typedef struct
    {
      uint8_t addr[BLE_GAP_ADDR_LEN];       /**< 48-bit address, LSB format. */
      uint8_t addr_type;                    /**< See @ref BLE_GAP_ADDR_TYPES. */
    } ble_gap_addr_t __attribute__((aligned(16)));
    
  • I have tested in another way.

    #pragma anon_unions
    typedef struct {
        uint8_t addr_type;                    /**< See @ref BLE_GAP_ADDR_TYPES. */
        union {
            uint8_t addr[BLE_GAP_ADDR_LEN];   /**< 48-bit address, LSB format. */
            __packed struct {
                uint16_t host;
                uint32_t net;
            };
        };
    } my_gap_addr_t;
    
    
    static ble_gap_addr_t addr1 = { 0x00, { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 } };
    static ble_gap_addr_t *p_addr;
    static my_gap_addr_t  *p_mddr;
    
    #define show(P) \
        printf("(0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x)\r\n", \
            P->addr[0], P->addr[1], P->addr[2], P->addr[3], P->addr[4], P->addr[5])
    
  • ...

    void test_something(void)
    {
        p_addr = &addr1;
        p_mddr = (my_gap_addr_t*)&addr1;
    
        show(p_addr);
        show(p_mddr);
        printf("0x%04x\r\n", p_mddr->host);
        puts("---");
        
        addr1.addr[0] = 0xab;
        addr1.addr[1] = 0xcd;
        show(p_addr);
        show(p_mddr);
        printf("0x%04x\r\n", p_mddr->host);
        puts("---");
        
        const uint8_t buffer[] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54 };
        memcpy((void*)addr1.addr, (const void*)buffer, sizeof(buffer));
        show(p_addr);
        show(p_mddr);
        printf("0x%04x\r\n", p_mddr->host);
        puts("---");
    }
    
  • Awesome. although gcc doesn't want this pragma, it just works!

Related