ARTIK 020 Bluetooth® Module Product Brief
코인 배터리, AA배터리등도 사용가능.
SIP-KITSLF001(약 12만원 2017년03월, 디지키 가격)
ARTIK 020 Bluetooth® Module Product Brief
코인 배터리, AA배터리등도 사용가능.
SIP-KITSLF001(약 12만원 2017년03월, 디지키 가격)
주의:본문은 검증되지 않았습니다.
비트-밴딩(Bit-banding)
---------------------------------------------------------
- 메모리를 절약하기위해, BOOL같은 변수는 1비트만 사용할 수 있게 해주는 방식.
- C컴파일러의 bool, BOOL등은 int형등으로 컴파일이 된다.
- 1비트변수를 사용하려면, 아래 주소를 액세스해야한다.
#define문을 사용하여 변수를 할당해야함을 의미한다.
실질적으로는 아래 그림과 같이 구성된다.
32비트 주소를 액세스하면, 1비트만 해당된다.
데이터쉬트등의 pdf문서에서는 아래와 같이 복잡한 수식(?)을 늘어 놓는다.
bit_word_offset = (byte_offset x 32) + (bit_number x 4) bit_word_addr = bit_band_base + bit_word_offset |
Bit-banding 메모리는 1Mbyte나 사용할 수 있으나, 실제로는 얼마되지 않는다.
내가 사용하는 칩은 얼마나 사용할 수 있을까?
STM32F205RCT6TR칩을 예로들어보면, 100k의 RAM을 가지고있다.
사실상 모든 RAM영역을 bit-banding하여 사용할 수 있음을 의미한다.
C언어로 변수할당하여 사용하는 변수와, C언어로 변수할당이 되었는지, 안되었는지 알 수 없는 RAM을 무작적, 직접 액세스할 수는 없다.
그래서, C언어로 bit-banding할 변수를 할당해놓고, 위의 복잡한(?)공식을 통해, RAM을 직접 액세스하면,
1비트단위로 액세스가 가능하다는 이야기이다.
C언어에서도 구조체(struct)로 1비트단위 액세스가 쉽게 된다.(struct bit field)
그러나, 이방식은 8~32비트에서 n비트만을 추출/삽입하는 코드가 들어간다.
그래서 비트필드 변수를 읽고, 쓰는작업은 느리다.
그러나, bit-banding을 사용하면, C언어의 비트필드보다 훨씬 더 빠르다는것이다.
(약 2~4배정도 빠를것으로 예상)
일단 비트밴딩할 변수를 할당하고, 해당 변수의 각 비트를 주소를 정해주어야 한다.
예) 아래는 예시이므로, 직접 확인해보기 바랍니다.
byte a;
#define RAM_START_ADDR 0x20000000
#define BIT_BANDING_START_ADDR 0x22000000
#define RAM_BIT_BANDING_GAP (BIT_BANDING_START_ADDR-RAM_START_ADDR)
#define a0 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+0))
#define a1 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+1))
#define a2 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+2))
...
#define a7 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+7))
a=0;
a1=1;
if(a==0x02)
{
printf("OK");
}
else
{
printf("err");
}
문제점
---------------------------
- 크로스컴파일이 안된다?
가능은 하다. 단, 실제변수 영역보다 8배 더 많은 영역을 비트-밴딩 영역으로 할당해야한다.
또한, 일반변수 액세스와, 비트밴딩 변수 영역이 다르므로, 2가지 방식으로 액세스가 불가능하다.
물론, 비트밴딩 함수/매크로를 만들어주면 되긴하다.
그러나, 그렇게되면, 모든 변수의 대입에 함수를 사용해야하고,
소스 코드가 너무 커지고, 복잡해지는 문제(?)가 발생한다.
cbi,sbi,gbi등을 이용한다면?
---------------------------------------------------------------------------
- cbi등의 매크로를 개조하여, 해당주소-비트의 bit-banding주소를 얻어서, 액세스하면, 쉽게 사용가능하다.
또한 실제 동작코드도 작아지고(?), 속도도 매우 빨라지게 된다.
- 레지스터에는 적용할 수 없어, 속도가 떨어지는 문제가 발생한다.
아래는 예문 코드이므로, 동작하지 않습니다. #define RAM_START_ADDR 0x20000000 #define BIT_BANDING_START_ADDR 0x22000000 #define BIT_BANDING_GAP (BIT_BANDING_START_ADDR-RAM_START_ADDR) #define BIT_BAND8(a,i) *((byte*)(&(a)-RAM_START_ADDR+BIT_BANDING_START_ADDR)+(i)) #define sbi(a,i) BIT_BAND8(a,i)=1 #define cbi(a,i) BIT_BAND8(a,i)=0 #define gbi(a,i) BIT_BAND8(a,i) |
주변장치 액세스할때 bit-banding은?
------------------------------------------------------------------------------------------
한번에 원하는 비트를 on/off할 수 있어 좋으나,
한번에 여러비트를 설정해야하는 경우도 많다. 이경우에는 더 느릴 수 도 있다.
결론
----------------------
Bit-banding은 매우 훌륭한 기능이나,
요즘 ARM Cortex칩들의 RAM이 부족하지는 않다.
과거의 8051이나, ATMega칩에 비해, 몇배나 더 많아졌다.
속도 또한 매우 빨라졌다.
굳이 bit-banding을 사용할 이유가 없다.
1) 메모리(RAM)가 정말 부족하고, 속도가 매우 중요한 경우
2) 속도가 매우 중요한 경우(주변장치 액세스)
__INT_LEAST8_TYPE__ __INT_FAST8_TYPE__ (0) | 2017.01.14 |
---|---|
C언어 - 배열 값 대입 코드 비교 (0) | 2016.12.16 |
임베디드 - AVR(ATMega) 개발환경 vs ARM cortex 개발환경 비교 (0) | 2016.11.17 |
임베디드 디버깅, 개발을 위한 크로스컴파일 환경 구축 (0) | 2016.11.02 |
gcc 링커스크립트 - 부트로더 주소지정 방법 (0) | 2016.10.07 |
아트멜사는 ATMega128을 비롯하여, 공전의 히트 제품을 출시하여, ARM cortex시리즈가 나오기 몇년전까지만해도,
엄청난 인기를 끌었다.
보통 AVR칩, AVR컴파일러등으로 불렀다.
(비디오 기록장치인 AVR과 관련이 없다.)
EEPROM을 내장하고, 적당한 성능에, 적당한 가격과, 무료컴파일러 지원이라는 시스템으로,
많은 사용자를 만들어냈다.
그당시에는 대부분의 컴파일러는 유료였고, 크렉하여 사용하던 시절이다.
현재의 대세인 ARM cortex시리즈와 비교해보면, AVR칩은 8비트에 16MHz이 저사양(?) cpu이고,
ARM cortex는 32비트에 보통 48MHz이상을 대부분 지원한다.
또한, 가격을 대폭 낮추어, 2016년 현재에는 AVR칩이 더 비싼 경우도 있다.
(수요가 줄어서, 가격이 올라간것도 이유)
어쨌든, 2016년에는 ARM cortex가 대세이다.
많은 칩제조회사들이 ARM코어를 사다가 칩을 제조하며,
이들 칩들은 대부분 호환이 가능하다.
가격
========
ARM coretex는 수많은 제조사들이 경쟁하여, 가격이 매우 낮아졌다.
AVR칩은 수요감소로 인해, 가격이 올라가는 추세이다.
소스코드 호환성
================
ARM coretex는 소스코드 조금만 손보면, 대부분의 칩에서 동작이 가능하다는 엄청난 메리트가 있다.
소스레벨에서는 어느정도 호환 가능하나, 사실상, 그냥 컴파일되는 경우는 없다.
또한, 32비트 CPU라서, 윈도우환경에서 개발하여, 포팅하는것도, 더욱 쉬워졌다.
AVR컴파일러는 1~2종류라고 봐도 된다.
2가지 컴파일러중 한가지에서 돌아가는 소스코드이다.
컴파일러 비교
==============
AVR컴파일로는 무료이나, ARM cortex 컴파일러는 gcc로 툴체인 구성하지않는한, 대부분 유료이다.
물론, 무료 컴파일러도 있으나, 많이 사용하지 않는다.
AVR컴파일러는 대표적인것이 2가지가 있다.
ARM컴파일러는 칩종류도 많고, 컴파일러 종류도 많다.
ARM은 소스문법에 따른 버그가 적으나,
AVR은 최적화시, 소스코드 작성을 어떻게 하느냐에따라, 알수없는 버그가 많은 편이다.
잘동작하는코드, 한두줄만 수정해도, 엉뚱한 상황이 벌어지는 경우가 생각보다 많다.
그냥 코드를 새로 다시 작성하다보면, 해결되는 경우도 있다.
코드의 순서를 어떻게 하느냐에 따라 문제가 생길 수 도 있고, 아닐 수 도 있다.
칩의 버그
=========
ARM칩은 각 제조사마다, 칩의 버그가 있는 경우가 있다.
아무래도, 초반이니 있을 수 있는 버그이나, 칩의 종류가 많기때문에, 해당버그는 수정되지 않고, 칩이 단종될 가능성도 있다.
예) STM사의 어떤칩은 UART인터럽트가 중간에 꺼져버린다.(호출이 안된다.)
AVR은 칩의 종류가 사실상 많지 않고, 10년넘게 사용되어, 많은 버그가 수정된 상태이다.
다음 프로젝트에 사용할 CPU는?
================================
당연히, ARM coretex이다.
AVR은 알수없는 컴파일러 문제가, 개발자들을 상당히 괴롭힌다.
이번에도 거의 다된 상태에서, 이상하게 동작을 한경우이다.
최적화 옵션을 끄니, 더 황당한 짓을 하기도 했다.
오히려, Os옵션으로 최적화 했을때, 그래도, 비교적 정상적인 동작을 했다.(어이 없음)
(물론, 윈도우에서 크로스컴파일 에뮬레이션까지 다해본 코드이다.)
C언어 - 배열 값 대입 코드 비교 (0) | 2016.12.16 |
---|---|
ARM Cortex-Bit-banding (0) | 2016.12.05 |
임베디드 디버깅, 개발을 위한 크로스컴파일 환경 구축 (0) | 2016.11.02 |
gcc 링커스크립트 - 부트로더 주소지정 방법 (0) | 2016.10.07 |
In-Application Programming (IAP) (0) | 2016.10.07 |
AVR, ARM등의 CPU프로그램을 작성할때,
1) 프로그램 작성
2) 다운로드
3) 테스트
4) 1번 부터, 될때까지 무한 반복.
문제는 다운로드 시간이 1초든, 10초든, 시간이 걸린다는 점입니다.
다운로드가 마우스클릭만으로 되는 경우는 드물고,
CPU 리셋을 하고, 다운로드하는 과정이 적게는 수십초~몇분까지도 걸립니다.
프로그램코드가 크다면, 다운로드 시간은 더 많이 걸립니다.
오타 하나 고치려고, 수정하고, 다운로드하고, 테스트하는 시간이 생각보다 많이 소모됩니다.
그래서, 윈도우환경에서 프로그램코드를 검증하고, 나중에 CPU에 다운로드해서, 테스트해보는 방법이 빠를 수 도 있습니다.
윈도우 환경에서는 많은 메모리와, VC++ 같은 우수한 컴파일러 환경을 사용할 수 있습니다.
문제는 윈도우 환경에서 동작하기위해, 코드를 각각 작성해야 하므로, 약 1.5배 정도의 코드를 작성해야 합니다.
C언어의 장점은 함수만 동일하게 작성하면, 어떤 환경이든, 대부분 동작이 된다는 것입니다.
물론, 하드웨어 환경도 비슷하게 꾸며주어야 합니다.
예) EEPROM_write() => WIN_EEPROM_File_Write()
보통 아래와 같이 매크로를 사용하여, 함수를 각각 만들어 줍니다.
void LCD_putch(byte c)
{
#ifdef WIN32
printf("%c",c);
#else
LCD_send_data(c);
#endif
}
UART통신, EEPROM, LCD, KEY등도 각각 함수를 만들어 줍니다.
물론, 윈도우 환경에서 사용할 함수를 만드는 작업이 쉽지않고, 시간도 많이 걸립니다.
그러나, 잘 많들어 놓으면, CPU에 다운로드하고, 테스트하는 시간이 획기적으로 줄어들어, 전체 개발속도가 향상될 수 있습니다.
ARM Cortex-Bit-banding (0) | 2016.12.05 |
---|---|
임베디드 - AVR(ATMega) 개발환경 vs ARM cortex 개발환경 비교 (0) | 2016.11.17 |
gcc 링커스크립트 - 부트로더 주소지정 방법 (0) | 2016.10.07 |
In-Application Programming (IAP) (0) | 2016.10.07 |
ARM Coretex STM3 - UART 인터럽트 송신 버그(?) (0) | 2016.09.28 |
기존 장비의 프로그램에 문제가 있어, 수정하고 있습니다.
다른 사람이 만든거라, 거의 새로 작성해야합니다.
기존 프로그램 코드는 여러가지 문제가 많아,
도저히 "부분수정"이 안됩니다.
"블랙박스모델"처럼, 입출력 동작 데이터만으로
"재구현"이 필요합니다.
물론 시간이 많이 걸립니다.
"부분수정", "최소수정"을 하려고, 다각도로 검토해보았으나.
시간만 많이 소요되고, 별 진전이 없고, "어차피 전체 수정이 필요하다"는 결론이 나옵니다.
지난번 장비 수정에서 약 50%의 시간이, "부분수정, 최소수정 검토"하는데 시간이 소모되었습니다.
"어떻게 수정할것인지에 대한 검토"는 반드시 필요하나, 발견되지 않은(않는) 문제때문에, 불필요하게 시간이 소요되는 경우가 맣습니다.
그냥 차라리, 블랙박스 모델로 새로 만드는것이 더 확실하고, 깔끔합니다.
그런데말입니다. 여기서 또 문제가 있습니다.
기능이 복잡한 경우에는 시간이 많이 소요됩니다.
최소수정으로 하려고하나, 안되는 경우에는 울며겨자먹기로, "재프로그램"을 하게 됩니다.
물론, 이경우에는 더 많은 시간이 소요됩니다.
system-reset을 구현하기위해, 와치독타이머를 사용하려고한다.
그러나, 기존 와치독 타이머는 너무 오래걸려서, 중지하고, 시간을 짧게 조절하려고한다.
=> IWDG는 한번 시작하면, 중지할 수 없다고 합니다.(변경 불가인듯)
적당한 시간설정해서 사용해야할듯.
인터럽트로 UART데이터를 보낼때, 일부 데이터가 전송이 안되는 경우가 발생했다.
원인은 확인할 수 없었고,
아래에 비슷한(?) 글이 있다.
https://community.nxp.com/thread/341862
요약 : USART_IT_TXE 가 발생하지 않는 경우가 있다.
USART_IT_TXE 발생시, 데이터를 널어주는 방식이었으나,
일부 전송이 안되는 문제로,
USART_IT_TC 인터럽트도 발생이 되지 않았다.
위 링크의 글대로, USART_IT_TXE로 보내고, 남는것은 메인루프에서 폴링방식으로 검사해서 전송되도록 했다.
gcc 링커스크립트 - 부트로더 주소지정 방법 (0) | 2016.10.07 |
---|---|
In-Application Programming (IAP) (0) | 2016.10.07 |
C언어를 잘하면, ATMega 프로그램도 잘 할 수 있나요? (0) | 2016.09.22 |
C언어 - 노드가 먼가요? (0) | 2016.09.22 |
VC++ 6.0 크로스컴파일 디버깅 (0) | 2016.09.22 |
보통 디지털 장비에는 CPU라고하는 칩이 들어가고, 프로그램을 넣어야 작동한다.
리눅스포팅과, 마이컴 프로그램의 차이는 무엇일까?
OS 포팅(프로그래밍)
보통 리눅스는 OS급의 기능(부가장치 드라이버 기능)이 필요한 장비에서 사용한다.
리눅스는 무료라서, 가장 많이 사용한다.
OS이다보니, 플래시 메모리와 RAM이 충분해야 돌아간다.
포팅은 다른 운영체제의 프로그램을 목적 환경에서 돌아가도록 수정하는것을 말하나,
요즘은 "리눅스포팅", "OS포팅"등으로 말하며, 대부분, 리눅스 운영체제를 동작가능하게 만드는 과정을 말한다.
운영체제를 사용하기 위해서는 malloc와 같은 동적 메모리할당 기능과, 가상메모리등의 기능들이 필요하다.
보통 화면출력(터치모니터등), LAN통신등을 하기위해 사용한다.
많은 복잡한 기능들이 필요한 경우에 사용한다.
TCP/IP스텍을 마이컴에 올릴 수 도 있으나, 여러가지 문제로 쉽지 않다.
이럴때, OS를 올리면, OS에서 기본 기능은 대부분 지원해주므로, 비교적 쉽고, 빠르게, 복잡하고, 많은 기능을 사용할 수 있다.
가격보다는 성능이 중요한곳에서 많이 사용한다.
CPU외에도 외부 RAM이 필요하기때문에, 여러개의 칩을 연결해야하고, 크기가 커지고, 소모전력도 올라간다.
저전력 기능이 필요한곳에서는 사용이 어렵다.
중/대규모 이상의 프로젝트
마이컴 프로그래밍
마이컴은 매우 소규모의 단순작업을 할 수 있는 수준에서 많이 사용된다.
예) 세탁기, 냉장고, 등등
마이컴 프로그래밍에서도 malloc등을 사용할 수 있으나, 메모리가 작기때문에, 사용하면, 속도가 느려지거나, 메모리가 부족하게되는등, 문제가 많기 때문에, 보통은 고정으로 변수를 지정해서 사용한다.
요즘은 1M바이트 이상의 고용량(?) CPU가 나오면서, 복잡하지 않은 왠만한 기능들은 마이컴CPU로도 만들 수 있다.
가격이 중요할 경우에 많이 사용한다.
CPU칩 하나로 대부분 구현이 가능하여, 저전력 기능이 필요한곳에 알맞다.
소/중 규모 프로젝트
/* ***************************************************************************** ** ** File : stm32_flash.ld ** ** Abstract : Linker script for STM32F207 Device with ** 1MByte FLASH, 128KByte SRAM ** ** Set heap size, stack size and stack location according ** to application requirements. ** ** Set memory bank area and size if external memory is used. ** ** Target : STMicroelectronics STM32 ** ** Environment : Eclipse with CDT plugin and GCC compiler from CodeSourcery ** ** Author Date Comment **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ** T.Kamenicky 24/06/11 Upravil kod stazen z netu ** T.Kamenicky 13/10/11 Predelal na STM32F2 ** T.Kamenicky 29/11/11 Pridal podporu externi SRAM ** ***************************************************************************** */ /* Entry Point */ /* This define entry point for linker, this address is used for CPU too as absolute first function */ ENTRY(Reset_Handler) /* Highest address of the user mode stack, _estack is end of stack */ _estack = 0x20020000; /* end of 128K RAM */ /* Generate a link error if heap and stack don't fit into RAM */ /* Heap is zero because we use own malloc implementation. The amount of heap is calculated * from free space after compilation, see last section for RAM area */ _Min_Heap_Size = 0x0; /* required amount of heap */ /* This stack is used for main function. If FreeRTOS is used this stack is used by OS itself. */ /* The size of stack for tasks is defined in freertos config file and when creating the task. */ _Min_Stack_Size = 0x600; /* required amount of stack */ /* Specify the memory areas */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1022K /* This is main program area */ FACTORY_VAR(rx) : ORIGIN = 0x080FF800, LENGTH = 2K /* This area is used for factory values, such as MAC address, ID...etc */ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* This is RAM area */ FSMC_SRAM (rx) : ORIGIN = 0x64000000, LENGTH = 2048K /* This is useful for external memory, like thru FSMC peripheral */ } /* Library configurations */ GROUP(libgcc.a libc.a libm.a libnosys.a) /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end * __etext * __data_start__ * __preinit_array_start * __preinit_array_end * __init_array_start * __init_array_end * __fini_array_start * __fini_array_end * __data_end__ * __bss_start__ * __bss_end__ * __end__ * end * __HeapLimit * __StackLimit * __StackTop * __stack */ ENTRY(Reset_Handler) SECTIONS { /* The startup code goes first into FLASH */ .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); } >FLASH /* The program code and other data goes into FLASH */ .text : { . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* glue arm to thumb code */ *(.glue_7t) /* glue thumb to arm code */ KEEP (*(.init)) KEEP (*(.fini)) . = ALIGN(4); _etext = .; /* define a global symbols at end of code */ } >FLASH /* .ARM.extab names a section that contains exception unwinding information. See EHABI for details. */ /* .ARM.exidx names a section that contains index entries for section unwinding. See EHABI for details. */ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH .ARM : { __exidx_start = .; *(.ARM.exidx*) __exidx_end = .; } >FLASH /* Is used for compiler information, which is located only in elf file */ .ARM.attributes 0 : { *(.ARM.attributes) } /* Those sections is used for initializing dynamic objects used in C++ */ .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array*)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array*)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(.fini_array*)) KEEP (*(SORT(.fini_array.*))) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH /* used by the startup as memory location to initialize data */ /* from this point the content of flash is copied to ram */ _sidata = .; /* Initialized data sections goes into RAM, load LMA copy after code */ .data : AT ( _sidata ) { . = ALIGN(4); _sdata = .; /* create a global symbol at data start */ *(.data) /* .data sections */ *(.data*) /* .data* sections */ . = ALIGN(4); _edata = .; /* define a global symbol at data end */ } >RAM _SRAM_data = _sidata + _edata - _sdata; /* Second part of inicialized section goes into SRAM conected thru FSMC */ /* FSMC_SRAM section, code must be located here explicitly */ /* unsigned long int __attribute__ ((section (".sram_data"))) my_initialized_number = 0xAABBCCDD; */ .fsmc_sram_data : AT ( _SRAM_data ) { . = ALIGN(4); _iSRAM_data = .; *(.sram_data) *(.sram_data*) . = ALIGN(4); _iSRAM_data_end = .; } >FSMC_SRAM .fsmc_sram_bss : AT ( _iSRAM_data_end ) { _iSRAM_null_data = .; *(.sram_bss) *(.sram_bss*) . = ALIGN(4); _iSRAM_null_data_end = .; } >FSMC_SRAM .fsmc_sram_perma : AT ( _iSRAM_null_data_end ) { _iSRAM_perma_data = .; *(.sram_perma) *(.sram_perma*) . = ALIGN(4); _iSRAM_perma_data_end = .; } >FSMC_SRAM /* Uninitialized data section */ . = ALIGN(4); .bss : AT ( _edata ) { /* This is used by the startup in order to initialize the .bss secion */ _sbss = .; /* define a global symbol at bss start */ __bss_start__ = _sbss; *(.bss) *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; } >RAM /* Those numbers are used for SRAM init */ PROVIDE ( _linker_sram_start = _iSRAM_data ); PROVIDE ( _linker_sram_data_end = _iSRAM_data_end ); PROVIDE ( _linker_sram_end = _iSRAM_null_data_end ); PROVIDE ( _linker_sram_inits = _SRAM_data ); /* Those numbers are used for malloc and sbrk functions */ PROVIDE ( _linker_memory_start = _sdata ); PROVIDE ( _linker_heap_start = _ebss ); PROVIDE ( _linker_heap_end = (_estack - _Min_Stack_Size) ); PROVIDE ( _linker_memory_end = _estack ); PROVIDE ( _end = _ebss ); /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : AT ( _linker_heap_end ) { . = ALIGN(4); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); } >RAM /* FLASH memory area for factory default values */ /* Example of usage: extern int foo(void) __attribute__ ((section (".fvtext"))); */ /* unsigned long int my_factory_number_changed_in_production = 0xAABBCCDD __attribute__ ((section (".fvrodata"))); */ .factory_values : { . = ALIGN(4); *(.fvtext) /* .fvtext sections (code) */ *(.fvtext*) /* .fvtext* sections (code) */ *(.fvrodata) /* read-only data (constants) */ *(.fvrodata*) . = ALIGN(4); } >FACTORY_VAR /* Remove information from the standard libraries */ /DISCARD/ : { libc.a ( * ) libm.a ( * ) libgcc.a ( * ) } } |
STMicroelectronics HEX파일 gcc HEX파일 비교 (0) | 2016.09.09 |
---|---|
gcc hex, bin file size 줄이기 (0) | 2016.09.09 |
uint64_t gcc err (0) | 2016.09.09 |
gcc - error: two or more data types in declaration specifiers (0) | 2016.09.09 |
startup_stm32f2xx.s - arm? gcc_ride7? (0) | 2016.09.09 |