Страница 1 из 1

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

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

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

Спасибо.

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

Добавлено: Ср апр 09, 2014 19:33:23
Goodefine
Смотрите настройки линкера (если iar - файл icf). Как лягут адреса можно видеть в map файле, более того, адреса можно задавать (#pragma location..). Крайне рекомендуется читать мануал на среду разработки, например...

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

Добавлено: Чт апр 10, 2014 10:55:50
TripleKill
Простите, сразу не указал. Пользуюсь кейлом. В настройках нашёл, где расположение кода в памяти менять, а вот прагму такую он не знает. Попробую поискать мануал, спасибо.

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

Добавлено: Чт апр 10, 2014 12:02:20
ut1wpr
Создать таблицу точек входа в функции сегмента, жестко ее привязать к фиксированному адресу, в таблице разместить переходы на функции. В дальнейшем вызовы функций осуществлять по адресам из таблицы. Можно по начальному адресу + смещение. Размещение функций в сегменте отдать на откуп линкеру.

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

Добавлено: Пт апр 11, 2014 14:55:53
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)
  }

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

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

Добавлено: Пт апр 11, 2014 17:59:53
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
};


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