KRW | USD

실시간 마이크로 컨트롤러 기반 애플리케이션의 신속한 개발을 위한 MicroPython

작성자: Jacob Beningo

Digi-Key 북미 편집자 제공

실시간 내장형 시스템은 극단적으로 복잡해지고 있으므로 이제는 복잡한 32비트 마이크로 컨트롤러뿐만 아니라 센서, 알고리즘, 인터넷 프로토콜 및 매우 다양한 최종 사용자 응용 분야까지 심도 있게 이해해야 합니다. 더 짧은 개발 주기 동안 더 많은 기능을 제공해야 하는 개발팀은 설계 속도를 높이면서도 코드를 신제품에 이식할 수 있는 방법을 찾아야 하며, 따라서 통합된 유연한 개발 플랫폼이 필요합니다.

개발 프로세스의 속도를 높일 수 있는 여러 마이크로 컨트롤러별 플랫폼이 존재하지만, 이러한 솔루션의 문제는 개발자가 하나의 마이크로 컨트롤러 제공업체에 종속된다는 점입니다. 한 플랫폼의 소프트웨어를 다른 플랫폼으로 이식하는 작업에는 많은 시간과 비용이 소요될 수 있습니다.

폭넓게 수용되어 탄력을 얻고 있는 차별화된 새로운 솔루션은 낮은 수준의 마이크로 컨트롤러 하드웨어를 Python과 같은 높은 수준의 프로그래밍 언어와 결합하는 것입니다. MicroPython은 그러한 솔루션 중 하나입니다. MicroPython은 다양한 마이크로 컨트롤러 벤더의 부품에서 실행 가능한 오픈 소스 방식의 언어이므로, 개발자는 자신의 필요 사항에 맞추어 즉시 사용할 수 있습니다.

MicroPython.org에서는 Python 3를 간결하고 효율적인 방식으로 구현한 언어가 MicroPython이며, 여기에는 제약이 존재하는 환경의 마이크로 컨트롤러에서 실행하는 데 최적화된 Python 표준 라이브러리의 작은 부분 집합이 포함되어 있다고 설명합니다. MicroPython은 킥스타터 프로젝트로 시작되었으며, 성공적으로 펀딩을 마쳤을 뿐만 아니라 대규모의 추종자가 등장하여 이제는 산업 시스템 및 우주 기반 시스템 등 여러 업계의 프로젝트에서 성공적으로 활용되고 있습니다.

적절한 마이크로 컨트롤러의 선택

MicroPython은 다양한 마이크로 컨트롤러에서 실행되며, 인터프리터를 실행하는 데 충분한 RAM, 플래시 및 처리 성능을 갖춘 추가적인 마이크로 컨트롤러에 MicroPython을 이식하는 데 큰 제약이 없습니다. 그러나 MicroPython을 실행하는 데 사용할 마이크로 컨트롤러를 선택할 때 개발자는 다음과 같은 몇 가지 중요 요구 사항을 살펴보아야 합니다.

  • 플래시 용량: 256kB 이상
  • RAM 용량: 16kB 이상
  • CPU 클록 80MHz 이상

위의 요구 사항은 일반적인 권장 사항이며 개발자는 애플리케이션의 필요 사항에 따라서 그리고 MicroPython 커널을 맞춤화하는 데 할애할 수 있는 시간에 따라서 이러한 요구 사항을 반드시 지킬 필요는 없습니다. 예를 들면, 256kB보다 훨씬 더 적은 플래시 용량을 사용하도록 MicroPython을 수정할 수 있습니다. 이러한 권장 사항은 개발자에게 최적의 환경을 제공하고 애플리케이션 코드의 성장을 위한 여유 공간을 제공하기 위한 것입니다.

MicroPython은 다양한 계열의 마이크로 컨트롤러로 이미 이식되어 왔으며, 이러한 마이크로 컨트롤러는 새 플랫폼으로 이식하거나 이미 지원되는 마이크로 컨트롤러를 선택할 때 좋은 시작점이 될 수 있습니다. MicroPython 소스 코드의 주 디렉터리가 그림 1에 표시되어 있습니다. 이제 MicroPython이 지원하는 다음과 같은 다양한 마이크로 컨트롤러 장치를 소개해 드리겠습니다.

예시적인 폴더 디렉터리 구조 이미지

그림 1: 현재 MicroPython이 지원하는 사용 가능한 마이크로 컨트롤러 플랫폼이 표시된 예시적인 폴더 디렉터리 구조. ARM, CC3200, esp8266, Microchip PIC 및 STM32 등 포함. (이미지 출처: Beningo Embedded Group)

루트 디렉터리에 나열된 각 폴더는 해당 칩 제품군에 대한 일반적인 드라이버 및 지원이 포함된 상위 수준 폴더입니다. 각 폴더 내에는 다양한 개발 기판 또는 프로세서가 존재할 수 있습니다. 예를 들면, stmhal 폴더는 STMicroelectronics의 STM32F429 Discovery Board 및 STM32 IoT Discovery Node (STM32L) 등의 개발 기판과 Adafruit Industries의 STM32F405 pyboard 기판 등을 지원합니다. ESP8266 폴더에는 Adafruit의 ESP8266용 Huzzah 브레이크아웃 기판 및 Feather Huzzah Stack Board에 대한 지원이 포함되어 있습니다.

MicroPython을 실행할 수 있는 개발 기판은 저렴하므로 개발자가 여러 기판을 구매하여 애플리케이션에 필요한 메모리, 스토리지 공간 및 처리 성능을 검토해 보는 것도 좋은 아이디어입니다. 예를 들면, 개발자는 STM32F405 pyboard를 사용하여 개발을 시작한 후 향후의 기능 추가 및 업그레이드를 위해 STM32F429로 전환하여 최종 제품을 개발할 수 있습니다. STM32F429에는 2MB의 플래시, 256kB의 RAM 및 대기 상태가 없는(0-wait-state) 특수한 RAM인 CCM이 포함되어 있습니다.

개발자가 작성하는 MicroPython 애플리케이션 코드는 반드시 마이크로 컨트롤러의 내부 플래시에 저장할 필요가 없습니다. MicroPython 커널은 마이크로 컨트롤러에 있어야 하지만 애플리케이션 코드는 Panasonic의 8GB microSD 카드와 같은 외장 스토리지 매체에 저장할 수 있습니다. 외장 메모리 스토리지 장치를 사용하여 애플리케이션 코드를 저장하는 경우에는 메모리 용량이 더 적은 마이크로 컨트롤러를 사용하여 전체 시스템 비용을 절감할 수 있습니다.

MicroPython의 구동

Adafruit STM32F405 pyboard는 MicroPython이 사전에 설치된 상태로 제공됩니다. 그러나 다른 개발 키트 또는 맞춤형 하드웨어를 사용하는 경우에는 개발자가 MicroPython 소스를 다운로드하고, 대상 기판에 맞추어 소스를 빌드하고, 마이크로 컨트롤러의 플래시에 소프트웨어를 기록해야 합니다. 모든 MicroPython 소스 코드는 GitHub에서 제공하므로 쉽게 구할 수 있습니다. MicroPython을 빌드하기 위한 도구 체인을 설정하고 환경을 구성하려면 개발자는 몇 가지 단계를 따라야 합니다. 아래의 예에서는 STM32F429 Discovery 기반을 위한 MicroPython을 빌드합니다.

먼저, 개발자는 Linux 기반 가상 머신을 생성하거나 네이티브 Linux 설치 환경을 사용해야 합니다. 터미널에서 Linux를 사용할 수 있게 되면 개발자는 다음 명령을 사용하여 ARM 컴파일러 도구 체인을 설치해야 합니다.

sudo apt-get install gcc-arm-none-eabi

 

Linux를 새로 설치한 경우에는 개정 관리 시스템인 git이 설치되어 있지 않을 수도 있습니다. 다음 명령을 사용하여 터미널에서 git을 설치할 수 있습니다.

 

sudo apt-get install git

 

git을 설치한 후에는 터미널에서 다음 명령을 실행하여 저장소의 MicroPython 소스를 확인할 수 있습니다.

 

git clone https://github.com/micropython/micropython.git

이 프로세스는 몇 분 동안 실행될 수 있지만 개발자는 표시되는 시퀀스를 확인해야 합니다(그림 2).

로컬 파일 시스템으로 MicroPython 저장소를 복제하는 과정의 이미지

그림 2: 개발자가 이후에 대상 기판에 맞추어 MicroPython을 빌드하거나 자체적인 애플리케이션을 위해 커널을 맞춤화할 수 있는 로컬 파일 시스템으로 MicroPython 저장소를 복제. (이미지 출처: Beningo Embedded Group)

MicroPython을 로컬 파일 시스템으로 복제한 후에는 해당 디렉터리로 변경한 후 터미널에서 “cd stmhal”을 실행해야 합니다. stmhal 디렉터리에는 STM32 마이크로 컨트롤러용 MicroPython에 대한 makefile이 포함되어 있습니다. 또한, 개발자가 검토할 수 있는 “boards” 폴더에는 현재 지원되는 모든 STM32 기판이 표시되어 있습니다. 이후 개발자는 터미널에서 “boards” 폴더에 위치한 모든 기판을 빌드할 수 있습니다. 예를 들면, 개발자는 다음 명령을 입력하여 STM32F4 Discovery 기판을 빌드할 수 있습니다.

make BOARD=STM32F4DISC

MicroPython을 빌드하는 데는 몇 분이 소요됩니다. 빌드가 진행되는 동안 개발자는 USB를 통해 MicroPython을 마이크로 컨트롤러에 프로그래밍하는 데 사용되는 장치 펌웨어 업데이트(DFU) 도구를 설치해야 합니다. 이 도구는 터미널에 다음 명령을 입력하여 설치할 수 있으며, 한 번만 설치하면 됩니다.

sudo apt-get install dfu-util

MicroPython의 빌드 및 dfu-util의 설치가 완료되면 개발자는 이제 MicroPython을 마이크로 컨트롤러에 로드할 수 있습니다. 개발자는 먼저 마이크로 컨트롤러를 DFU 부트로더 모드로 설정해야 합니다. 플래시의 코드를 실행하는 대신, 리셋 시에 내부 부트로더를 로드할 부트 핀을 설정하면 DFU 부트로더 모드를 설정할 수 있습니다.

마이크로 컨트롤러가 부트로더 모드로 설정되어 있고 USB를 통해 호스트 컴퓨터에 연결된 상태에서 다음 명령을 실행하면 dfu-util을 사용하여 MicroPython을 다운로드할 수 있습니다.

dfu-util -a 0 -d 0483:df11 -D build-STM32F4DISC/firmware.dfu

dfu-util은 컴파일 프로세스에서 출력되는 dfu 파일을 사용합니다. 이 프로세스에서는 마이크로 컨트롤러를 완전히 삭제한 후 다시 프로그래밍하므로 몇 분이 소요될 수 있습니다. 이 프로세스는 아래에 표시된 프로세스와 매우 비슷하게 진행됩니다(그림 3). 도구의 작업이 완료되면 내부 플래시에서 로드하도록 부트 점퍼를 조정해야 합니다. 그 후에는 마이크로 컨트롤러의 전원을 껐다가 켤 수 있습니다. 이제 MicroPython은 대상 마이크로 컨트롤러에서 실행됩니다.

dfu-util을 사용하여 MicroPython을 마이크로 컨트롤러로 로드하는 프로세스의 이미지

그림 3: dfu-util을 사용하여 MicroPython을 마이크로 컨트롤러로 로드하는 프로세스. (이미지 출처: Beningo Embedded Group)

센서와 연결 장치 사이의 인터페이싱

MicroPython과 같은 높은 수준의 프로그래밍 언어를 사용하여 실시간 내장 소프트웨어를 개발할 때의 가장 큰 장점은 기반 하드웨어에 상관없이 소프트웨어를 실행할 수 있다는 점입니다. 따라서 개발자는 pyboard에서 실행하기 위한 MicroPython 스크립트를 개발한 후 스크립트를 거의 또는 전혀 수정하지 않고도 ESP8266 또는 STM32F4 Discovery 기판에서도 스크립트를 실행할 수 있습니다. Bosch Sensortec BMP280 기압계 및 온도 센서를 I2C 버스에 인터페이싱한 후 Microchip Technology RN-42 Bluetooth 모듈을 사용하여 Bluetooth 직렬 링크를 통해 데이터를 송신하는 기본 MicroPython 스크립트가 어떻게 이루어져 있는지 살펴보겠습니다.

BMP280은 I2C 기반 기압계 및 온도 센서이며, I2C 슬레이브 주소의 기본값은 119(십진수)입니다. BMP280을 pyboard에 인터페이싱하는 가장 쉬운 방법은 DFRobotGravity 기판을 사용하는 것이며, 이 기판은 장치에 전력을 쉽게 공급하고 I2C에 액세스할 수 있는 견고한 커넥터를 제공합니다. 개발자는 I2C1 또는 I2C2 버스를 선택하여 Gravity 기판을 연결할 수 있습니다. 기판을 연결한 후의 MicroPython 스크립트 작업은 직관적입니다.

먼저 개발자는 pyb 라이브러리에서 I2C 클래스를 가져와야 합니다. pyb 라이브러리를 사용하면 SPI, I2C 및 UART 등과 같은 마이크로 컨트롤러 주변 장치의 기능에 액세스할 수 있습니다. 주변 장치를 사용하기 전에, 개발자는 주변 장치를 제어하는 데 사용할 수 있는 개체를 생성하기 위해 주변 장치 클래스를 인스턴스화해야 합니다. 주변 장치 클래스를 인스턴스화한 후, 개발자는 주 애플리케이션 루프에 진입하기 전에 장치의 존재를 확인하는 것과 같은 다른 초기화 작업을 실행할 수 있습니다. 이후 주 애플리케이션 코드는 1초에 한 번 센서를 샘플링합니다. 이러한 작업을 실행하는 한 예가 아래에 표시되어 있습니다(코드 목록 1).

Copy

from pyb import I2C

 

GlobalTemp = 0.0

GlobalBarometer = 0.0

 

# Initialize and Instantiate I2C peripheral 2

I2C2 = I2C(2,I2C.MASTER, baudrate=100000)

 

while True:

            SensorSample()

            pyb.delay(1000)

 

def SensorSample():

            #Read the Temperature Data

            TempSample = I2C2.readfrom_mem(119, 0xFA,3)

 

            #Read the Pressure Data

            PressureSample = I2C2.readfrom_mem(119, 0xF7,3)

코드 목록 1: I2C 주변 장치를 초기화한 후 DFRobot Gravity 기판과 커뮤니케이션하여 온도 및 기압계 센서 데이터를 취득하는 MicroPython 스크립트. (코드 출처: Beningo Embedded Group)

센서 데이터를 샘플링한 후 그 데이터를 그대로 유지하는 것은 MicroPython이 개발팀에 제공할 수 있는 강력한 성능을 입증하는 데 그리 유용하지 않습니다. 많은 개발팀은 Bluetooth를 사용하여 센서 장치를 인터넷이나 로컬 센서 허브에 연결하는 데 있어 기술적 어려움을 겪고 있습니다.

Bluetooth 기능을 프로젝트에 추가하는 쉬운 방법 중 하나는 RN-42를 사용하는 것입니다. RN-42는 Bluetooth를 통해 송신해야 하는 UART 데이터를 마이크로 컨트롤러가 단순히 송신하기만 하면 RN-42가 Bluetooth 스택 전체를 처리하는 모드를 제공합니다(그림 4).

MicroPython을 실행하는 pyboard가 UART를 통해 RN-42 Bluetooth 모듈에 연결된 이미지

그림 4: MicroPython을 실행하는 pyboard를 UART를 통해 RN-42 Bluetooth 모듈에 연결. (이미지 출처: Beningo Embedded Group)

Bluetooth 기판을 연결한 후, 개발자는 수신된 센서 데이터를 Bluetooth를 통해 모바일 장치에 전송하여 모바일 장치가 추가적인 분석을 위해 데이터를 저장하거나 클라우드로 전달할 수 있는 매우 단순한 스크립트를 작성할 수 있습니다. 이러한 예시적인 스크립트가 아래에 표시되어 있습니다(코드 목록 2). 이 예에서, UART1은 115200bps, 8비트 송신, 패리티 비트 없음 및 단일 정지 비트로 구성되어 있습니다.

Copy

from pyb import uart

from pyb import I2C

 

GlobalTemp = 0.0

GlobalBarometer = 0.0

 

# Initialize and Instantiate I2C peripheral 2

I2C2 = I2C(2,I2C.MASTER, baudrate=100000)

 

# Configure Uart1 for communication

Uart1 = pyb.UART(1,115200)

Uart1.init(115200, bits=8, parity=None, stop=1)

 

while True:

            SampleSensor()

            pyb.delay(1000)

 

def SensorSample():

            #Read the Temperature Data

            TempSample = I2C2.readfrom_mem(119, 0xFA,3)

 

            #Read the Pressure Data

            PressureSample = I2C2.readfrom_mem(119, 0xF7,3)

 

            #Convert Sample data to string

            data = “#,temperature=”str(TempSample)+”,pressure”+str(PressureSample)+”,#,\n\r”

 

            #Write the data to Bluetooth

            Uart1.write(data)

코드 목록 2: UART1을 초기화한 후 외부 장치와 커뮤니케이션하는 예시적인 MicroPython 스크립트 (코드 출처: Beningo Embedded Group)

Python 애플리케이션 코드는 다른 하드웨어 플랫폼으로 쉽게 이식할 수 있을 뿐만 아니라, 애플리케이션은 이미 구현된 공통 라이브러리 및 기능을 사용하므로 개발자는 개발 작업의 속도를 높일 수 있습니다. 소프트웨어의 가장 낮은 수준에서 시작하여 가장 높은 수준까지 작업하는 경우에는 1주일 이상이 소요될 수 있지만 위의 애플리케이션은 1시간 이내에 작성할 수 있습니다.

실시간 소프트웨어의 개발을 위한 유용한 정보

MicroPython을 사용하면 내장형 애플리케이션을 쉽게 개발할 수 있지만, 시스템을 통해 실시간 성능을 얻는 것은 생각만큼 직관적이지 않을 수 있습니다. MicroPython은 코드의 간소화 및 재사용에 대한 큰 장점을 제공하지만, 개발자가 몇 가지 흥미로운 사실 및 라이브러리를 알고 있지 않다면, 예측 가능한 일관적인 타이밍을 시스템으로부터 얻기 어려울 수 있습니다.

MicroPython에는 백그라운드에서 실행되어 힙 및 기타 메모리 자원을 관리하는 가비지 수집기가 포함되어 있습니다. 가비지 수집기는 비결정적이므로 결정적인 행동을 기대하는 개발자는 시간 결정적 섹션에서 가비지 수집기가 실행되기 시작하는 경우에 문제를 겪을 수 있습니다. 이러한 일이 발생하지 않도록 개발자가 따라야 할 몇 가지 권장 사항은 다음과 같습니다.

첫 번째로, 개발자는 가비지 수집 라이브러리인 gc를 가져온 다음, 가비지 수집기가 활성화 및 비활성화되는 때를 제어하기 위한 활성화 및 비활성화 메서드를 사용할 수 있습니다. 아래에 표시된 것과 같이, 개발자는 중요한 섹션이 시작되기 전에 가비지 수집 기능을 비활성화한 다음 해당 섹션 이후에 가비지 수집 기능을 활성화할 수 있습니다(코드 목록 3).

Copy

import gc

 

gc.disable()

 

#My time critical code

 

gc.enable()

코드 목록 3: 시간 결정적 코드 섹션이 시작되기 전의 MicroPython 가비지 수집기 비활성화. (코드 출처: Beningo Embedded Group)

두 번째로, 개발자는 가비지 수집 프로세스를 수동으로도 제어할 수 있습니다. 개발자가 개체를 생성 및 소멸시킬 때, 개체는 힙 기반의 메모리에 할당됩니다. 가비지 수집기가 실행되면 사용되지 않는 공간의 할당이 해제됩니다. 가비지 수집기는 불규칙한 간격으로 이러한 작업을 실행하므로, 개발자는 힙 공간에 가비지가 너무 많지 않도록 가비지 수집을 주기적으로 실행하기 위한 수집 메서드를 사용할 수 있습니다. 이러한 메서드를 실행하면 가비지 수집 실행에 소요되는 시간은 10밀리초에서 1밀리초 미만으로 감소할 수 있습니다. 또한, 가비지 수집을 수동으로 호출하면 개발자의 애플리케이션은 비결정적인 타이밍을 갖는 코드를 제어할 수 있게 됩니다. 이를 통해 개발자는 가비지 수집을 실행할 때를 결정하고 애플리케이션이 실시간 성능을 갖도록 할 수 있습니다.

개발자는 다른 여러 모범 사례를 따라 실시간 코드를 작성할 수도 있습니다. 이러한 모범 사례의 예는 다음과 같습니다.

  • 미리 할당된 버퍼를 커뮤니케이션 채널에 사용
  • 커뮤니케이션용 주변 장치를 사용할 때는 readinto 메서드를 사용
  • Python의 일반적인 주석 기록 방식인 ###을 사용하지 않음
  • 런타임 중의 개체 생성 및 소멸을 최소화
  • 애플리케이션 실행 시간을 모니터링

더 많은 "모범 사례"를 확인하기 원하는 개발자는 여기에서 MicroPython 최적화 문서를 검토해 볼 수 있습니다.

결론

기반 마이크로 컨트롤러에 상관없이 실행 가능한 실시간 내장형 애플리케이션을 구현하고자 하는 개발자에게 MicroPython은 흥미로운 플랫폼입니다. 개발자는 MicroPython에 제공되는 표준 라이브러리를 사용하여 높은 수준의 Python 스크립트를 작성한 후 지원되는 모든 마이크로 컨트롤러에서 스크립트를 실행할 수 있습니다. 이를 통해 개발자는 다음을 포함한 여러 장점을 얻을 수 있습니다.

  • 애플리케이션 재사용 향상
  • 시장 출시 기간 단축
  • 애플리케이션과 하드웨어를 분리

MicroPython이 모든 응용 분야에 적합한 것은 아니지만 신속한 시제품 제작 및 개념 증명을 통해 산업 시스템 및 우주 시스템 응용 분야에서 지금까지 성공적으로 활용되어 왔습니다. 

면책 조항: 이 웹 사이트에서 여러 작성자 및/또는 포럼 참가자가 명시한 의견, 생각 및 견해는 Digi-Key Electronics의 의견, 생각 및 견해 또는 Digi-Key Electronics의 공식 정책과 관련이 없습니다.

작성자 정보

Jacob Beningo

Jacob Beningo는 임베디드 소프트웨어 컨설턴트로서 현재 십여 개국 이상의 국가에 있는 고객들과 협력하여 제품 품질, 비용, 출시 기간을 향상시켜 고객의 비즈니스를 극적으로 변화시키고 있습니다. 그는 인기 있는 강연자이자 기술 교육자이며 임베디드 소프트웨어 개발 기술에 대해 200개 이상의 기사를 발표했습니다. 그는 미시간 대학교 공학 석사 학위를 비롯하여 세 개의 학위를 소지하고 있습니다. 월간 Embedded Bytes 뉴스레터를 수신하려면 jacob@beningo.com 및 Jacob Beningo의 웹 사이트인 www.beningo.com으로 언제든지 문의해 주세요.

게시자 정보

Digi-Key 북미 편집자