STM32f103c8t6 (ram 20kbyte, flash 64kbyte) 사용중 mp3 파일을 CPU 내장 플래시(flash)메모리에 넣고자 애쓰다가 삽질했다.
http://www.iar.com/Global/Resources/Developers_Toolbox/Building_and_debugging/Constructing%20a%20bootloader%20STM32F207ZG-SK.pdf
위에 링크한 게시물을 확인하세요.
그러니까.. 펌웨어를 작성하는데, 프로그램 안에서 jpg 파일이나 mp3파일이나 wav 파일등 바이너리(binary)데이터를 flash에 넣고 그것을 읽어서 사용하고 싶을때 어떻게 하느냐.
xxx.h 나 xxx.c 등.. 코드로 변환하여 파일을 포함시키면 기본적으로 ram 에 올라간다. 그러면 안그래도 부족한 램이 꽉차서 프로그램이 뻣어버린다. 따라서 flash에 넣고 그것을 읽어서 사용하도록 해야 한다.
방법은 iar ewarm 의 linker 옵션의 input 섹션의 raw binary image 기능이다.
파일을 선택하고, symbol 과 section을 지정해주고, icf 파일에다가 직접 원하는 flash 속에서의 주소를 지정해준다.
그렇게 하면 linker 가 icf 에 기술한 주소에 raw binary image 로 지정한 파일을 해당 위치에 저장해준다.
그러면 프로그램에서는 unsigned char *my_jpg = (unsigned char*)0x08001234 식으로 파일의 주소를 직접 지정하여 읽어서 사용하면 된다.
이거 몰라서 hex로 변환하여 프로젝트에 .c 파일로 추가해서 했다가 졸라 삽질했다.
왜냐하면 램이 20KByte 밖에 없는데 내가 추가한 파일은 15KByte 였으니까 프로그램이 시작도 못하고 죽지... 젠장..
예제)
stm32f10x_flash.icf 를 다음과 같이 수정하였음
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000 ;
define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x3000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:0x08008000 {section .wave };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
위에 place at address mem:0x08008000 {section .mp3 }; 부분의 0x08008000 이라는 주소는 0x0800FFFF (FLASH의 끝 주소) 에서 파일 용량만큼 7FFF(32KB) 만큼 뺀 것이다.
링커 옵션의 input 섹션에 다음과 같이 파일을 추가해야함.
No comments:
Post a Comment