Страница 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
};
Если прототипы разные - можно в виде структуры сделать, вместо массива. Или при вызове приведение типа делать.