2014-02-20 2 views
0

У меня возникла следующая проблема.big endian swap macro "uswap" приводит к непредвиденной ошибке

следующий номер макросоци-

#define uswap_32(x) \ 
((((x) & 0xff000000) >> 24) | \ 
(((x) & 0x00ff0000) >> 8) | \ 
(((x) & 0x0000ff00) << 8) | \ 
(((x) & 0x000000ff) << 24)) 

ПОЛУЧИТЬ как аргумент х = 0x49074808

Почему моя программа перерыв/сбрасывает здесь ??

Thx

EDIT:

Описание моего реального приложения:

У меня есть загрузчик, сидя на начало вспышки адрес 0x08000000U происходит до 0x08004000U. После загрузчика есть заголовок uImage (снято с uboot) во флэш-памяти с размером 0x40. В моем приложении я просто хочу проверить, есть ли правильный заголовок uImage, потому что у меня есть две версии bootloader. Можно обрабатывать изображения типа uImage, а другие нельзя. В последнем случае, после приложения bootloader вообще нет заголовка uImage, есть код приложения!

В приложении я просто хочу, чтобы проверить CRC заголовка:

#define UIMAGE_FLASH_ADDRESS  (0x08004000U) 
image_header_t *header; 
header = (image_header_t *) UIMAGE_FLASH_ADDRESS; 
if (image_check_hcrc(header)) 
    /* do something...*/ 




static int image_check_hcrc(const image_header_t *hdr) 
{ 
    uint32_t hcrc; 
    uint32_t len = image_get_header_size(); 
    image_header_t header; 

    /* Copy header so we can blank CRC field for re-calculation */ 
    memcpy(&header, (char *)hdr, image_get_header_size()); 
    header.ih_hcrc = 0;   // byte order independent 
    hcrc = crc32(0, (unsigned char *)&header, len); 

    return hcrc == image_get_hcrc(hdr); 
} 

Призыв к uswap_32() происходит в последней строке выше функции:

#define uswap_32(x) \ 
((((x) & 0xff000000) >> 24) | \ 
(((x) & 0x00ff0000) >> 8) | \ 
(((x) & 0x0000ff00) << 8) | \ 
(((x) & 0x000000ff) << 24)) 

# define cpu_to_be32(x)  uswap_32(x) 
# define be32_to_cpu(x)  uswap_32(x) 
#define uimage_to_cpu(x)  be32_to_cpu(x) 
#define cpu_to_uimage(x)  cpu_to_be32(x) 



#define image_get_hdr_l(f) \ 
    static inline uint32_t image_get_##f(const image_header_t *hdr) \ 
{ \ 
    return uimage_to_cpu(hdr->ih_##f); \ 
} 
image_get_hdr_l(magic)  /* image_get_magic */ 
image_get_hdr_l(hcrc)  /* image_get_hcrc */ 
image_get_hdr_l(time)  /* image_get_time */ 
image_get_hdr_l(size)  /* image_get_size */ 
image_get_hdr_l(load)  /* image_get_load */ 
image_get_hdr_l(ep)  /* image_get_ep */ 
image_get_hdr_l(dcrc)  /* image_get_dcrc */ 

#define image_get_hdr_b(f) \ 
static inline uint8_t image_get_##f(const image_header_t *hdr) \ 
{ \ 
    return hdr->ih_##f; \ 
} 
image_get_hdr_b(os)  /* image_get_os */ 
image_get_hdr_b(arch)  /* image_get_arch */ 
image_get_hdr_b(type)  /* image_get_type */ 
image_get_hdr_b(comp)  /* image_get_comp */ 
+4

Можете ли вы сказать * как * он «ломается/сбрасывается»? Каков ожидаемый результат? Каков фактический результат? И как вы используете этот макрос (фактический код)? –

+2

ваш макрос выглядит товар. как вы это называете – MOHAMED

+0

Я тестирую ваш макрос в http://www.compileonline.com/compile_c_online.php, и он работает без проблем: 'main() { unsigned int A = 0x45231512; printf ("% 02X \ n", uswap_32 (A)); } ' – MOHAMED

ответ

2

Это хорошая идея для назначения x локальной переменной внутри макроса. В противном случае, если выражение передается в качестве аргумента макросу, оно будет оцениваться 4 раза. Например, uswap (2 + 3) или, что еще хуже, uswap (some_func (x)).

Вторая проблема - вам нужно добавить явный модификатор типа UL для констант. Вот более безопасная версия макроса:

#define uswap_32(x) ({\ 
    uint32_t _x = (x);\ 
    (uint32_t)(\ 
     ((_x & 0xff000000UL) >> 24) | \ 
     ((_x & 0x00ff0000UL) >> 8) | \ 
     ((_x & 0x0000ff00UL) << 8) | \ 
     ((_x & 0x000000ffUL) << 24)); \ 
}) 
Смежные вопросы