2016-07-18 4 views
2

Keil을 사용하여 Windows에서 stm32 arm cortex m3 마이크로 컨트롤러를 프로그래밍 한 경험이 있습니다. 이제 리눅스 환경으로 이동하고 오픈 소스 도구를 사용하여 STM32 cortex m3 장치를 프로그래밍하려고합니다.우분투에서 STM32f103 프로그램을 컴파일하는 방법은 무엇입니까?

나는 조금 연구를 해본 결과 OpenOCD 또는 Texane의 ST Link를 사용하여 칩을 플래시 할 수 있음을 발견했다. 나는 또한 코드를 컴파일하기 위해 크로스 컴파일러가 필요하다는 것을 알았다. gcc-arm-none-eabi 툴 체인.

기본 소스 및 헤더 파일이 필요한지 알고 싶습니다. 간단한 깜박임 프로그램을 만드는 데 필요한 핵심 및 시스템 파일은 다음과 같습니다.

저는 현재 HAL 라이브러리를 사용하지 않을 것입니다. 난 stm32f103zet6 mcu (매우 일반적인 보드)를 사용하고 있습니다. http://regalis.com.pl/en/arm-cortex-stm32-gnulinux/으로 갔지만 파일을 정확히 찾아 낼 수 없었습니다.

리눅스 환경에서 stm32 프로그래밍을 시작하기위한 튜토리얼이 있다면 알려주십시오.

도움을 주시면 감사하겠습니다. 감사!

+0

HAL과 베어 메탈을 사용하는 많은 예제가 있습니다. 당신은 자신의 헤더를 만들 수 있습니다. stm hal이나 cmsis가 필요하지 않습니다. 원하는 경우 원하는 값을 사용할 수 있습니다. –

답변

-1

http://gnuarmeclipse.github.io/

이 당신은 IDE (이클립스), 툴체인, 디버거, 헤더를 포함한 모든 것을 찾을 수 있습니다.

+0

답장을 보내 주셔서 감사합니다! 정말 감사. 그러나, 나는 IDE를 찾고 있지 않다. 사실, 나는 IDE를 사용하고 싶지 않다. 도구 체인과 Makefiles로 작업하고 싶습니다. 미안, 나는 내 질문에 충분히 명확하지 않았다. 명령 줄에서 모든 것을하고 싶습니다. 나는 이제 가능한지 궁금해.? – Navin

+0

eclipse 및 위에서 언급 한 사이트의 플러그인을 사용하여 샘플 프로젝트를 만든 다음 생성 된 makefile 및 디렉토리 구조를 시작점으로 사용할 수 있습니다. – berendi

-1

이 부분을보세요. package. 이것은 IDE + toolchain + 디버거이며 Linux 플랫폼에서 사용할 수 있습니다. 그것을 연구하고 원하는 것을 할 수있는 아이디어를 얻을 수 있습니다. 나는 리눅스 프로그램의 대부분이 commnad 라인 인터페이스를 가지기를 바란다.

나는 당신에게 제안 할 수 있습니다 : 이미 귀하의 MCU에 사용할 수있는 경우 LL API를 사용해보십시오.

2

다음은 stm32 제품군 전체에서 상당히 이식성이 좋은 매우 간단한 예입니다. Doesnt는 도움이되는 무엇이든을지도 또는 무언가를 깜박 거리기 위하여 공백에서 기입해야한다 (도식을 읽으십시오, 설명서, gpio에 시계를 가능하게하고십시오, 지시를 따르십시오 그/푸시 산출을 밀기 위하여 etc로, 놓으십시오 비트 또는 비트 등을 지우십시오).

나는 다른 사람들이 어떻게 할 수 있는지에 대한 나의 이유가 있으며, 우리는 모두 그러한 견해들 뒤에 수십 년이나 수십 년간 다양한 경험을 가지고 있습니다. 그러나 하루가 끝날 때마다 의견을 말하고 여러 가지 해결책이 효과가 있습니다. 당신은 단순히 툴체인을 얻기 위해이 작업을 수행 할 수 있습니다 우분투의 마지막 많은 자료

:

apt-get install gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi 

또는 당신은 운영 체제를위한 사전 구축 여기 얻을 수

https://launchpad.net/gcc-arm-embedded 

flash.s

.cpu cortex-m0 
.thumb 
.thumb_func 
.global _start 
_start: 
stacktop: .word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.thumb_func 
reset: 
    bl notmain 
    b hang 
.thumb_func 
hang: b . 
.align 
.thumb_func 
.globl PUT16 
PUT16: 
    strh r1,[r0] 
    bx lr 
.thumb_func 
.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr 
.thumb_func 
.globl GET32 
GET32: 
    ldr r0,[r0] 
    bx lr 
.thumb_func 
.globl dummy 
dummy: 
    bx lr 
.end 

flash.ld

MEMORY 
{ 
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

.cpu cortex-m0 
.thumb 
.thumb_func 
.global _start 
_start: 
    ldr r0,stacktop 
    mov sp,r0 
    bl notmain 
    b hang 
.thumb_func 
hang: b . 
.align 
stacktop: .word 0x20001000 
.thumb_func 
.globl PUT16 
PUT16: 
    strh r1,[r0] 
    bx lr 
.thumb_func 
.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr 
.thumb_func 
.globl GET32 
GET32: 
    ldr r0,[r0] 
    bx lr 
.thumb_func 
.globl dummy 
dummy: 
    bx lr 
.end 

sram.ld

MEMORY 
{ 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 
SECTIONS 
{ 
    .text : { *(.text*) } > ram 
    .rodata : { *(.rodata*) } > ram 
    .data : { *(.data*) } > ram 
    .bss : { *(.bss*) } > ram 
} 

notmain을 sram.s.C

void PUT32 (unsigned int, unsigned int); 
unsigned int GET32 (unsigned int); 
void dummy (unsigned int); 
#define STK_CSR 0xE000E010 
#define STK_RVR 0xE000E014 
#define STK_CVR 0xE000E018 
#define STK_MASK 0x00FFFFFF 
int delay (unsigned int n) 
{ 
    unsigned int ra; 
    while(n--) 
    { 
     while(1) 
     { 
      ra=GET32(STK_CSR); 
      if(ra&(1<<16)) break; 
     } 
    } 
    return(0); 
} 
int notmain (void) 
{ 
    unsigned int rx; 
    PUT32(STK_CSR,4); 
    PUT32(STK_RVR,1000000-1); 
    PUT32(STK_CVR,0x00000000); 
    PUT32(STK_CSR,5); 
    for(rx=0;;rx++) 
    { 
     dummy(rx); 
     delay(50); 
     dummy(rx); 
     delay(50); 
    } 
    return(0); 
} 

메이크

#ARMGNU ?= arm-none-eabi 
ARMGNU ?= arm-linux-gnueabi 

AOPS = --warn --fatal-warnings -mcpu=cortex-m0 
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 


all : notmain.gcc.thumb.flash.bin notmain.gcc.thumb.sram.bin 

clean: 
    rm -f *.bin 
    rm -f *.o 
    rm -f *.elf 
    rm -f *.list 
    rm -f *.bc 
    rm -f *.opt.s 
    rm -f *.norm.s 
    rm -f *.hex 

#--------------------------------- 

flash.o : flash.s 
    $(ARMGNU)-as $(AOPS) flash.s -o flash.o 

sram.o : sram.s 
    $(ARMGNU)-as $(AOPS) sram.s -o sram.o 

notmain.gcc.thumb.o : notmain.c 
    $(ARMGNU)-gcc $(COPS) -mthumb -c notmain.c -o notmain.gcc.thumb.o 

notmain.gcc.thumb.flash.bin : flash.ld flash.o notmain.gcc.thumb.o 
    $(ARMGNU)-ld -o notmain.gcc.thumb.flash.elf -T flash.ld flash.o notmain.gcc.thumb.o 
    $(ARMGNU)-objdump -D notmain.gcc.thumb.flash.elf > notmain.gcc.thumb.flash.list 
    $(ARMGNU)-objcopy notmain.gcc.thumb.flash.elf notmain.gcc.thumb.flash.bin -O binary 

notmain.gcc.thumb.sram.bin : sram.ld sram.o notmain.gcc.thumb.o 
    $(ARMGNU)-ld -o notmain.gcc.thumb.sram.elf -T sram.ld sram.o notmain.gcc.thumb.o 
    $(ARMGNU)-objdump -D notmain.gcc.thumb.sram.elf > notmain.gcc.thumb.sram.list 
    $(ARMGNU)-objcopy notmain.gcc.thumb.sram.elf notmain.gcc.thumb.sram.hex -O ihex 
    $(ARMGNU)-objcopy notmain.gcc.thumb.sram.elf notmain.gcc.thumb.sram.bin -O binary 

당신은 또한 당신이 선호하는 경우이 방법을 사용/시도 할 수 있습니다. 나는 이유가있다. TL, DW. 어느 정도 ST는 당신을위한 유도체를 (모두가 여전히 팔으로 이동해야합니까) 발행 팔 문서 사이

void dummy (unsigned int); 
#define STK_MASK 0x00FFFFFF 
#define STK_CSR (*((volatile unsigned int *)0xE000E010)) 
#define STK_RVR (*((volatile unsigned int *)0xE000E014)) 
#define STK_CVR (*((volatile unsigned int *)0xE000E018)) 
int delay (unsigned int n) 
{ 
    unsigned int ra; 
    while(n--) 
    { 
     while(1) 
     { 
      ra=STK_CSR; 
      if(ra&(1<<16)) break; 
     } 
    } 
    return(0); 
} 
int notmain (void) 
{ 
    unsigned int rx; 
    STK_CSR=4; 
    STK_RVR=1000000-1; 
    STK_CVR=0x00000000; 
    STK_CSR=5; 
    for(rx=0;;rx++) 
    { 
     dummy(rx); 
     delay(50); 
     dummy(rx); 
     delay(50); 
    } 
    return(0); 
} 

. st docs 플러스.

uart 기반 부트 로더가 내장되어 있습니다 (USB 등), 인터페이스가 매우 쉽습니다 ... 내 호스트 코드가 프로그램을 다운로드하는 데 수백 줄의 코드가 필요합니다. 또는 작성 afternoont. YMMV. 당신은 이미 발견이나 핵 보드 중 하나를 가지고 있지 않다면 얻을 수 있습니다. 어쨌든 추천합니다. 다른 stm32 나 다른 비 암 칩을 프로그램하기 위해 디버그 끝을 사용할 수 있습니다 (모든 것이 아니라, openocd가 지원하는 것에 달려 있습니다.) , etc., 그러나 몇몇은) 열성적인 stlink usb dongles보다는 30 % 그들을 위해 얻을 수 있고 당신은 확장 usb 케이블, etc., 등등을 필요로하지 않는다. YMMV. 이미 언급 한 것처럼 openocd 또는 texane stlink와 stlink를 확실히 사용할 수 있습니다.

필자는 외피 부츠를 사용하여 두 가지 예를 제공했는데 하나는 구울 때 openocd를 통해 다운로드하고 다른 방법으로는 구울 수 있지만 플래시를 사용하면 틀림없이 실행하면 시작 주소. 나는이 방법을 선호한다. YMMV.

이 접근법은 HAL 제한 사항이나 요구 사항, 빌드 환경 등에 의해 이식 가능하며 완전히 방해받지 않습니다. 그러나 다양한 방법을 시도해 보는 것이 좋습니다. 이런 베어 메탈은 하나 이상의 st 솔루션과 cmsis 방식을 사용하는 HAL 유형의 베어 메탈입니다. 매년 한 번씩 다시 시도하십시오. 당신이 골랐던 것이 아직도 당신이 좋아하는 것이 있는지보십시오.

이 예제는 전체적으로 많이 사용하지는 않지만 실제로 사용하는 방법을 보여줍니다. armv7m thumb2 확장을 피하기 위해 피질 -m0을 선택했습니다. 이러한 확장 기능이없는 엄지 손가락은 가장 휴대가 간편한 팔 명령 세트입니다. 그래서 코드는 거의 아무것도하지 않지만, 어떤 stm32 cortex-m에서도 systick 타이머를 사용하지 않습니다.

편집

이 함께 당신은 최소한의 비 C 코드 것 링커를 공급하기 위해 무엇을해야와

.

.global _start 
_start: 
.word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 

그리고 이것은 칩 벤더 코어마다 작은 일마다 작은 인터럽트 벡터의 수십 내지 수백이있을 수에 따라 단축된다. 이 경우 재설정 및 정지 라벨은 해당 벡터를 처리하는 C 함수의 이름입니다 (칩 및 코어에 대한 문서에서 벡터가 처리하는 내용을 결정합니다). 첫 번째 벡터는 항상 스택 포인터의 초기화 값입니다. 두 번째는 항상 리셋되고 다음 몇 가지는 공통적인데, 그 다음에는 칩 벤더가 와이어 링하는 코어의 일반적인 인터럽트 핀이므로 칩 공급 업체 문서를 살펴 봐야합니다.

핵심 디자인은 레지스터가 보존되어 있으므로 어셈블리가 약간 필요하지 않습니다. 아무런 부트 스트랩없이 실행하면 .bss가 초기화되지 않고 .data가 초기화되지 않는다고 가정하고 리셋 기능에서 복귀 할 수 없습니다. 실제 구현에서는 데모 테스트에서는 10 번 깜박일 수 있습니다 끝마친).

귀하의 툴체인이이를 수행하는 다른 방법이있을 수 있습니다.모든 툴체인은 어셈블러를 가져야하고 어셈블러는 단어 테이블을 생성 할 수 있기 때문에 언제나 그 옵션이 있습니다. 그러나이 도구에 대한 또 다른 도구와 언어를 만드는 것은 실제로 의미가 없지만 일부 사람들은 필요성을 느낍니다. 툴체인은 _start라는 엔트리 포인트를 필요로하지 않을 수도 있고 엔트리 포인트 이름 요구 사항이 다를 수도 있습니다.

키엘을 사용하는 경우에도 키엘보다 gnu 도구를 사용해보십시오. 쉽게 얻을 수 있으며, 더 많은 지원과 경험이 있어야합니다. 성능이 현명하거나 다른 Kiel과 같이 코드의 "좋은"코드로 생성되지는 않지만 항상 GNU 도구에 대한 도움을 얻을 수 있으므로 뒷주머니에 코드를 포함시켜야합니다.

+0

답장 dwelch에 감사드립니다! 여기 어셈블리 언어를 사용하고있는 것으로 보입니다. 나는 엄지 손가락 지시라고 생각합니다. ARM에서 어셈블리 프로그래밍을하는 것은 완전히 순진합니다. Keil에서는 cortex m3의 코어 헤더 파일, 시스템 시작 파일 (어셈블리로 작성된 유일한 파일), 장치 헤더 및 기타 몇 가지 파일을 포함하는 데 사용했습니다. Makefile과 크로스 컴파일러 (베어 메탈)로 그 파일들을 포함하고 사용할 수 있기를 원합니다. 내가 분명히 자신을 설명하기를 바란다. 어떤 설명이 있는지 물어보십시오. 시간 내 주셔서 다시 한번 감사드립니다. – Navin

+0

예, 플래시에서 부팅 한 경우 cortex-m은 비 C 코드로 필요한 벡터 테이블 (잘 및 링커 스크립트 또는 일종의 명령)입니다. 위의 플래시 코드에서 .word를 사용하는 부분은이 툴체인에 대한 최소값이며 후자의 예에서는 휘발성 포인터 항목을 사용합니다. –

+0

cortex-m은 엄지 전용 기계이며, 전체화 된 암 지시를 지원하지 않습니다. m0, m0 +는 armv6-m이며 thumb 이외에 엄지 2 확장의 수가 적습니다. m3과 m4 및 m7에는 지원하는 엄지 2 확장이 많이 있습니다. Thumb without thumb2는 arm7tdmi에서 현재까지 모든 팔 코어에서 작동하는 유일한 명령어 세트이며 배우기 쉽습니다. –