Два уровня кода для STM32F4

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
TripleKill
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Два уровня кода для STM32F4

Сообщение TripleKill »

Подскажите, как можно реализовать подобное. В контроллере выделяются два (или более) диапазона памяти. В каждый может записываться код, но код из "верхнего" диапазона может вызывать функцию из "нижнего".
Условная иллюстрация:
Изображение

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

Спасибо.
Аватара пользователя
Goodefine
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Re: Два уровня кода для STM32F4

Сообщение Goodefine »

Смотрите настройки линкера (если iar - файл icf). Как лягут адреса можно видеть в map файле, более того, адреса можно задавать (#pragma location..). Крайне рекомендуется читать мануал на среду разработки, например...
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
TripleKill
Вымогатель припоя
Сообщения: 671
Зарегистрирован: Вт июн 29, 2010 12:31:49

Re: Два уровня кода для STM32F4

Сообщение TripleKill »

Простите, сразу не указал. Пользуюсь кейлом. В настройках нашёл, где расположение кода в памяти менять, а вот прагму такую он не знает. Попробую поискать мануал, спасибо.
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: Два уровня кода для STM32F4

Сообщение ut1wpr »

Создать таблицу точек входа в функции сегмента, жестко ее привязать к фиксированному адресу, в таблице разместить переходы на функции. В дальнейшем вызовы функций осуществлять по адресам из таблицы. Можно по начальному адресу + смещение. Размещение функций в сегменте отдать на откуп линкеру.
С уважением,
Виктор.
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: Два уровня кода для STM32F4

Сообщение BorisSPB »

В свойствах проекта в закладке Target определить дополнительные секции с нужными адресами и атрибутами. Откомпилировать.
В результате в выходной папке будет сгенерирован scatter-файл с расширением .sct.
В свойствах проекта в закладке Linker убрать галочку с пункта Use Memory Layout from Target Dialog и в поле Scatter File выбрать нужный файл.
Отредактировать по своим потребностям, например:

Код: Выделить всё

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 UNINIT 0x00000100  {  ; RW data
   *(NoInit)
  }
  RW_IRAM2 0x20000100 UNINIT 0x00000100  {  ; RW data
   *(Custom)
  }
  RW_IRAM3 0x20000200 0x00004E00  {
   .ANY (+RW +ZI)
  }
}


Здесь объявлены две дополнительные секции NoInit и Custom.
В коде объявить атрибуты:

Код: Выделить всё

int var1 __attribute__( ( section( "NoInit"),zero_init) );
int var2 __attribute__( ( section( "Custom"),zero_init) );

В итоге var1 будет размещена в секции NoInit, а var2 в секции Custom.
Все сказанное справедливо и для функций, только объявление функции будет типа:

Код: Выделить всё

void MyFunction (void) __attribute__ ((section ("MySection")));

Сама секция должна быть в ROM. Например:

Код: Выделить всё

  ER_IROM2 0x0801A000 0x00006000  {  ; load address = execution address
   *(MySection)
  }

Кроме имен секций можно указывать еще и имена объектных файлов, тогда все относящееся к определенному исходнику будет размещено в нужной секции.
Аватара пользователя
kisssko
Открыл глаза
Сообщения: 52
Зарегистрирован: Пт янв 10, 2014 02:05:13
Откуда: Воронеж

Re: Два уровня кода для STM32F4

Сообщение kisssko »

Указатели функций можно разместить в массиве, а массив положить в известном месте, вместе с кодом.. В массив же компилятор сам всё пропишет.
Как то так инициализировать его:

Код: Выделить всё

uint32_t fnlist[]=
{
 (uint32_t)func1,
 (uint32_t)func2,
 (uint32_t)func3,
 (uint32_t)func4
};


Или так:

Код: Выделить всё

// Здесь задать нужный прототип функций
typedef void (*fnptr)(void);
fnptr fnlist[]=
{
 func1,
 func2,
 func3,
 func4
};


Если прототипы разные - можно в виде структуры сделать, вместо массива. Или при вызове приведение типа делать.
Ответить

Вернуться в «ARM»