Программирование ARM: решение проблем, FAQ BEKEN: как поместить функцию в RAM Sat, July 13 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

BEKEN: как поместить функцию в RAM Печать
Добавил(а) microsin   

По умолчанию код пользователя размещается в памяти FLASH. В этом случае такой код прозрачно для кода приложения подгружается в кэш и оттуда уже выполняется. В моменты копирования кода из FLASH в RAM кэша происходят задержки, появление которых прогнозировать невозможно.

В некоторых случаях необходимо обеспечить жесткий реалтайм, чтобы функция всегда работала строго определенное, заранее известное время (например код, который формирует задержки для потока данных RGB-светодиода [2]). Или нужно, чтобы функция всегда отрабатывала максимально быстро (например код обработчика прерывания, ISR). Для этого необходимо гарантировать, чтобы функция и любой вызываемый из неё код находились в RAM.

Некоторые системные функции, такие как код планировщика и API-функции RTOS, размещены в RAM. Размещение кода и данных в определенные места адресного пространства управляется файлом настройки линкера тулчейна GCC (файл с расширением *.ld или *.lds). Имена функций, которые должны быть размещены в RAM, должны быть упомянуты в соответствующей секции этого файла. Ниже приведен пример размещения в RAM микроконтроллера BK7231N пользовательской функции void myRAMfunc (uint8_t color).

void myRAMfunc (uin8_t color)
{
   uint32_t duty;
 
   bk_pwm_initlevl_set_high(PWM_CHANNEL);
 
   GLOBAL_INT_DECLARATION();
   GLOBAL_INT_DISABLE();
 
   duty = (color & MASK_GREEN) ? 65 : 13;
   pwm_set_duty_cycle(PWM_CHANNEL, duty);
   pwm_unit_enable(PWM_CHANNEL);
   rgbdelay(145);
   ...
 
   pwm_unit_disable(PWM_CHANNEL);
   GLOBAL_INT_RESTORE();
}

Ниже показан фрагмент файла линкера config/bk7231n_boot.lds, для функции myRAMfunc добавлена красная строчка:

/* Разделение памяти на области векторов и ОЗУ */
MEMORY
{
   flash  (rx) : ORIGIN = 0x00010000, LENGTH = 2M-68K
   tcm   (rw!x): ORIGIN = 0x003F0000, LENGTH = 60k
   itcm   (rwx): ORIGIN = 0x003FF000, LENGTH = 4k
   ram  (rw!x):  ORIGIN = 0x00400100, LENGTH = 192k - 0x100
}
 
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_vector_start);
_vector_start = ORIGIN(flash);
 
SECTIONS
{
/* Регион векторов прерывания */
   . = ORIGIN(flash);
   .vectors :
   {
      KEEP(*(*.vectors))
      KEEP( *(*.rom1))
   } > flash
 
/* Регион кода инструкций */
 
    . = ORIGIN(itcm);
    .itcm.code ALIGN(8) :
    {
      /* itcm 4KB code */
      *(.text.intc_hdl_entry)
      *(.text.intc_irq)
      ...
      *(.text.rt_hw_interrupt_enable)
      *(.text.rt_thread_self)
      /**(.text.rt_schedule_remove_thread)*/
      *(.text.rt_timer_stop)
      /**(.text.rt_thread_resume)*/
      *port_asm.o(.text .text.*)
      *context_gcc.o(.text .text.*)
      *(.text.myRAMfunc)
    } > itcm AT>flash
    _itcmcode_flash_begin = LOADADDR(.itcm.code);
    _itcmcode_ram_begin = ADDR(.itcm.code);
    _itcmcode_ram_end = _itcmcode_ram_begin + SIZEOF(.itcm.code);
    ...

[Ссылки]

1. bekencorp / bdk_rtt site:github.com.
2. WS2811: микросхема для управления трехцветным RGB-светодиодом.

 

Добавить комментарий


Защитный код
Обновить

Top of Page