'Embedded Linux'에 해당되는 글 5건

Embedded Linux/Raspberry Pi

라즈베리파이와 PC에서 개발환경을 꾸미는 방법에는 여러가지가 있다.

보통 ssh, scp나 rsync를 사용하는데, 개인적으로는 RSYNC를 사용하는 방법을 선호한다.

ssh나 scp는 target board(라즈베리파이) 에 소스코드를 보관하고 원격에서 접속해서 소스코드를 수정하는 방식이고, rsync는 target board와 host pc 양쪽에 소스코드를 보관하면서 동기화 하는 방식이다.

(Target board) — (Network) — (Windows 10 PC)

PC에서는 보통 VS Code를 사용해서 editing을 하는데, extentions를 활용해서 개발환경을 더 쉽게 꾸밀 수 있다.

rsync를 선호하는 다른 이유는 예전 프로젝트에서 MIPS 아키텍쳐의 target 보드에서 개발했는데, VS Code extentions의 ssh 가 arm과 x86 계열만 지원했기 때문에 rsync에 익숙해져서이기도 하다.

준비

  • Windows PC
    • WSL(Windows Subsystem for Linux)
    • VS Code

VS Code, WSL 설치

여기서 다룰 내용은 아님. Ubuntu 20-04를 설치함.

WSL에 sshpass 설치

PC에서 라즈베리파이로 rsync로 동기화 하려면 ssh를 기본적으로 사용한다. 때문에 라즈베리파이의 username/password 가 필요하다.

물론 인증서 기반으로 할 수도 있겠지만, VS Code에서 자동으로 동기화 하려니까 어떻게 하는지 모르겠다..

설치 방법은 WSL을 실행한 후에 아래 명령을 입력한다.

$ sudo apt install sshpass
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  sshpass
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 10.5 kB of archives.
After this operation, 30.7 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu focal/universe amd64 sshpass amd64 1.06-1 [10.5 kB]
Fetched 10.5 kB in 1s (10.1 kB/s)
Selecting previously unselected package sshpass.
(Reading database ... 32169 files and directories currently installed.)
Preparing to unpack .../sshpass_1.06-1_amd64.deb ...
Unpacking sshpass (1.06-1) ...
Setting up sshpass (1.06-1) ...
Processing triggers for man-db (2.9.1-1) ...

VS Code에 sync-rsync extension 설치

VS Code에서 rsync를 사용하는 방법은 WSL이나 cygwin 을 설치해야한다.

위에서 WSL을 설치 했다.

settings.json 수정

sync-rsync 연결을 위해서 setting.json에 관련 내용을 추가한다.

{
    "sync-rsync.shell": "sshpass -p \"raspberry\" ssh -p 22",
    "sync-rsync.remote": "pi@<ip-address>:/home/pi/work/",
    "sync-rsync.local": "/mnt/c/workspace/", 
    "sync-rsync.onSave": true, 
    "sync-rsync.onSaveIndividual": true, 
    "sync-rsync.exclude": [ 
           ".vscode", 
           ".git", 
           ".gitignore",
           ], 
     // 파일과 디렉토리의 권한 설정 
     "sync-rsync.chmod": "D2775,F664", 
     "sync-rsync.flags": "rlptv", 
     "sync-rsync.useWSL": true, 
 }

위에 처럼 설정하면 라즈베리파이의 "/home/pi/work/" 디렉토리와 PC의 "/mnt/c/workspace" 를 동기화 할 수 있다.

"/mnt/c/" 는 WSL에서 windows의 C 드라이브를 mount 해 놓은 것이다.

파일 동기화 하기

VS Code에서 작업 디렉토리 "/mnt/c/workspace" 를 오픈한 후에 "F1"을 눌러 command 창을 띄운다.

여기서 sync-rsync를 입력하면 몇가지 기능이 나온다.

  • Sync Remote to Local: target(라즈베리파이)의 파일을 PC로 가져와 동기화 한다.
  • Sync Local to Remote: PC의 파일을 target에 동기화 한다.

자동 동기화

파일을 수정하고 저장(Ctrl+S) 하면 자동으로 동기화가 진행된다.

Embedded Linux/OpenWrt

 

OpenWrt에서 네트워크 응용을 운영하다보면 설정에 의해 네트워크 포트 액세스를 허용/제한 설정을 해야 하는 경우가 있다.

 

firewall 에 rule 추가

SNMP 서비스 액세스를 허용/제한 하기 위해 가장 간단하다고 생각하는 방법은 아래와 같다.

root@OpenWrt:~# uci set firewall.snmp=rule 
root@OpenWrt:~# uci set firewall.snmp.name='reject snmp traffic' 
root@OpenWrt:~# uci set firewall.snmp.src='wan' 
root@OpenWrt:~# uci set firewall.snmp.dest_port='161' 
root@OpenWrt:~# uci set firewall.snmp.target='REJECT' 
root@OpenWrt:~# uci set firewall.snmp.enabled='0' 
root@OpenWrt:~# uci commit

 

위에 명령을 입력하면 firewall에 아래처럼 저장된다.

여기서 사용된 option은 아래와 같다. 특정 ip, port, 날짜 지정 등의 옵션을 사용할 수 있지만 사용 목정에 맞게 심플하게 추가했다.

  • src: "zone name"의 형태로 트래픽 소스 zone을 선택한다. zone 은 network 설정에서 선택한다.
  • dest_port: rule을 적용할 port이다. snmp 서비스 액세스를 제어할 거니까 '161'을 설정
  • target: rule 동작 방법 ("ACCEPT", "REJECT". "DROP", "MARK", NOTRACK") 중 "REJECT" 선택
  • enabled: 이 rule을 사용할지 사용 안할지 선택.

 

위 설정에 의해 enabled가 '1'인 경우 SNMP 포트(161)을 REJECT 하고, enabled가 '0' 인 경우 ACCEPT 하는 rule을 생성했다.

 

방화벽 설정
방화벽 설정 방화벽 설정은 /etc/config/firewall에 있습니다. 개요 OpenWrt는 패킷 필터링, NAT 및 mangling을 위해 netfilter를 사용합니다. UCI 방화벽은 iptables system에서 추상화 된 인터페이스를 제공하여 사용자가 필요한 경우 iptables 규칙을 스스로 제공 할 수있게하면서 가장 일반적인 목적에 맞는 단순한 설정 모델을 제공합니다
https://openwrt.org/ko/docs/guide-user/firewall_configuration#rules

 

 

테스트

먼저, enabled option이 0인 경우 (SNMP ACCEPT)시에는 SNMP 요청에 응답하는 것을 볼 수 있다.

 

root@OpenWrt:~# uci set firewall.snmp.enabled='0' 
root@OpenWrt:~# uci commit 
root@OpenWrt:~# /etc/init.d/firewall reload

 

 

 

이후 SNMP REJECT enable option을 1로 바꾸고 firewall을 reload 하면 SNMP 서비스를 제한할 수 있다.

root@OpenWrt:~# uci set firewall.snmp.enabled='1' 
root@OpenWrt:~# uci commit 
root@OpenWrt:~# /etc/init.d/firewall reload

 

  • SNMP요청에 timeout 발생

 

Embedded Linux/Docker

 

Docker에서 python 스크립트를 실행하려고 한다.

1. Docker에 Python 설치

 

(2021-06-03) 기준으로 python.org 에서 release 된 stable 버전은 3.9.5이다.

때문에 docker hub에서 3.9.5 버전의 alpine 버전을 다운로드 받았다.

https://hub.docker.com/_/python

위 링크에서 TAG를 보고 원하는 버전을 선택하면 된다.

docker pull python:3.9-alpine
  • alpine 버전은 alpine 리눅스 기반으로 제작된 이미지라고 한다.
  • 나중에 알게 되었지만, 라즈베리파이에서는 alpine 버전이 동작하지 않았다.
  • python:3.9-slim 으로 다시 설치함

 

2. Docker에서 Python 스크립트 실행

 

Docker build를 해서 custom 컨테이너를 만들고 Python 스크립트를 실행할 예정이다.

python 스크립트

아래처럼 간단하게 python 코드를 작성한다.

print("python app start")

 

우선 잘 동작하나 테스트.

 

 

Dockerfile 작성

 

FROM python:3.9-slim  WORKDIR /home/pi/work/docker COPY . /home/pi/work/docker  CMD ["python", "app.py"]

처음이라 이것저것 넣고 빼고 테스트를 해보았는데, 위에 4개[FROM, WORKDIR, COPY, CMD]가 기본인 듯 하다.

 

이렇게 작성하면 끝

 

Docker build & Run

 

빌드 명령.

docker build -t test1:v3 .

test1은 컨테이너 이름, v3은 태그명 으로 보면 되겠다. 이렇게 빌드하면 아래처럼 확인된다.

 

실행

docker run test1:v3 .

 

 

  • 라즈베리파이에서 python alpine 버전을 사용했을 경우에는 아래처럼 에러가 발생한다.
pi@raspberrypi:~/work/docker $ docker run python:3.9-alpine Fatal Python error: init_interp_main: can't initialize time Python runtime state: core initialized PermissionError: [Errno 1] Operation not permitted  Current thread 0xb6f4b390 (most recent call first): <no Python frame>

 

검색해보니, alpine 버전은 glibc가 아니라 musl libc를 사용해서 C라이브러리 의존성에 문제가 있을 수 있다고 한다.

https://jadehan.tistory.com/58

'Embedded Linux > Docker' 카테고리의 다른 글

Raspberry pi 4에 Docker 설치  (0) 2021.06.03
Embedded Linux/Docker

 

1. Docker 설치

Docker 설치에는 2가지 방법이 있는 것 같다.

 

  • apt를 사용한 설치.
apt install docker.io

 

  • Docker 설치 스크립트를 사용한 설치https://get.docker.com 에서 docker 설치 스크립트를 다운로드 할 수 있다.
    curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh

 

2. 설치 확인

sudo docker --version

 

3. docker 그룹에 사용자 추가

docker 는 root 권한을 실행되기 때문에 sudo 명령이 필요하다.

sudo 없이 사용하기 위해서 user를 docker 그룹에 추가해준다.

sudo usermod -aG docker $USER
  • 라즈베리파이4에서 ssh로 접속하여 docker를 설치했는데, ssh 재접속을 해야만 docker 그룹에 추가된 것을 확인할 수 있다.

 

4. helloworld 테스트

docker에서 제공하는 helloworld 컨테이너를 https://hub.docker.com 에서 다운 받아 동작을 확인할 수 있다.

docker run hello-world

hello-world는 아래처럼 출력된다.

 

 

 

 

'Embedded Linux > Docker' 카테고리의 다른 글

Docker에서 Python 실행하기  (0) 2021.06.03
Embedded Linux/OpenWrt

 

OpenWrt용 python package를 설치하는 Makefile 만들기

 

  1. 참고:
https://openwrt.org/docs/guide-developer/packages
https://openwrt.org/docs/guide-developer/packages

 

 

openWrt를 빌드 할 때 python 패키지를 추가해서 빌드를 해야하는 경우가 생겼다.

이전에는 python 패키지를 추가할 때 아래처럼 makefile을 만들어서 사용했다.

include $(TOPDIR)/rules.mk


PKG_NAME:=python-flask_socketio
PKG_VERSION:=4.3.2
PKG_RELEASE:=1
PKG_LICENSE:=GPLv3

PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/miguelgrinberg/Flask-SocketIO.git
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz

include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/python/python3-package.mk

define Package/python3-flask_socketio
  SUBMENU:=Python
  SECTION:=lang
  CATEGORY:=Languages
  TITLE:=Python3 flask_socketio
  DEPENDS:=+python3-light +python3-socketio +python3-engineio
  VARIANT:=python3
endef

define Package/python3-flask_socketio/description
Python3 bindings for Unified Configuration Interface.
endef

$(eval $(call Py3Package,python3-flask_socketio))
$(eval $(call BuildPackage,python3-flask_socketio))

 

이렇게 makefile을 만들어서 packages 디렉토리에 추가 해놓으면 OpenWrt 빌드 시에 git에서 코드를 다운받아서 .ipk를 만들고 image에 포함되었다.

 

만약 python 패키지에 dependancies 가 있다면 위와 같은 방식으로 makefile을 만들어 넣은 후에 위 DEPENDS: 에 python 패키지 이름을 추가하는 방식으로 진행했다.

 

이번에도 python 패키지를 추가할 일이 있어서 위와 동일한 방식으로 진행하려다가 에러가 발생했다.

💡
../staging_dir/hostpkg/bin/python3.7: can't open file './setup.py': [Errno 2] No such file or directory

 

위 에러로 검색을 해보니 "setup.py" 는 프로젝트의 빌드, 테스트. 배포에 필요한 정보를 담고 있고 setuptools로 테스트, 빌드, 배포하는 것을 확인했다.

 

그리고 내가 빌드하려던 python 패키지에는 setup.py 파일이 없는 것을 확인했다.

github를 commit log를 보니 특정 commit에는 setup.py 가 있는데 master 에는 없었다.

 

그래서 setup.py를 빌드 디렉토리에 넣고 makefile에 setup.py를 추가하는 내용을 추가했다.

  • 위에서 언급한 commit log에 있던 setup.py는 예전 버전의 문법으로 작성되었는지.. 에러가 발생해서 새로 작성해서 추가했다.

setup.py

import re
import sys
from setuptools import setup


with open('aiosmtplib/__init__.py', 'r') as f:
    version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
                        f.read(), re.MULTILINE).group(1)

setup(
    name='python-aiosmtplib',
    version=version,
    url='http://github.com/cole/aiosmtplib/',
    license='MIT',
    author='Cole Maclean',
    author_email='hi@colemaclean.dev',
    description='asyncio SMTP Client',
    packages=['aiosmtplib'],
    zip_safe=False,
    include_package_data=True,
    platforms='any',
    install_requires=[],
    tests_require=[],
    test_suite='tests',
    classifiers=[
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
        'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
        'Topic :: Software Development :: Libraries :: Python Modules'
    ]
)

 

makefile

define Build/Prepare
  @echo "[APP]: Prepare Build..."
	$(CP) setup.py $(PKG_BUILD_DIR)/
endef

 

이렇게 수정하고 컴파일 해보니 정상적으로 빌드돠고 ipk 파일이 생성되었다.

$ make package/python-aiosmtplib/compile V=s -j1

 

1
블로그 이미지

IoT 개발자 블로그이고 싶다.

1byte