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

vovo

Участник
  • Постов

    9
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные vovo


  1. Хорошая ссылка, гораздо гораздее чем штатный pdf, спасибо.

    А ларчик открылся весьма просто - надо было всего лишь явно указать startup модуль в первом регионе)))

    Спасибо всем кто участвовал))), пока вроде всё намазывается, если что, ещё вас помучаю.

  2. Извиняюсь. Пробел перед двоеточием, после ".text0" поставьте.

    Про пробел я и сам уже понял, но это не спасает

    P.S. И постарайтесь избегать избыточного цитирования, оно является нарушением Правил форума.

    С таким движком форума впервые общаюсь.

     

    Не нужно совершенно разные вещи (bootloader и приложение) запихивать в один проект

    загрузчик это не проект, он прошит в ROM чипа, при наличие программы (по оценке сектора 0 и тела программы) он её запускает, но для этого а адресе 0x00000000 должен быть адрес вершины стека, а в адресе 0x00000004 адрес перехода на начало программы. Вот их то в таком случае ликер и не помещает образ. Если область флеша одна, линкер правильно размещает начальные адреса, размещает данные с адреса 0х1000 по 0х2000, но заполняет нулями и главное включает в образ, что при программировании приводит к уничтожению этих данных. С ARM компилятором всё великолепно получается, но требуется переход на GCC.

     

  3. Но вы так и не сказали, зачем вам это нужно.

     

    Зачем вы дважды указываете адрес - при задании региона и при объявлении выходной секции?

    Замените

        .text0 0x0:
        {
            ......
        } > FLASH1

    на

        .text0:
        {
            ......
        } > FLASH1

    и с остальными секциями аналогично.

    Попробовал, в строке где скобка открывающая, линкер выдаёт ошибку синтаксиса.

    c:/program files (x86)/gnu tools arm embedded/5.4 2016q3/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld.exe:./SRC/gcc.ld:55: syntax error

    Мне не совсем понятен настойчивый вопрос про цель всего этого, но отвечу: в нулевом сегменте лежит код, на который смотрит bootloader чипа, его трогать нельзя, в первом сегменте, лежат данные, изменяемые программой по внешним воздействиям, в последующих сегментах остальной код программы, причём желательно его также разместить по необходимым адресам.

  4. Да, по второму вопросу протупил, виноват, исправлюсь. Хотя..., а если это библиотека, я не знаю имён модулей, но хочу разместить её в определённом фрагменте памяти?

    А вот по первому

    /* Linker script to configure memory regions. 
    * Need modifying for a specific board. 
    *   FLASH.ORIGIN: starting address of flash
    *   FLASH.LENGTH: length of flash
    *   RAM.ORIGIN: starting address of RAM bank 0
    *   RAM.LENGTH: length of RAM bank 0
    */
    MEMORY
    {
     FLASH1 (rx) : ORIGIN = 0x0, LENGTH = 0x1000
    
     FLASH2 ® : ORIGIN = 0x1000, LENGTH = 0x1000
     FLASH3 (rx) : ORIGIN = 0x2000, LENGTH = 0x80000 - 0x2000
    
     RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 8K */
     RAM2 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 8K */
    }
    
    /* Linker script to place sections and symbol values. Should be used together
    * with other linker script that defines memory regions FLASH and RAM.
    * It references following symbols, which must be defined in code:
    *   Reset_Handler : Entry of reset handler
    * 
    * It defines following symbols, which code can use without definition:
    *   __exidx_start
    *   __exidx_end
    *   __copy_table_start__
    *   __copy_table_end__
    *   __zero_table_start__
    *   __zero_table_end__
    *   __etext
    *   __data_start__
    *   __preinit_array_start
    *   __preinit_array_end
    *   __init_array_start
    *   __init_array_end
    *   __fini_array_start
    *   __fini_array_end
    *   __data_end__
    *   __bss_start__
    *   __bss_end__
    *   __end__
    *   end
    *   __HeapLimit
    *   __StackLimit
    *   __StackTop
    *   __stack
    */
    ENTRY(Reset_Handler)
    
    SECTIONS
    {
    
    .text0 0x0:
    {
    	KEEP(*(.isr_vector))
    	KEEP(*(.Reset_Handler_s))
    	KEEP(*(.init))
    	KEEP(*(.fini))
    } > FLASH1
    .dfdata 0x1000:
    {
    	/*. = 0x1000;*/
           *(.ARM.__AT_0x00001000)
    } > FLASH2
    .text 0x2000 :
    {
        /*. = 0x2000;*/
    	*(.text*)
    
    	/* .ctors */
    	*crtbegin.o(.ctors)
    	*crtbegin?.o(.ctors)
    	*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    	*(SORT(.ctors.*))
    	*(.ctors)
    
    	/* .dtors */
    		*crtbegin.o(.dtors)
    		*crtbegin?.o(.dtors)
    		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    		*(SORT(.dtors.*))
    		*(.dtors)
    
    	*(.rodata*)
    
    	KEEP(*(.eh_frame*))
    } > FLASH3
    
        __exab_start = .;
    .ARM.extab : 
    {
    	*(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH3
    __exab_end = .;
    
    __exidx_start = .;
    .ARM.exidx :
    {
    	*(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH3
    __exidx_end = .;
    
    /* To copy multiple ROM to RAM sections,
     * uncomment .copy.table section and,
     * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
    /*
    .copy.table :
    {
    	. = ALIGN(4);
    	__copy_table_start__ = .;
    	LONG (__etext)
    	LONG (__data_start__)
    	LONG (__data_end__ - __data_start__)
    	LONG (__etext2)
    	LONG (__data2_start__)
    	LONG (__data2_end__ - __data2_start__)
    	__copy_table_end__ = .;
    } > FLASH3
    */
    
    /* To clear multiple BSS sections,
     * uncomment .zero.table section and,
     * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
    /*
    .zero.table :
    {
    	. = ALIGN(4);
    	__zero_table_start__ = .;
    	LONG (__bss_start__)
    	LONG (__bss_end__ - __bss_start__)
    	LONG (__bss2_start__)
    	LONG (__bss2_end__ - __bss2_start__)
    	__zero_table_end__ = .;
    } > FLASH3
    */
    
    __etext = .;
    
    .data : AT (__etext)
    {
    	__data_start__ = .;
    	*(vtable)
    	*(.data*)
    
    	. = ALIGN(4);
    	/* preinit data */
    	PROVIDE_HIDDEN (__preinit_array_start = .);
    	KEEP(*(.preinit_array))
    	PROVIDE_HIDDEN (__preinit_array_end = .);
    
    	. = ALIGN(4);
    	/* init data */
    	PROVIDE_HIDDEN (__init_array_start = .);
    	KEEP(*(SORT(.init_array.*)))
    	KEEP(*(.init_array))
    	PROVIDE_HIDDEN (__init_array_end = .);
    
    
    	. = ALIGN(4);
    	/* finit data */
    	PROVIDE_HIDDEN (__fini_array_start = .);
    	KEEP(*(SORT(.fini_array.*)))
    	KEEP(*(.fini_array))
    	PROVIDE_HIDDEN (__fini_array_end = .);
    
    	KEEP(*(.jcr*))
    	. = ALIGN(4);
    	/* All data end */
    	__data_end__ = .;
    
    } > RAM
    
       .bss_RAM2 : ALIGN(4)
       {
          PROVIDE(__start_bss_RAM2 = .) ;
          *(LWIP_ram_heap*)
          *(.bss.$RamAHB32*)
          . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
          PROVIDE(__end_bss_RAM2 = .) ;
       } > RAM2 
    .bss :
    {
    	. = ALIGN(4);
    	__bss_start__ = .;
    	*(.bss*)
    	*(COMMON)
    	. = ALIGN(4);
    	__bss_end__ = .;
    } > RAM 
    
    .heap (COPY):
    {
    	__end__ = .;
    	PROVIDE(end = .);
    	*(.heap*)
    	__HeapLimit = .;
    } > RAM2
    
    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (COPY):
    {
    	*(.stack*)
    } > RAM2
    
    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
    PROVIDE(__stack = __StackTop);
    
    /* Check if data + heap + stack exceeds RAM limit */
    /*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")*/
    }
    

    Вот так мне нужно, но не работает

    А вот так работает

    /* Linker script to configure memory regions. 
    * Need modifying for a specific board. 
    *   FLASH.ORIGIN: starting address of flash
    *   FLASH.LENGTH: length of flash
    *   RAM.ORIGIN: starting address of RAM bank 0
    *   RAM.LENGTH: length of RAM bank 0
    */
    MEMORY
    {
     FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 128K */
     RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 8K */
     RAM2 (rwx) : ORIGIN = 0x200c7000, LENGTH = 0x8000 /* 8K */
    }
    
    /* Linker script to place sections and symbol values. Should be used together
    * with other linker script that defines memory regions FLASH and RAM.
    * It references following symbols, which must be defined in code:
    *   Reset_Handler : Entry of reset handler
    * 
    * It defines following symbols, which code can use without definition:
    *   __exidx_start
    *   __exidx_end
    *   __copy_table_start__
    *   __copy_table_end__
    *   __zero_table_start__
    *   __zero_table_end__
    *   __etext
    *   __data_start__
    *   __preinit_array_start
    *   __preinit_array_end
    *   __init_array_start
    *   __init_array_end
    *   __fini_array_start
    *   __fini_array_end
    *   __data_end__
    *   __bss_start__
    *   __bss_end__
    *   __end__
    *   end
    *   __HeapLimit
    *   __StackLimit
    *   __StackTop
    *   __stack
    */
    ENTRY(Reset_Handler)
    
    SECTIONS
    {
    .text :
    {
    	KEEP(*(.isr_vector))
    	*(.text*)
    
    	KEEP(*(.init))
    	KEEP(*(.fini))
    
    	/* .ctors */
    	*crtbegin.o(.ctors)
    	*crtbegin?.o(.ctors)
    	*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    	*(SORT(.ctors.*))
    	*(.ctors)
    
    	/* .dtors */
    		*crtbegin.o(.dtors)
    		*crtbegin?.o(.dtors)
    		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    		*(SORT(.dtors.*))
    		*(.dtors)
    
    	*(.rodata*)
    
    	KEEP(*(.eh_frame*))
    } > FLASH
    
    .ARM.extab : 
    {
    	*(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH
    
    __exidx_start = .;
    .ARM.exidx :
    {
    	*(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;
    
    /* To copy multiple ROM to RAM sections,
     * uncomment .copy.table section and,
     * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
    .copy.table :
    {
    	. = ALIGN(4);
    	__copy_table_start__ = .;
    	LONG (__etext)
    	LONG (__data_start__)
    	LONG (__data_end__ - __data_start__)
    	LONG (__etext2)
    	LONG (__data2_start__)
    	LONG (__data2_end__ - __data2_start__)
    	__copy_table_end__ = .;
    } > FLASH
    
    /* To clear multiple BSS sections,
     * uncomment .zero.table section and,
     * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
    .zero.table :
    {
    	. = ALIGN(4);
    	__zero_table_start__ = .;
    	LONG (__bss_start__)
    	LONG (__bss_end__ - __bss_start__)
    	LONG (__bss2_start__)
    	LONG (__bss2_end__ - __bss2_start__)
    	__zero_table_end__ = .;
    } > FLASH
    
    __etext = .;
    
    .data : AT (__etext)
    {
    	__data_start__ = .;
    	*(LWIP_ram_heap)
    	__data_end__ = .;
    
    } > RAM
    
    __etext2 = __etext + SIZEOF(.data);
    .data2 : AT (__etext2)
    {
    	__data2_start__ = .;
    		*(vtable)
    	*(.data*)
    
    	. = ALIGN(4);
    	/* preinit data */
    	PROVIDE_HIDDEN (__preinit_array_start = .);
    	KEEP(*(.preinit_array))
    	PROVIDE_HIDDEN (__preinit_array_end = .);
    
    	. = ALIGN(4);
    	/* init data */
    	PROVIDE_HIDDEN (__init_array_start = .);
    	KEEP(*(SORT(.init_array.*)))
    	KEEP(*(.init_array))
    	PROVIDE_HIDDEN (__init_array_end = .);
    
    
    	. = ALIGN(4);
    	/* finit data */
    	PROVIDE_HIDDEN (__fini_array_start = .);
    	KEEP(*(SORT(.fini_array.*)))
    	KEEP(*(.fini_array))
    	PROVIDE_HIDDEN (__fini_array_end = .);
    
    	KEEP(*(.jcr*))
    	. = ALIGN(4);
    	/* All data end */
    	__data2_end__ = .;
    
    } > RAM2
    
    .bss :
    {
    	. = ALIGN(4);
    	__bss_start__ = .;
    	*(.bss*)
    	. = ALIGN(4);
    	__bss_end__ = .;
    } > RAM
    
    .bss2 :
    {
    	. = ALIGN(4);
    	__bss2_start__ = .;
    	*(COMMON)
    	. = ALIGN(4);
    	__bss2_end__ = .;
    } > RAM2
    
    .heap (COPY):
    {
    	__end__ = .;
    	PROVIDE(end = .);
    	*(.heap*)
    	__HeapLimit = .;
    } > RAM2
    
    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (COPY):
    {
    	*(.stack*)
    } > RAM2
    
    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
    PROVIDE(__stack = __StackTop);
    
    /* Check if data + heap + stack exceeds RAM limit */
    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
    }
    

  5. Ещё раз благодарю за подсказки, с multi RAM разбрался. А вот как быть с multi ROM? Только когда секция FLASH едина, только тогда правильно выставляестя топ стека и стартовый переход. А вот стоит мне порезать FLASH на куски, то секция векторов прерываний и стартовый код ложатся таки куда надо, а вот топ стека адрес перехода на стартовый код нулевые выходят. И параллельно вопрос- а что в GCC нет возможности одной директивой все функции одного файла исходника отправить в свою секцию, только каждой функции __attribute__ прикручивать?

  6. Линкер файл я даже не цеплял. Думал, по аналогии с MDK, что по умолчанию что то должно быть. Стартап взят отсюда C:\Program Files (x86)\GNU Tools ARM Embedded\5.4 2016q3\share\gcc-arm-none-eabi\samples\startup, тул скачан с ARMа. Я посмотрел *.ld файл, предлагаемый в тулчейне, там тоже нет этих символов, кроме __bss_start__, этот совпадает. Ok, спасибо за подсказки, пошёл изучать скрипты линкера.

  7. Доброго времени дня!

    Никак не могу найти решение проблемы.

     

    linking...

    ./gnu/startup_armcm3.o: In function `Reset_Handler':

    E:\ARM_F/SRC/startup_ARMCM3.S:172: undefined reference to `__copy_table_start__'

    E:\ARM_F/SRC/startup_ARMCM3.S:173: undefined reference to `__copy_table_end__'

    E:\ARM_F/SRC/startup_ARMCM3.S:204: undefined reference to `__data_start__'

    E:\ARM_F/SRC/startup_ARMCM3.S:205: undefined reference to `__data_end__'

    E:\ARM_F/SRC/startup_ARMCM3.S:233: undefined reference to `__zero_table_start__'

    E:\ARM_F/SRC/startup_ARMCM3.S:234: undefined reference to `__zero_table_end__'

    collect2.exe: error: ld returned 1 exit status

     

    Toolchain GNU Tools ARM Embedded\5.4 2016q3

     

    Файл startup_ARMCM3.S взят из папки c тулчейном. Включён взамен стартового файла рабочего проекта, собранного на ARM MDK.

    Проект на GCC успешно компилится но не хочет собираться по указанным выше причинам. Вопрос - чего в супе не хватает?

    Это ведь области RAM, которые при старте инициализируются или обнуляются, что не так?

     

    Спасибо.

     

  8. Вопрос снят. Надо внимательней читать документацию. Но в описании косячёк всё же имеется. В одном месте можно понять, что функция выбора контакта есть праймари, а в другом месте она же - секондари. О как.

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