Roberto_Tolas 0 11 декабря, 2014 Опубликовано 11 декабря, 2014 · Жалоба Здравствуйте. Имеется следующий код: void a(void) { printf("a"); } typedef void function(void); function *ptr_funca = a; int main(void) { if (a != ptr_funca) { printf("!"); } } Данный код, скомпилированный под архитектуру i386, не печатает восклицательный знак, а под архитектуру Cortex-M3 "печатает". Если сделать указатель на функцию или саму функцию статичными, то всё становится нормально. Под i386 компиляция происходит чистым gcc, под Cortex - arm-none-eabi-gcc. В чём может быть подвох? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aaron 1 11 декабря, 2014 Опубликовано 11 декабря, 2014 · Жалоба Фигня какая-то, может дело в каких-то ключах компиляции под arm-none-eabi-gcc, если static так влияет на поведение. Сам постоянно пользуюсь такими указателями. Правда, я бы вам рекомендовал вот так делать: typedef void( *const function)(void); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Roberto_Tolas 0 12 декабря, 2014 Опубликовано 12 декабря, 2014 (изменено) · Жалоба Да, тоже сначало грешили на опции, но кажется это не они. Вот строка компиляции: arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T "./gcc.ld" -nostartfiles -nodefaultlibs -o main main.c Может скрипт линковки? (attach) MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K } __stack = ORIGIN(RAM) + LENGTH(RAM); _estack = __stack; /* STM specific definition */ __Main_Stack_Size = 1024 ; PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ; __Main_Stack_Limit = __stack - __Main_Stack_Size ; PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ; _Minimum_Stack_Size = 256 ; PROVIDE ( _Heap_Begin = _end_noinit ) ; PROVIDE ( _Heap_Limit = __stack - __Main_Stack_Size ) ; ENTRY(Reset_Handler) /* Sections Definitions */ SECTIONS { .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Interrupt vectors */ KEEP(*(.cfmconfig)) /* Freescale configuration words */ *(.after_vectors .after_vectors.*) /* Startup code and ISR */ . = ALIGN(4); } >FLASH .inits : { . = ALIGN(4); KEEP(*(.init)) KEEP(*(.fini)) . = ALIGN(4); PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*)) KEEP(*(.preinit_array_platform .preinit_array_platform.*)) KEEP(*(.preinit_array .preinit_array.*)) PROVIDE_HIDDEN (__preinit_array_end = .); . = ALIGN(4); PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); . = ALIGN(4); PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) KEEP(*(.fini_array)) PROVIDE_HIDDEN (__fini_array_end = .); . = ALIGN(4); } >FLASH .flashtext : { . = ALIGN(4); *(.flashtext .flashtext.*) /* Startup code */ . = ALIGN(4); } >FLASH .text : { . = ALIGN(4); *(.text .text.*) /* all remaining code */ *(.rodata .rodata.*) /* read-only data (constants) */ *(vtable) /* C++ virtual tables */ KEEP(*(.eh_frame*)) *(.glue_7) *(.glue_7t) } >FLASH .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH __exidx_start = .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH __exidx_end = .; . = ALIGN(4); _etext = .; __etext = .; _sidata = _etext; .data : AT ( _sidata ) { . = ALIGN(4); _sdata = . ; /* STM specific definition */ __data_start__ = . ; *(.data_begin .data_begin.*) *(.data .data.*) *(.data_end .data_end.*) . = ALIGN(4); _edata = . ; /* STM specific definition */ __data_end__ = . ; } >RAM .bss (NOLOAD) : { . = ALIGN(4); __bss_start__ = .; /* standard newlib definition */ _sbss = .; /* STM specific definition */ *(.bss_begin .bss_begin.*) *(.bss .bss.*) *(COMMON) *(.bss_end .bss_end.*) . = ALIGN(4); __bss_end__ = .; /* standard newlib definition */ _ebss = . ; /* STM specific definition */ } >RAM .noinit (NOLOAD) : { . = ALIGN(4); _noinit = .; *(.noinit .noinit.*) . = ALIGN(4) ; _end_noinit = .; } > RAM /* Mandatory to be word aligned, _sbrk assumes this */ PROVIDE ( end = _end_noinit ); /* was _ebss */ PROVIDE ( _end = _end_noinit ); PROVIDE ( __end = _end_noinit ); PROVIDE ( __end__ = _end_noinit ); ._check_stack : { . = ALIGN(4); . = . + _Minimum_Stack_Size ; . = ALIGN(4); } >RAM /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } Движок форума не дает загрузить расширение ld поменял на txt gcc.txt Изменено 12 декабря, 2014 пользователем Tolas Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 12 декабря, 2014 Опубликовано 12 декабря, 2014 · Жалоба для указателя на функцию можно попробовать так: void a(void) { printf("a"); } typedef void (*function)(void); function ptr_funca = a; int main(void) { if (a != ptr_funca) { printf("!"); } return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 15 декабря, 2014 Опубликовано 15 декабря, 2014 · Жалоба Данный код, скомпилированный под архитектуру i386, не печатает восклицательный знак, а под архитектуру Cortex-M3 "печатает". Если сделать указатель на функцию или саму функцию статичными, то всё становится нормально. Под i386 компиляция происходит чистым gcc, под Cortex - arm-none-eabi-gcc. В чём может быть подвох? Возможно, в стартовом коде. Инициализацией глобальных переменных занимается именно он. Если же указатель сделать статическим, то вероятно компилятор его просто соптимизирует. Такая проблема только с указателями, или и с другими глобальными переменными? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 15 декабря, 2014 Опубликовано 15 декабря, 2014 · Жалоба Вообще-то для начала неплохо было бы посмотреть на адреса, хранящиеся в этих указателях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Roberto_Tolas 0 15 декабря, 2014 Опубликовано 15 декабря, 2014 · Жалоба Сократив ld-скрипт до вида MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K } _estack = ORIGIN(RAM) + LENGTH(RAM); ENTRY(Reset_Handler) SECTIONS { .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Interrupt vectors */ KEEP(*(.cfmconfig)) /* Freescale configuration words */ *(.after_vectors .after_vectors.*) /* Startup code and ISR */ . = ALIGN(4); } >FLASH .text : { *(.text*) } > FLASH .bss : { *(.bss*) } > RAM } Указатели стали работать верно. Reset_Handler выглядит void __attribute__ ((section(".after_vectors"),naked)) Reset_Handler(void) { asm volatile ( " b main \n" : : : ); } Вообще-то для начала неплохо было бы посмотреть на адреса, хранящиеся в этих указателях. Единственное что можно сказать что этот указатель не NULL и не указывает на функцию. Такая проблема только с указателями, или и с другими глобальными переменными? Со всеми глобальными переменными. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 15 декабря, 2014 Опубликовано 15 декабря, 2014 · Жалоба void __attribute__ ((section(".after_vectors"),naked)) Reset_Handler(void) { asm volatile ( " b main \n" : : : ); } У вас resetHandler ничего не делает, кроме вызова main. А он должен заполнить нулями секцию bss и проинициализировать секцию data. На данный момент у вас там просто мусор... Ну и кстати, это может быть обычная с-шная функция, без всяких наворотов. У меня например такая void Reset_Handler(void) { SystemInit(); uint32_t *src, *dst; for (src = &__data_load, dst = &__data_start; dst != &__data_end; ++src, ++dst) *dst = *src; for (dst = &__bss_start; dst != &__bss_end; ++dst) *dst = 0; __libc_init_array(); main(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 15 декабря, 2014 Опубликовано 15 декабря, 2014 · Жалоба Ну и кстати, это может быть обычная с-шная функция, без всяких наворотов. У меня например такая А у меня такая: void __attribute((used)) Reset_Handler(void) { /* copy-init variables */ memcpy(&__data_start__, &__etext, &__data_end__ - &__data_start__); /* zero-init variables */ memset(&__bss_start__, 0, &__bss_end__ - &__bss_start__); (void)main(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 17 декабря, 2014 Опубликовано 17 декабря, 2014 · Жалоба А у меня такая: я чет побоялся использовать стандартную библиотеку на этом этапе :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться