본문 바로가기

Study_Embedded/[오제이 튜브의 임베디드 실전 강의]

[오제이 튜브의 임베디드 실전 강의] 3-1강 개발 환경 구축하기, 4강 Hello!! GPIO!!

728x90

1. 개발 환경 구축

1.1. 개발 환경 구축이란

- 개발을 할 수 있는 환경을 구축하는 준비과정

  • 보통 컴파일 + "Hello World"가 출력되는 상황 + 디버깅이 되는 상황을 환경구축이 완료되었다고 한다
    • 임베디드 분야는 환경 구축이 유난히 어려움
    • 임베디드 계열의 "Hello World" 는 GPIO 제어 : 이번 강의의 목적 

 

1.2. IDE란

- IDE (Integrated Development Environment) : 통합 개발 환경을 의미

  • Coding, Debugging, Compile, 배포 등 프로그램 개발에 관련된 모든 작업을 하나의 프로그램 안에서 처리할 수 있는 환경을 제공하는 Software
  • Ex) Visual Studio, Jupyter
  • IDE = Source code editor + Compiler + Local bulid 자동화 + Debugger
    • Source code editor : 코드를 편집할 수 있는 공간
    • Linux의 경우 VI Editor나 메모장 등에서 코딩 진행 가능
    • Local build 자동화 : 버튼 하나만 누르면 여러 파일로 나눠져있는 코드들을 알아서 합쳐서 build 해줌
      Linux 환경에선 make file 문법을, Android 환경은 gradle debugger를 사용해야 함 
  • 위의 기능들은 모두 별도의 프로그램
  • Linux 환경에서는 make file을 통해 위의 것들을 일일히 다 별도로 사용해야 함
    • Ex) Debugger : GDB
    • Local build 자동화 : make file 생성
    • Compiler : GCC
    • Source code editor : Vi Editor

 

  • 각 언어 및 OS에 따라 대표적인 IDE가 있다 : 각각에 따라 대표적인 IDE가 있음 
  • Ex) JAVA는 Eclipse, Window는 Visual Studio 등
    • Eclipse : JAVA를 기반으로 한 IDE
    • 소스 코드가 오픈되어 있어 그걸 기반으로 Cube IDE가 만들어짐 -> 사용 방법 동일
    • 용량이 크다는 단점이 있다

 

1.2.1 강의 사용 IDE 

  • 이번 강의에서 사용할 IDE는 STM32 Cube IDE

 

- STM32 Cude IDE를 사용하는 이유

  1. 무료 IDE
  2. Eclipse를 써봤다면 편리함
    • STM32 Cube IDE가 Eclipse 기반으로 되어있음
  3. ST 제품은 setting만으로 기본 코드가 완성됨
  4. 기존에 IAR Embedded Workbench for ARM을 사용해보셨는데 유료이고 큰 단점이 있음
    • 유료 (많이 비쌈)
    • 많이 무거움
    • 편집툴이 불편함. Debugging 한번 완료시 다른 모든 파일들이 사라짐
    • Setting으로 자동 완성되는 기능이 없음
  • IAR Embedded Workbench for ARM은 ARM 전용 컴파일러를 제공함
  • 각 컴파일러 마다 같은 코드를 수행해도 어셈블리 코드가 다름 : 고성능을 요할 때 각자 최적화 되어있는 것에 따라 성능이 좌우되는 경우도 있음

 

1.3. STM32CubeIDE 설치

 

STM32CubeIDE - STMicroelectronics

STM32CubeIDE - Integrated Development Environment for STM32, STM32CubeIDE-RPM, STM32CubeIDE-Lnx, STM32CubeIDE-Win, STM32CubeIDE-DEB, STM32CubeIDE-Mac, STMicroelectronics

www.st.com

 

  • 설치 파일 압축 해제 후 실행

 

 

  • 설치 진행 중 'NSIS Error during installation '이라는 Error가 뜨면 Installer의 directory를 C:로 바꿔볼 것

 

 

 

  • J-Link, ST-Link driver 모두 선택

 

설치 완료

 

 

  • Debugger를 따로 설치할 필요가 없음

 

1.3.1 환경 구성

  • STM32CubeIDE 실행
  • 프로젝트를 생성하고 칩 설정 : STM32F103C8T6

폴더 위치 설정. 프로젝트에 따라 폴더를 별도로 구성하려면 체크박스 선택 x

 

  • 위와 같은 Update Job, Workbench 관련 오류 발생
  • 위 경고 문구에 표시된 .lock 파일을 삭제하여 해결
1. .lock 파일

 

 

  • File -> New -> STM32 Project 선택 (좀 오래 기다려야 함)

 

 

  • STM32 Project 창에서 제품 찾기 : Series에서 STM32F1 선택 -> 그 중에서 STM32F103C8T6선택

Project에 사용할 Chip 선택

 

  • 혹은 좌측의 항목들을 통해 Chip을 찾을 수 있다
    • STM32CubeIDE 장점. 이런 편리한 기능이 많음

 

  • Package의 LQFP48은 칩의 형태를 나타냄. 핀의 수는 기준점으로부터 반시계방향으로 셈

 

  • 위의 Datasheet창을 선택하면 해당 칩의 최신 datasheet가 나옴

 

 

  • Project 이름 설정. Options는 아래와 같이 설정

 

 

 

 

  • 각 동작시마다 지정되어있는 설정(layer)을 불러올 것이냐는 질문. Yes 선택
  • Project 생성 완료

 

2. STMCubeIDE 관련

2.1. ioc

ioc 화면. 원래는 코딩으로 일일히 설정해야 하는 것을 위의 Cube IDE에서는 클릭만으로 설정할 수 있다

 

  • STMCubeIDE의 ioc 화면
    • IOC (Inversion Of Control) : 메소드나 객체의 호출을 사용자가 아닌 외부에서 결정하는 것
  • 설정 후 저장(Ctrl + S) 시 위의 설정에 맞는 코드를 자동으로 생성해줌

 

2.2. 코드 작성 관련

  • 코드 작성은 USER CODE BEGIN XXX 과 USER CODE END XXX 사이에 입력
    • Includes, PTD 등의 위치는 상관 없음
  • 그 외 구역에 입력하면 아래 그림처럼 코드 생성시 사라짐

칩 설정 후 코드 생성시 그 외 지역의 코드들은 사라짐

 

2.3. 한글 작성 관련

  • 한글 주석 작성 시 오른쪽처럼 깨질 수 있음

 

3. 프로그래밍 및 Debug

  • ST Link와 보드 연결
  • 전원은 ST Link에만 연결
    • 보드 상의 USB 포트는 추가 전원 포트
    • ST Link에서 공급하는 전원 만으로도 충분히 동작함
  • (연결 사진 추가)

 

  • HAL_init에 breakpoint 삽입 (더블 클릭)
2. HAL

  • 상단의 벌레 모양 버튼 클릭을 통해 Debug 시작

 

  • 위의 창이 뜨면 바로 OK 클릭

 

새로운 버전이 있다는 알림. 아래의 check box 는 선택 X

 

 

firmware 업그레이드가 필요하다는 알림이 뜸

 

3.1. 펌웨어 업데이트 방법

  1. https://www.st.com/en/development-tools/stsw-link004.html#get-software 로 접속한 후 Download latest 클릭.   
    ST-LINK Utility 실행
  2. ST-Link -> Firmware update 선택 -> USB 다시 연결 후 Device Connect, yes를 눌러 firmware update 진행
  3. Debugger Update 완료

 

 

  • Debugger Update 완료 후 SystemClock_cinfig();에 breakpoint를 찍고 debug 실행
  • target이 응답이 없다며 종료됨 : Pin 설정 필요

 

3.2. Pin Setting

- ico 창으로 이동

 

 

- System Core -> SYS 클릭

 

 

- Debug는 Serial Wire, Timebase Source는 SysTick으로 설정 (Debug interface 종류)

  • JTAG (Joint Test Action Group) : 디지털 회로에서 특정 node의 digital 입출력을 위해 Serial 통신 방식으로 output data를 전송하거나 input data를 수신하는 방식
  • 5개의 핀 (TDI, TMS, TCK, NRST, TDO) 사용. 20개의 핀으로 구성되어 있어 보드의 자리를 많이 차지함
    • 제품의 동작 테스트시 핀 마다의 동작을 표준으로 만들어 테스트하기 용이하게 만들어놓은 형태
    • Embedded System의 MCU를 테스트 한다기 보단 Board 자체를 테스트 함
    • Hardware Debugger의 일종으로 사용자가 CPU를 직접 조절하며 Debugging 가능
    • JTAG Interface 구성은 아래와 같다
      1. TDI (Test Data In) : Test를 위한 data 신호. TMS에 의해 전이된 TAP state에 따라 TDI가 Command/Data가 될 수 있음
      2. TDO (Test Data Out) : Test 결과를 외부에서 확인하기 위한 핀. TDI와 마찬가지로 TAP state에 따라 Address/Data가 될 수 있음
      3. TCK (Test Clock) : Test의 Clock 설정
      4. TMS (Test Mode Select) : Test Mode로의 전환을 위한 제어 신호
      5. TRST (Test Reset) : Test 초기화 
  • Serial Wire : Serial(직렬) 통신으로 Clock(SWCLK)과 Data(SWDIO) 2개의 핀만을 사용 
  • HW 개발자들은 Serial Wire를 선호
    • 2개의 Pin만을 사용
    • JTAG은 최소 4개의 Pin 사용 필요

 

- 저장하여 코드 생성

 

3.3. Debug 시작

- while 문 안에 HAL_Delay(100) 작성

  • 100ms를 의미

 

- 상단의 Resume을 눌러 한 breakpoint에서 다음 breakpoint로 이동

  • HAL_Delay(100)에서 계속 머뭄

 

 

  • 위처럼 임베디드 프로그램은 하나의 loop문 (while문) 안에서 계속 돌아간다. 예외로 interrupt는 loop문 바깥에 존재
  • 임베디드 시스템은 OS가 없는 프로그래밍을 함. Thread와는 별개
  • 쓰레드는 누군가 OS를 만들어 준 것이고 그 OS를 기반으로 코딩을 하는 것
    • 쓰레드 (Thread) : 한 program 내에서, 특히 process 내에서 실행되는 흐름의 단위.
      한 program은 환경에 따라 둘 이상의 thread를 동시에 실행할 수 있다

 

4. GPIO 제어

  • GPIO (General Purpose Input/Output) : 사용자의 의도에 따라 입출력이 제어될 수 있는 범용 입출력 포트
    다른 핀들과 달리 특정한 목적이 미리 정의되지 않으며 사용자가 설정하기 전에는 사용이 불가능 하다.
  • 각 포트에는 3개의 레지스터가 있다
    1. DDRx (Portx Data Direction Register) : A ~ G I/O Port의 입/출력 방향 결정. 0은 입력, 1은 출력
    2. PORTx (Portx Data Register) : Portx로 출력할 데이터 저장
    3. PINx (Portx Pin Input Address) : Portx에서 입력받은 데이터 저장

  • 보드 회로도 중 일부. D2의 위치에 있는 LED를 제어하기 위해서는 PC13의 GPIO를 제어해야 한다
  • PC13 : GPIO중 GPIOC의 그룹중 13이라는 번호를 가진 Pin

  • PC13의 GPIO를 Output으로 설정
  • 이후 위 사진과 같이 설정 후 저장
    • 각 설정 별 상세 의미는 다음 강에서 설명
  • User Label을 사용하면 변경사항이 생겼을 때 코드를 일일히 변경할 필요 없이 Label에 해당하는 값만 바꿔주면 된다 

 

  • 이후 main.c에 MX_GPIO_Init(void)가 자동으로 생성됨 (Function Prototype)

 

  • Ctrl + 좌클릭을 하면 function의 정의 부분으로 가서 내부를 볼 수 있다
    • 일일히 코딩해야 하나, ioc를 통해 생성됨

 

  • 이후 while문 내부에 아래 코드 작성

Ctrl + Space bar로 여러 자동 완성 statements를 볼 수 있다

 

  • 위의 statements중 WritePin 선택
HAL_GPIO_WritePin(GPIOx, GPIO_Pin, PinState)
  • GPIOx는 GPIO GROUP을 넣는 자리로, GPIO_LED_GPIO_PortGPIOC를 넣으면 됨
  • GPIO_Pin은 GPIO_LED_Pin 이나 GPIO_PIN_13을 넣음
  • PinState는 Pin의 상태를 설정. 1이 HIGH

  • 위 내용들은 main.h에 정의되어있음
  • 위처럼 User Label을 사용하면 그 Label에 해당하는 값(GPIO_LED)들이 정의가 된다 

 

각 pin들은 HAL Drive에 다 정의가 되어있다

  • uint16_t는 <stdint.h> header에 정의된 data type으로, 모든 platform에서 동일한 bit 수를 사용하도록 설정하기 위해 사용한다
    • C언어에서는 Compiler의 종류나 OS의 차이에 따라 data type의 크기가 변경될 수 있다
    • Memory 관리가 중요한 Embedded 환경에서 주로 사용한다

 

  • 0x2000 : GPIO 13번 Pin을 제어함을 의미

각 주소번지도 정의가 되어있다

 

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  while (1)
  {
	  HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 1);
	  HAL_Delay(100);
	  HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 0);
	  HAL_Delay(100);
  }
}
  • main문 안의 while문에 위처럼 코드 작성
    • GPIO Port의 PC13 Pin의 GPIO를 설정
  • 이후 Debug 실행 -> while 문 내부로 진입
  • D2의 LED가 0.1초 간격으로 깜빡임

(동영상 삽입)

 

 

 

4.1. GPIO를 input으로 설정하여 스위치를 이용해서 LED를 껏다가 켜보기

  • S2 스위치에 input이 들어올 시 D2의 LED에 불이 들어오게 하기   
  • S2 스위치 사용을 위해선 PA0을 GPIO input으로 사용해야 함

 

  • PA0을 GPIO input으로 설정하고 위와 같이 설정 후 저장해서 코드 생성

 

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  while (1)
  {
	  if(!HAL_GPIO_ReadPin(GPIO_SW_GPIO_Port, GPIO_SW_Pin)){
		  HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 0);
	  }
	  else{
		  HAL_GPIO_WritePin(GPIO_LED_GPIO_Port, GPIO_LED_Pin, 1);
	  }

	  HAL_Delay(100);
  }
}

  • main.h에 정의된 코드를 기반으로 while문에 코드 작성

 

  • S2 스위치를 누르면 LED가 점등된다

 

5. etc

5.1. 보드에 전원이 안들어오는 이유 :

  • ST Link를 통해 보드에 주는 전류가 충분하지 않기 때문
  • 해결 방법 : 보드 구성품에 포함되어 있는 USB 연결선으로 보드에 전원을 별도로 준다
  • 주의 : 핀에 5V전원을 동시에 주면 보호회로가 없어 보드가 타버림

 

- Appendix

1. .lock 파일

1.1. 사용 이유

1) Resource Management

  • 한 Program에 대한 다수의 Instance 사용, 여러 사용자가 한 자원에 대해 동시에 접근하는 것을 방지
    • 동시적 접근으로 인한 충돌이나 Data 손실을 방지

2) Indication of Activity

  • 특정 자원이 사용 중임을 나타냄
    • lock 파일이 존재하는 한, Application의 다른 instance들은 해당 자원을 수정하지 말아햐 함을 알게 됨

3) Safe Updates

  • Software update나 설치 시 현재 update 중인 파일의 수정을 방지
    • Update 과정이 다른 동작에 의해 방해받지 않게 함

 

1.2. 동작 과정

1) 설치 & 제거

  • Program이 어떤 자원에 대한 독점적인 접근이 필요한 동작을 수행할 경우, 관련 Directory에 lock file을 생성
    • 해당 동작 완료 시, Program은 lock file을 삭제해야 함

2) .lock file 확인

  • 동작 수행 전 lock file의 존재 여부를 확인
    • lock file이 존재할 경우, 해당 자원이 이미 사용되고 있음을 확인하여 동작을 대기하거나 중단 

3) 관련 오류

  • 일반적으로, 한 자원에 대한 동작을 완료한 후 그에 해당하는 lock file을 삭제해야 함
  • 그런데, Program이 충돌하거나 예상치못하게 종료된 경우, lock file이 삭제되지 않을 수 있음
    • 이는 위와 같은 오류를 유발할 수 있음
    • 이로 인해 파일이 시스템 상에서 "stale lock" 상태로 남아 Program이 해당 자원이 여전히 사용 중이라 여기게 함
    • 자원과 관련된 .lock file을 직접 삭제하여 해결 가능
  • 또는 자원과 관련된 Directory에 .lock file을 생성하거나 제거할 권한이 없는 경우, 오류를 유발할 수 있음
    • Program을 관리자 권한으로 실행하여 해결 가능  

 

2. HAL (Hardware Abstraction Layer)

  • Computer의 물리적인 Hardware와 Computer에서 실행되는 Software 사이의 추상화 계층
  • Hardware의 변화를 감지하여 수많은 종류의 Hardware상에서 별 차이없이 Software가 동작할 수 있도록 함
  • OS의 kernel 또는 장치 드라이버에서 호출
    • OS 단이 아닌 Hardware 공급쪽에서 구현해야 하는 Standard Interface
    • OS에서 하위 수준의 Driver 구현을 고려하지 않아도 되게 해줌
  • 하드웨어(MCU)에 따라 설정을 바꿔줘야 하나, 사용하고자 하는 MCU만 선택하면 관련 설정을 자동으로 수행
  • Hardware의 차이를 숨겨 응용 프로그램이 Hardware에 상관없이 작동할 수 있는 일관된 플랫폼을 제공
    • 구체적으로는 추상화된 API를 통해 응용 프로그램들이 Host System의 Hardware를 발견하고 사용할 수 있게 함
    • API (Application Programming Interface) : Computer나 Software를 서로 연결하는 Interface
      System이 동작하는 방식에 관한 세세한 부분을 숨겨 그 내용들이 변경되더라도 사용자가 계속 사용할 수 있고
      일정한 관리가 가능한 부분만 노출시킨다

API 설명 그림. 출처 : https://blog.wishket.com/api%EB%9E%80-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85-%EA%B7%B8%EB%A6%B0%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8/

  • 즉 API는 서로 다른 프로그램들이 상호 소통이 가능하게 해주는 중간 매개채 역할을 한다

 

  • HAL에서는 하드웨어 부품에 따라 해야 할 복잡한 과정을 일관성 있고, 간략한 인터페이스로 제공하기 위해
    같은 류의 하드웨어를 공통 명령어 집합으로 묶어두는데, 이를 "하드웨어 추상화"라고 함

STM32에서의 HAL의 역할

  • STM32에서의 HAL은 STM32의 어떤 하드웨어라도 쉽게 개발을 할 수 있도록 도와주는 Interface로써 Middleware와 연결이 용이하고 Cube와 연계하여 몇가지 MCU 설정만으로도 기본 Source Code를 자동 생성
    • Middleware : 서로 다른 Application이 서로 통신하는데 사용되는 Software로, 양쪽을 연결하여 data를 주고받을 수 있도록 중간에서 매개체 역할을 하는 Software와 Network를 통해 연결된 여러 개의 컴퓨터에 있는 많은 Process들에게 어떤 서비스를 사용할 수 있도록 연결해주는 Software
    • 응용 프로그램이 OS로부터 제공받는 서비스 외에 추가적으로 이용할 수 있는 서비스를 제공하는 Software

 

2.1. Register Abstraction

  • Pointer로 Register를 직접 제어할 수 있으나, 이는 매번 Register의 주소값을 확인해야 하는 번거로움이 존재함
  • 이를 해결하기 위해 Structure 및 Union을 활용하여 Register Abstraction을 할 수 있다

5강 자료 중 일부

 

3. startup 코드 관련

  • startup_stm... : Start 코드 (어셈블리)

 

  • 위처럼 각 함수가 Mapping 되어있음

 

 

  •  DMA는 인터럽트 함수를 의미
    • 특정 조건에서 발생하는 함수
    • 위의 함수를 stm32f1xx_it.c에 선언해줘야 하나 이도 ioc setting으로 설정 가능

 

 

 


위 내용의 모든 출처는 유튜버 '[오제이 튜브]OJ Tube' 님께 있습니다.

https://www.youtube.com/watch?v=YZJ6RfhuGd0&list=PLz--ENLG_8TNjRg1OtyFBvUyV4PHaKwmu&index=7

https://community.st.com/s/question/0D50X0000Anr4B5SQI/stm32cubeide-nsis-error-during-installation

 

STM32CubeIDE NSIS Error during installation

 

community.st.com

https://blog.wishket.com/api%EB%9E%80-%EC%89%BD%EA%B2%8C-%EC%84%A4%EB%AA%85-%EA%B7%B8%EB%A6%B0%ED%81%B4%EB%9D%BC%EC%9D%B4%EC%96%B8%ED%8A%B8/

 

API란? 비개발자가 알기 쉽게 설명해드립니다! - wishket

여러분은 API가 무엇인지 알고 계신가요? 자주 듣지만 그 개념이 무엇인지 정확하게 알기 쉽지 않은데요. 이번 시간 위시켓이  API란 무엇인지 알기 쉽게 설명해드리고자 합니다. 

blog.wishket.com

https://velog.io/@ketchup0211/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Hardware-Abstraction-Layer-HAL-%EC%9D%B4%EB%9E%80

 

[운영체제] Hardware Abstraction Layer (HAL) 이란?

하드웨어 추상화 계층(Hardware Abstraction Layer)이란, 말 그대로 보자면 하드웨어를 사용하기 위한 abstraction layer이다. 이는 하드웨어의 구체적인 특징 및 복잡한 내부 구조를 감추고, 깔끔하고 일관

velog.io

 

https://velog.io/@actor/%EC%9E%84%EB%B2%A0%EB%94%94%EB%93%9C-OS-%EA%B0%9C%EB%B0%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-Hardware-Abstraction-Layer

 

Hardware Abstraction Layer

HAL이 무엇인지 그리고 레지스터를 어떻게 추상화 하는지 학습하였다. 그리고 이들을 활용하여 HAL UART를 구현하는 과정을 작성하였다.

velog.io

 

https://velog.io/@ketchup0211/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-Hardware-Abstraction-Layer-HAL-%EC%9D%B4%EB%9E%80

 

[운영체제] Hardware Abstraction Layer (HAL) 이란?

하드웨어 추상화 계층(Hardware Abstraction Layer)이란, 말 그대로 보자면 하드웨어를 사용하기 위한 abstraction layer이다. 이는 하드웨어의 구체적인 특징 및 복잡한 내부 구조를 감추고, 깔끔하고 일관

velog.io

 

https://blog.naver.com/wararat/220695063632

 

STM32(CubeMx) HAL 라이브러리를 사용해 보자

STM32시스템에서 스탠다드 페리프 라이브러리를 사용하는 대신 HAL 라이브러리를 사용해 보겠습니다....

blog.naver.com

 

https://ko.wikipedia.org/wiki/%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4_%EC%B6%94%EC%83%81%ED%99%94

 

하드웨어 추상화 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 하드웨어 추상화(hardware abstraction)는 특정 플랫폼의 구체적인 부분과 하드웨어의 자원을 직접 접근을 흉내내는 소프트웨어들의 집합이다. 하드웨어 추상화는

ko.wikipedia.org