-
Notifications
You must be signed in to change notification settings - Fork 0
/
memory-link.txt
executable file
·114 lines (83 loc) · 8.15 KB
/
memory-link.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
С точки зрения программирования внутреняя память микроконтроллера stm32f429
состоит из шести областей, у каждой из которых есть уникальные свойства
(см. Memory mapping, DM00071990.pdf, STM32F427xx and STM32F429xx datasheet,
p.84):
-- флеш-память (Flash memory), содержимое которой не изменяется во время
работы программы;
-- CCM data RAM (64 KB data SRAM), с которой может работать только ядро
(см. Figure 5. STM32F427xx and STM32F429xx Multi-AHB matrix, p.21 там же);
-- SRAM1, с которой ядро может работать используя шину данных; эту
область памяти руководства рекомендуют отображать в нулевые адреса
(см. 2.3.1 Embedded SRAM, DM00031020.pdf, RM0090 Reference manual, p.68);
-- SRAM2 и SRAM3, для доступа к которым ядро может использовать только
системную шину;
-- Backup SRAM, питание которой может осуществляться от внешней батарейки.
Кроме того к микроконтроллеру может подключаться несколько микросхем внешней
памяти (каждая также со своими уникальными свойствами).
При программировании необходимо учитывать наличие и свойства этих областей
памяти, для примера: буфера для перефрийных устройств при использовании модулей
DMA не могут располагаться в памяти CCMRAM; буфера устройств активно
использующих память имеет смысл разнести по разным областям памяти, в этом
случае будет обеспечина их параллельная бесконфликтная работа.
С другой стороны, компилятор GCC разделяет единое адресное пространство памяти
на четыре следующих сегмента:
-- сегмент кода .text;
-- сегмент инициализированных данных .data;
-- сегмент неинициализированных данных .bss;
-- сегмент данных только для чтения .rodata (в этот сегмент попадают данные
используемые для инициализации переменных с областью размещения auto).
Размещением указанных сегментов по конкретным адресам в памяти микроконтроллера
занимается линковщик (программа ld). Это размещение выполняется в соответствии
со скриптами (программами) линковки.
Стандартные скрипты линковки крайне просты и не учитывают всего многообразия
видов памяти микроконтроллеров. Поэтому были написаны специализированные
скрипты линковки и соответствующим образом изменена процедура инициализации
памяти микроконтроллера.
Скрипт линковки разделён на два файла:
-- ldscripts/mem.ld (или fast-mem.ld), в котором описывается конфигурация
памяти микроконтроллера;
-- ldscripts/sections.ld, в котором указано размещение стандартных и
специализированных сегментов программы по областям памяти микроконтроллера.
В качестве основной памяти для переменных используется область памяти CCMRAM,
стек располагается также в памяти CCMRAM.
Размещение области динамически распределяемой памяти (кучи) может быть задано
индивидуально с помощью определения REGION_HEAP в файле mem.ld (fast-mem.ld);
сейчас эта область размещается в основной памяти (REGION_HEAP совпадает с CCMRAM).
Для указания в программе размещения переменных в определённых областях памяти
предлагаются следующие макросы (см.файл sections.h):
RO_DATA размещение переменной во флеш-памяти;
NOINIT размещение неинициализированной переменной в обычной памяти
(REGION_DATA, размещение задаётся в скрипте линковки);
BACKUP_NOINIT размещение неинициализированной переменной в памяти Backup SRAM;
EXTMEM_NOINIT размещение неинициализированной переменной во внешней памяти;
BIT_BAND_DATA размещение инициализированной битовой переменной;
BIT_BAND_BSS размещение битовой переменной с начальным значением 0;
BIT_BAND_NOINIT размещение неинициализированной битовой переменной;
CCMRAM_DATA размещение инициализированной переменной в памяти CCMRAM;
CCMRAM_BSS размещение переменной с начальным значением 0 в памяти CCMRAM;
CCMRAM_NOINIT размещение неинициализированной переменной в памяти CCMRAM.
Аналогично последним трём макросам определены макросы для резмещения переменных
в областях памяти SRAM1, SRAM2 и SRAM3: SRAMx_DATA, SRAMx_BSS, SRAMx_NOINIT,
где x может принимать значения 1, 2 или 3.
Общий формат использования макросов:
MACRO_NAME( <type>, <var name> [,<init value>] ), где
<type> -- тип переменной (например, short int);
<var name> -- имя переменной;
<init value> -- необязательное присвоение начального значения переменной
(только для xxx_DATA).
Пример использования макросов:
#include <sections.h>
SRAM2_NOINIT( unsigned char, BigRingBuf[1024] );
CCMRAM_BSS( unsigned long int, FastCounter );
CCMRAM_DATA( unsigned long int, FastFlags, = 0x8008 );
RO_DATA( const unsigned char, HelloWorldText[], = "Hello World!" );
Процедура инициализации выполняет функции, ссылки на которые находятся в
сегментах .preinit_array_sysinit, .preinit_array_platform и .preinit_array
(см. файл sections.ld); затем обнуляет сегменты .bss, инициализирует
(с помощью функции memcpy) данные в сегментах .data и выполняет функции,
ссылки на которые находятся в сегменте .init_array. После этого управление
передаётся в функцию main. После возврата из функции main выполняются функции,
ссылки на которые находятся в сегменте .fini_array.
Код процедуры инициализации находится в файле startup.S.
Потрепалов И.С.
Апрель 2015 г.