После того, как FMC/FSMC запустился и работает, внешняя память отражается по соответствующим адресам. Эту память можно использовать по захардкоденным адресам
char * ptr = (char*)0xC0000000; |
но каждый раз вычислять адреса не комильфо. Тем более, для этого как раз есть специальная штука — heap и malloc/free.
Нужно только рассказать malloc где у нас эта память и сколько её. Самый простой способ — исправить правила линковки: Суть такова. _sbrk использует память начиная c адреса переданного линковщиком как end, стоит положить его адрес SDRAM, как malloc начинает раздавать адреса из неё.
например из соответствующих правил сборки грохнуть
PROVIDE( end = .) |
и дописать свой:
end = 0xC000000; |
Или добавить полноценно, в описании памяти добавить регион SDRAM
MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K SDRAM(rw) : ORIGIN = 0xC0000000, LENGTH = 8M } |
и добавить секцию в раздел SECTIONS:
._user_heap(NOLOAD) : { PROVIDE(_heap_start = .); PROVIDE ( end = . ); . += LENGTH(SDRAM); PROVIDE(_heap_end = .); } >SDRAM |
или (если не нравится, что size показывает дофига) без секции:
_heap_start = ORIGIN(SDRAM); _heap_end = ORIGIN(SDRAM)+LENGTH(SDRAM); |
А символы _heap_start и _heap_end будем использовать в своей реализации _sbrk, которая еще проверит не вылезаем ли мы за размер:
#include <stdlib.h> #include <errno.h> caddr_t _sbrk(int incr) { extern uint8_t _heap_start; extern uint8_t _heap_end; static uint8_t *current_end = NULL; uint8_t *current_block_address; if (!current_end) current_end = &_heap_start; current_block_address = current_end; incr = (incr + 3) & (~3); if (current_end + incr > &_heap_end) { errno = ENOMEM; return (caddr_t) -1; } current_end += incr; return (caddr_t) current_block_address; } |