Jump to content

    
Alex_Golubev

Может кто поделиться примером переноса вектора прерывания в память ITCMRAM на stm32 в gcc

Recommended Posts

uint32_t *src = (uint32_t *)(flash address of vectors);
uint32_t *dst = (uint32_t *)(ITCRAM address of vectors);
for( int i = 0; i < number_of_vectors; i++)
    *dst++ = *src++;

Вот самый топ искусства программирования !

Share this post


Link to post
Share on other sites
12 минут назад, Alex_Golubev сказал:

Хочу перенести вектор прерывания в ITCRAM для увеличения скорости выполнения

И сколько наносекунд планируете выиграть?  :biggrin:

Share this post


Link to post
Share on other sites
1 час назад, Alex_Golubev сказал:

Хочу перенести вектор прерывания в ITCRAM для увеличения скорости выполнения есть у кого пример как это сделать?

Просто объявляете регион памяти для ITCRAM, а затем в атрибутах функции указываете этот регион.

Примерно так (функция в ОЗУ):

int ram_func(const int x, const int y) __attribute__(( section(".ramfunc") ));

В скрипте линкера:

	.data : AT ( _sidata )
	{
		. = ALIGN(4);
		_sdata = .;
		*(.data)
		*(.data.*)
		*(.ramfunc)
		. = ALIGN(4);
		_edata = . ;
	} >RAM

 

Share this post


Link to post
Share on other sites

Не забудьте сказать процессору о том, куда переложили таблицу векторов. SBC->VTOR

P.S. и располагать таблицу векторов нельзя где попало. Нужно выровнять.  Не знаю, какой из stm32 имеется в виду, но обычно выравнивание требуется по границе 128 или 256 байт.

Edited by one_eight_seven

Share this post


Link to post
Share on other sites
1 час назад, Alex_Golubev сказал:

Хочу перенести вектор прерывания в ITCRAM для увеличения скорости выполнения

Один вектор? Или несколько? Или всю таблицу векторов полностью?

Share this post


Link to post
Share on other sites

Перенести можно только всю таблицу целиком.

Но можно и не переносить: вектора во flash, обработчик прерывания в ОЗУ.

Share this post


Link to post
Share on other sites
41 минуту назад, adnega сказал:

вектора во flash, обработчик прерывания в ОЗУ.

Да, я именно это и имел ввиду. Неправильно выразился.

Сами обработчики могут быть раскиданы как угодно. Часть во флеше, часть в ОЗУ.

Share this post


Link to post
Share on other sites
2 минуты назад, Darth Vader сказал:

Да, я именно это и имел ввиду. Неправильно выразился.

Сами обработчики могут быть раскиданы как угодно. Часть во флеше, часть в ОЗУ.

Все реально. Если код не модифицирующийся - тогда совсем легко.

Когда вы укажите функции секцию, то она скомпилируется с адресами из ОЗУ, но копия будет лежать во flash.

Стартап на этапе инициализации секций должен скопировать образ из flash в ОЗУ. Все! - функцию/обработчик можно вызывать.

Share this post


Link to post
Share on other sites

Пытаюсь разобраться.

При старте вызывается функция 'SystemInit()' в ней происходит перенос векторов 'VTOR' включение 'float' и настройка тактовой частоты.  Вектора переносятся:

#define D1_ITCMRAM_BASE (0x00000000UL)
#define VECT_TAB_OFFSET  0x00000000UL

extern unsigned char itcm_text_start;
extern unsigned char itcm_text_end;
extern unsigned char itcm_data;  
  
SCB->VTOR = D1_ITCMRAM_BASE   | VECT_TAB_OFFSET; 

memcpy(&itcm_text_start, &itcm_data, (int) (&itcm_text_end - &itcm_text_start));

Не совсем понимаю скрип линкира поэтому могу ошибиться.

Добавил 

Скрытый текст

   itcm_data = LOADADDR(.itcm_text); 
   .itcm_text :
   {
   . = ALIGN(4);
   itcm_text_start = .;
   *core_*.o(.text*)
   *(.itcm_text) /**/
   *(.itcm_text*) /**/
   . = ALIGN(4);
   itcm_text_end = .;
   } >ITCM_RAM AT> FLASH

 

Привожу весь flash.id 

Скрытый текст

ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);	/* end of "RAM_D1" Ram type memory */

_Min_Heap_Size = 0x1000 ;	/* required amount of heap  */
_Min_Stack_Size = 0x2000 ;	/* required amount of stack */

/* Memories definition */
MEMORY
{
  DTCMRAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  ITCMRAM    (xrw)    : ORIGIN = 0x00000000,   LENGTH = 64K
  RAM_D1    (xrw)    : ORIGIN = 0x24000000,   LENGTH = 512K
  RAM_D2    (xrw)    : ORIGIN = 0x30000000,   LENGTH = 288K
  RAM_D3    (xrw)    : ORIGIN = 0x38000000,   LENGTH = 64K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 2048K
}

/* Sections */
SECTIONS
{
  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH
  
  .SYS : 
  { *(.SYS)
  } >DTCMRAM
  
  .DIO : 
  { *(.DIO)
  } >RAM_D1
  
  .D2 : 
  { 
  . = ALIGN(4);
  *(.D2)
  } >RAM_D2
  
  .dma_buffer : 
  { *(.dma_buffer) 
  } >RAM_D3

   itcm_data = LOADADDR(.itcm_text); 
   .itcm_text :
   {
   . = ALIGN(4);
   itcm_text_start = .;
   *core_*.o(.text*)
   *(.itcm_text) /**/
   *(.itcm_text*) /**/
   . = ALIGN(4);
   itcm_text_end = .;
   } >ITCM_RAM AT> FLASH


  /* Constant data into "FLASH" Rom type memory */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH

  .ARM.extab   : { 
    . = ALIGN(4);
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    . = ALIGN(4);
  } >FLASH
  
  .ARM : {
    . = ALIGN(4);
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
    . = ALIGN(4);
  } >FLASH

  .preinit_array     :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    . = ALIGN(4);
  } >FLASH
  
  .init_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
    . = ALIGN(4);
  } >FLASH
  
  .fini_array :
  {
    . = ALIGN(4);
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
    . = ALIGN(4);
  } >FLASH

  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM_D1" Ram type memory */
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
    
  } >RAM_D1 AT> FLASH

  /* Uninitialized data section into "RAM_D1" Ram type memory */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)

    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM_D1

  /* User_heap_stack section, used to check that there is enough "RAM_D1" Ram  type memory left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM_D1

  /* Remove information from the compiler libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

 

Вопрос все правильно сделал со скриптом линкира? И как можно проверить что вектора перенеслись в область ITCMRAM?

Share this post


Link to post
Share on other sites

Вектора не перенеслись 

Скрытый текст

.isr_vector     0x0000000008000000      0x298
                0x0000000008000000                . = ALIGN (0x4)
 *(.isr_vector)
 .isr_vector    0x0000000008000000      0x298 Startup/startup_stm32h743vitx.o
                0x0000000008000000                g_pfnVectors
                0x0000000008000298                . = ALIGN (0x4)

 

оказались в область flash памяти.

Edited by Alex_Golubev

Share this post


Link to post
Share on other sites
1 hour ago, Alex_Golubev said:

Вектора не перенеслись 

оказались в область flash памяти.

 

Так вы же сами указали их там размещать

.isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

 

Share this post


Link to post
Share on other sites
19 minutes ago, Alex_Golubev said:

вектора перенеслись но программа не запускается .

Конечно. Они собрались у вас после текста. Для переноса векторов вам надо создать место для второй таблицы, и при старте скопировать туда основную. Или создать сразу две таблицы, в разных секциях.

Edited by one_eight_seven

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.