Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Инициализация указателей
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Tolas
Здравствуйте.
Имеется следующий код:
Код
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
Фигня какая-то, может дело в каких-то ключах компиляции под arm-none-eabi-gcc, если static так влияет на поведение. Сам постоянно пользуюсь такими указателями.
Правда, я бы вам рекомендовал вот так делать:
typedef void( *const function)(void);
Tolas
Да, тоже сначало грешили на опции, но кажется это не они.
Вот строка компиляции:
Код
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -T "./gcc.ld" -nostartfiles -nodefaultlibs -o main main.c


Может скрипт линковки? (attach)
CODE

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
psL
для указателя на функцию можно попробовать так:
Код
void a(void)
{
    printf("a");
}

typedef void (*function)(void);
function ptr_funca = a;

int main(void)
{
    if (a != ptr_funca)
    {
        printf("!");
    }

    return 0;
}
Непомнящий Евгений
Цитата(Tolas @ Dec 11 2014, 12:10) *
Данный код, скомпилированный под архитектуру i386, не печатает восклицательный знак, а под архитектуру Cortex-M3 "печатает".
Если сделать указатель на функцию или саму функцию статичными, то всё становится нормально. Под i386 компиляция происходит чистым gcc, под Cortex - arm-none-eabi-gcc. В чём может быть подвох?

Возможно, в стартовом коде. Инициализацией глобальных переменных занимается именно он. Если же указатель сделать статическим, то вероятно компилятор его просто соптимизирует.

Такая проблема только с указателями, или и с другими глобальными переменными?
scifi
Вообще-то для начала неплохо было бы посмотреть на адреса, хранящиеся в этих указателях.
Tolas
Сократив ld-скрипт до вида
CODE

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 выглядит

CODE

void __attribute__ ((section(".after_vectors"),naked))
Reset_Handler(void)
{
asm volatile
(
" b main \n"
:
:
:
);
}


Цитата
Вообще-то для начала неплохо было бы посмотреть на адреса, хранящиеся в этих указателях.

Единственное что можно сказать что этот указатель не NULL и не указывает на функцию.

Цитата
Такая проблема только с указателями, или и с другими глобальными переменными?

Со всеми глобальными переменными.
Непомнящий Евгений
Цитата(Tolas @ Dec 15 2014, 17:11) *
CODE

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
Цитата(Непомнящий Евгений @ Dec 15 2014, 17:55) *
Ну и кстати, это может быть обычная с-шная функция, без всяких наворотов. У меня например такая

А у меня такая:
Код
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();
}
Непомнящий Евгений
Цитата(scifi @ Dec 15 2014, 19:14) *
А у меня такая:


я чет побоялся использовать стандартную библиотеку на этом этапе sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2018 Invision Power Services, Inc.