Перейти к содержанию
    

Инициализация указателей

Здравствуйте.

Имеется следующий код:

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. В чём может быть подвох?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Фигня какая-то, может дело в каких-то ключах компиляции под arm-none-eabi-gcc, если static так влияет на поведение. Сам постоянно пользуюсь такими указателями.

Правда, я бы вам рекомендовал вот так делать:

typedef void( *const function)(void);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, тоже сначало грешили на опции, но кажется это не они.

Вот строка компиляции:

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

Изменено пользователем Tolas

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

для указателя на функцию можно попробовать так:

void a(void)
{
    printf("a");
}

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

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

    return 0;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Данный код, скомпилированный под архитектуру i386, не печатает восклицательный знак, а под архитектуру Cortex-M3 "печатает".

Если сделать указатель на функцию или саму функцию статичными, то всё становится нормально. Под i386 компиляция происходит чистым gcc, под Cortex - arm-none-eabi-gcc. В чём может быть подвох?

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сократив 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 и не указывает на функцию.

 

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

Со всеми глобальными переменными.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну и кстати, это может быть обычная с-шная функция, без всяких наворотов. У меня например такая

А у меня такая:

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();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А у меня такая:

 

я чет побоялся использовать стандартную библиотеку на этом этапе :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...