みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

raspberrypi3 meta-raspberrypiでuartコンソール

2017/01/18修正

ラズベリーパイ3にシリアルコンソールでログインしたい。

少し古い情報だと、ラズベリーパイ3はオンボードBluetoothの影響で、すこし複雑な設定を行う必要があるとなっているが、最近のラズベリーパイ3向けのカーネルでは、config.txtenable_uart=1とすることで使用できる。

ここではYoctoProjectのmeta-raspberrypiでシリアルコンソールを使用する方法について記述する。

USB-シリアル変換モジュール

最近のPCはシリアルポートを搭載しているものが少ない。、シリアルポートがないPCを使用する場合は、USBポートをシリアルとして使用するためにUSB-シリアル変換を行う必要がある。

今回は秋月電子で購入できる、これ を使用する。

変換モジュールとラズベリーパイ3の接続

秋月の変換モジュールはUSBポートからの給電で動作することができるため、ラズベリーパイとはTXDRXDを接続するだけで使用できる。

変換モジュールのジャンパを次のようにショートさせる。

ジャンパ 接続 説明
J1(3ピン) 1-2間をショート I/O電圧を3.3V
J2(2ピン) ショート USBバスから5Vを給電

これらは購入時そのままのはず。

ラズベリーパイ3との接続を次に示す。

f:id:mickey_happygolucky:20170118001627p:plain

ラズベリーパイ3側の使用ピンを示す。

ピン GPIO 機能
8 GPIO14 UART0_TXD
10 GPIO15 UART0_RXD
14 - GND

GNDはピン14の他にも複数あり、どれに接続してもよいが、接続し忘れると悲しいことになる。

Linuxの作成

今回はmortyブランチで作業する。

ベース環境の取得

$ git clone git://git.yoctoproject.org/poky.git -b morty
$ cd poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

meta-raspberrypiはまだmortyブランチがないのでmasterを使用する。

oe-init-build-envの読み込み

下記を実行する。

$ cd ~/rpi3
$ source poky/oe-init-build-env

これにより、クロスコンパイルに必要な環境変数が設定され、ビルドディレクトリに移動される。

meta-raspberrypiをビルド対象に追加

次のコマンドを実行する。

$ bitbake-layers add-layer ../poky/meta-raspberrypi

local.confの修正

次の行をlocal.confの先頭の方に追加する。

MACHINE ?= "raspberrypi3"
DL_DIR ?= "${HOME}/work/yocto/downloads"

ENABLE_UART = "1"

ENABLE_UART = "1"でシリアルコンソールが有効になる。

bitbakeの実行

$ bitbake rpi-basic-image

SDカードの作成

$ sudo dd if=tmp/deploy/images/raspberrypi3/rpi-basic-image-raspberrypi3.rpi-sdimg of=/dev/sdb bs=40M

/dev/sdbはSDカードのデバイス。環境により変更が必要な場合がある。

動作確認

作成したSDカードをラズベリーパイ3に挿入後、PCのUSBポートと変換モジュールを接続して、PC上でminicomなどを起動する。この時フロー制御は無効にしておくこと。

この状態でラズベリーパイ3に電源を入れるとログイン画面が表示される。

f:id:mickey_happygolucky:20161218111846p:plain

pandocでplantumlを使う

pandocでドキュメントを書いているときにUMLで図を差し込みたいことがある。

UMLを描くためにはいろいろとツールがあるが、テキストから図を生成できるPlantUMLが便利。

PlantUML自体は以前取り上げたことがあるので、導入方法はこちらで。

pandocではフィルタを使えば、plantumlの記法で記述したコードブロックを直接、図に変換することができる。

いろいろと実装が存在するが、今回はここのものを使用する。

ダウンロード

パスが通っている場所にフィルタのスクリプトをダウンロードする。

ここでは~/binとする。

$ cd ~/bin
$ wget https://raw.githubusercontent.com/matthiasbeyer/pandoc-paper-template/master/scripts/plantuml-filter.py
$ chmod +x ./plantuml-filter.py

スクリプトの作成

このフィルタはパスが通っているところにplantumlという名前でPlantUMLが実行できることを想定しているため、ラッパーとなるスクリプト~/bin/plantumlとして作成する。

#!/bin/bash

java -jar plantuml.jar $@

これに実行権限をつける。

$ chmod +x ~/bin/plantuml

図の埋め込み

pandocのマークダウンに次のように記述する。

```{.plantuml}
start

:test;

stop
```

これを試しにtest.mdとして保存する。

変換

これを次のように変換する。

pandoc -F plantuml-filter.py -otest.html test.md

次のような図が生成される。

f:id:mickey_happygolucky:20161209015130p:plain

日本語対応

PlantUMLのコードブロックに日本語が含まれる場合エラーが発生するので、次のように修正した。

--- plantuml-filter.py~  2016-12-09 01:14:35.235721804 +0900
+++ plantuml-filter.py    2016-12-09 01:39:31.432327258 +0900
@@ -12,7 +12,7 @@
 from pandocfilters import toJSONFilter, Str, Para, Image, attributes
 
 def sha1(x):
-  return hashlib.sha1(x).hexdigest()
+  return hashlib.sha1(x.encode('utf-8')).hexdigest()
 
 def out(s):
     sys.stderr.write('\t[PLTUML] ' + s + '\n');
@@ -21,7 +21,7 @@
 
 def pipe(cmd, data):
     p = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
-    p.stdin.write(data)
+    p.stdin.write(data.encode('utf-8'))
     p.stdin.close()
     data = p.stdout.read()
     p.stdout.close()

次のようなコードブロックを変換する。

```{.plantuml}
start

:日本語;

stop
```

すると、次のような図が生成される。

f:id:mickey_happygolucky:20161209015148p:plain

CMakeLists.txt 覚書

2020年に書き直したものはこちら

プロジェクト名の変数化

プロジェクト名を変数化しておくといろいろと便利。set(変数名 値)で変数を定義できる。

cmake_minimum_required(VERSION 2.8)
set(PROJ_NAME hello)

add_executable(${PROJ_NAME}
    ${PROJECT_SOURCE_DIR}/main.cpp
)

C++14有効化

include(CheckCXXCompilerFlag)コンパイラフラグチェックを有効化

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
if(COMPILER_SUPPORTS_CXX14)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
endif()

pkg-configによるモジュールの追加

find_package(PkgConfig)でpkg-configを有効化

# find opengl via pkg-config
find_package(PkgConfig)
pkg_check_modules(OPENCV REQUIRED opencv)
pkg_check_modules(LIBAV REQUIRED libavcodec libavfilter libavformat libavutil libavdevice libavformat libavresample)

この例ではOpenCV関連の変数のプリフィックスOPENCV_となる。インクルードディレクトリはOPENCV_INCLUDE_DIRS、ライブラリはOPENCV_LIBRARIESとしてアクセスできるようになる。

LIBAVのように複数のパッケージをまとめて検索することもできる

インクルードディレクトリの設定

INCLUDE_DIRECTORIESのように変数にパスを設定しておき、include_directoriesで登録する。

# Include directories for this project
set(INCLUDE_DIR
  ${OPENCV_INCLUDE_DIRS}
  ${QT4_INCLUDE_DIRS}
  ${PROJECT_SOURCE_DIR}/include
)

# Add a include files
include_directories("${INCLUDE_DIR}")

ここによると、 次にようにINCLUDE_DIRECTORIES変数に設定することでもできるらしい。

set(INCLUDE_DIRECTORIES
  ${PROJECT_SOURCE_DIR}/../include
)

追加のライブラリ(dll)

LIBRARIESのように変数にライブラリを設定しておき、target_link_librariesで登録する。

set(LIBRARIES
    ${LIBAV_LIBRARIES}
    ${QT4_LIBRARIES}
    -lrt 
    -lpthread)

target_link_libraries(${PROJ_NAME} ${LIBRARIES})

pkg-configの変数や、-lrtのように個別に設定することもできる。

追加のライブラリ(static)

DLLの場合同様にSTATIC_LIBRARIESのように変数に登録しておき、target_link_librariesで登録する。

set(STATIC_LIBRARIES
    ${PROJECT_SOURCE_DIR}/prebuilt_lib/libsdi.a
    ${PROJECT_SOURCE_DIR}/prebuilt_lib/libgdi.a
    jpegdecdrv
)

target_link_libraries(${PROJ_NAME} ${STATIC_LIBRARIES})

ビルド済みのバイナリをリンクする場合は、ライブラリまでのフルパスを書く。

ソースからコンパイルする場合は、jpegdecdrvのようにライブラリ名のみ記述すると、パスの解決などをCMakeがやってくれる。

DLLとスタティックを同時にリンク

DLLとスタティックなライブラリを同時にリンクしたい場合は、次のように同時に設定できる。

target_link_libraries(${PROJ_NAME} ${LIBRARIES} ${STATIC_LIBRARIES})

実行ファイルの生成

CMakeで実行形式を生成したい場合は、add_executable(実行ファイル名 ソースファイル名)で設定する。

# Add a target executable
add_executable(${PROJ_NAME}
    ${PROJECT_SOURCE_DIR}/main.cpp
)

一つのCMakeLists.txtに複数add_executableを書くこともできる。

アセンブラの有効化

add_executableにhello.Sなどアセンブラのソースファイルを登録したい場合は、予め有効化しておく必要がある。

# Enable assembler
enable_language(ASM)

add_executable(${PROJ_NAME}
    ${PROJECT_SOURCE_DIR}/main.c
    ${PROJECT_SOURCE_DIR}/hello.S
)

サブディレクトリの登録

ライブラリなどのサブモジュールを一緒にビルドする場合、1つのCMakeLists.txtに全て定義することもできるが、 従来のMakefileのようにディレクトリごとにCMakeLists.txtを置くこともできる。

その場合はadd_subdirectory(ディレクトリ名)で登録する。

# Add sub-directories
add_subdirectory(libhello)
add_subdirectory(libbye)

スタティックライブラリの生成

スタティックライブラリをビルドする場合はadd_librarySTATICを設定する。

add_library(hello STATIC
    hello.cpp
    hello_func.cpp
)

この例ではlibhello.aが生成される。

CXX_FLAGSの設定

CXX_FLAGSなどの一般的に変数に関してはCMAKE_CXX_FLAGSのように予め定義してある。

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__ARMV8")

meta-raspberrypi + morty + RPi3のcore-image-satoでエラー

2016/11/17 追記 直したって連絡もらいました!んで、直ってました。Thx!!

meta-raspberrypiとmortyでrpi-basic-imageが動いたので、

調子にってcore-image-satoも試してみる。

bitbake core-image-sato
WARNING: Host distribution "Ubuntu-16.10" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.
Loading cache: 100% |############################################| Time: 0:00:00
Loaded 1338 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies
ERROR: Nothing RPROVIDES 'linux-firmware-brcm43430' (but /home/mickey/work/yocto/rpi-morty/poky/meta/recipes-core/packagegroups/packagegroup-base.bb RDEPENDS on or otherwise requires it)
NOTE: Runtime target 'linux-firmware-brcm43430' is unbuildable, removing...
Missing or unbuildable dependency chain was: ['linux-firmware-brcm43430']
NOTE: Runtime target 'packagegroup-base-extended' is unbuildable, removing...
Missing or unbuildable dependency chain was: ['packagegroup-base-extended', 'linux-firmware-brcm43430']
ERROR: Required build target 'core-image-sato' has no buildable providers.
Missing or unbuildable dependency chain was: ['core-image-sato', 'packagegroup-base-extended', 'linux-firmware-brcm43430']

Summary: There was 1 WARNING message shown.
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.

むむむ。

masterブランチもダメだ。。。

meta-raspberrypiのコミットログをみてみると、明らかに怪しそうなコミットがある。

commit 380740d866b5360647fb5980cb8df69f8af814e5
Author: Khem Raj <raj.khem@gmail.com>
Date:   Thu Nov 3 15:26:09 2016 -0700

    linux-firmware_git.bbappend: Delete
    
    OE-core already bumped the base rev on linux-firmware package
    to include the upstreamed version of brcmfmac43430 firmware in
    september via OE-Core commit a0bc732976670810505286ba43feee70e2c812ce
    
    Signed-off-by: Khem Raj <raj.khem@gmail.com>

これをgit revertして再度core-image-satoをbitbakeしたところ、成功した。

一応、質問はしてみてるけど、直してくれるかな?

yocto raspberrypi3でmorty

ちょっと時間が経ってしまったが、yocto 2.2(morty)がリリースされたので、raspberrypi3で動かしてみる。

ベース環境の取得

$ git clone git://git.yoctoproject.org/poky.git -b morty
$ cd poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

meta-raspberrypiはまだブランチがないのでmasterを使用する。

oe-init-build-envの読み込み

下記を実行する。

$ cd ~/rpi3
$ source poky/oe-init-build-env

これにより、クロスコンパイルに必要な環境変数が設定され、ビルドディレクトリに移動される。

meta-raspberrypiをビルド対象に追加

次のコマンドを実行する。

$ bitbake-layers add-layer ../poky/meta-raspberrypi

local.confの修正

次の行をlocal.confの先頭の方に追加する。

MACHINE ?= "raspberrypi3"
DL_DIR ?= "${HOME}/work/yocto/downloads"

動作確認

bitbakeの実行

$ bitbake rpi-basic-image

DISTRO_VERSIONが2.2になっていることがわかる。

Build Configuration:
BB_VERSION        = "1.32.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Ubuntu-16.10"
TARGET_SYS        = "arm-poky-linux-gnueabi"
MACHINE           = "raspberrypi3"
DISTRO            = "poky"
DISTRO_VERSION    = "2.2"
TUNE_FEATURES     = "arm armv7ve vfp thumb neon vfpv4 callconvention-hard cortexa7"
TARGET_FPU        = "hard"
meta              
meta-poky         
meta-yocto-bsp    = "morty:dc8508f609974cc99606b9042bfa7f870ce80228"
meta-raspberrypi  = "master:17a6933adfc7bdf4e7e18dcc9d59e35718620fd4"

Initialising tasks: 100% |################################################################################################| Time: 0:00:14
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 5485 tasks of which 15 didn't need to be rerun and all succeeded.

Summary: There was 1 WARNING message shown.

SDカードの作成

$ sudo dd if=tmp/deploy/images/raspberrypi3/rpi-basic-image-raspberrypi3.rpi-sdimg of=/dev/sdb bs=40M

/dev/sdbはSDカードのデバイス。環境により変更が必要な場合がある。

実行

f:id:mickey_happygolucky:20161115235426j:plain

無事起動した。

yocto meta-raspberrypiでVC4 graphics driverを試す

このように、RaspbianではVC4のgalliumドライバが使用できていたのだが、 最近、meta-raspberrypiでもこの対応が入ったので試してみる。

local.confにMACHINE_FEATURES += "vc4graphics"の行を追加することで、galliumドライバが有効になり、X11環境からOpenGLを使用できるようになる。

これによって、いままで使用できなかった、GLUTやGLFWが使用できるようになる。(かもしれない)

今回はes2gear_x11で歯車を表示するところまで確認する。

ベース環境の取得

$ git clone git://git.yoctoproject.org/poky.git
$ cd poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

特にポリシーはないが、今回はmasterブランチで作業する。

oe-init-build-envの読み込み

下記を実行する。

$ cd ~/rpi3
$ source poky/oe-init-build-env

これにより、クロスコンパイルに必要な環境変数が設定され、ビルドディレクトリに移動される。

meta-raspberrypiをビルド対象に追加

次のコマンドを実行する。

$ bitbake-layers add-layer ../poky/meta-raspberrypi

local.confの修正

次の行をlocal.confの先頭の方に追加する。

MACHINE ?= "raspberrypi3"
MACHINE_FEATURES += "vc4graphics"
IMAGE_INSTALL_append = " mesa-demos"

DL_DIR ?= "${HOME}/work/yocto/downloads"

mesa-demosを追加インストールしているは、歯車を表示するため。

DL_DIRの行は必要はないが、ダウンロードしたファイルを複数のビルドディレクトリから使いまわせるようにするために設定している。

動作確認

bitbakeの実行

今回はX11OpenGLが使用できるようになったかを確かめたいので、core-image-satoを作成する。

$ bitbake core-image-sato

SDカードの作成

$ sudo dd if=./tmp/deploy/images/raspberrypi3/core-image-sato-raspberrypi3.rpi-sdimg of=/dev/sdb bs=40M

/dev/sdbはSDカードのデバイス。環境により変更が必要な場合がある。

実行

Linux起動後、ターミナルを起動しes2gears_x11を実行してみる。

歯車が表示された。

日本語対応のditaaをpandocで使用する

PlantUMLなどでditaaを使用してみたが、ditaaは便利そうなのに日本語が非対応で残念。 しかし、日本語に対応したditaaも存在する。

これをpandocのフィルタと組み合わせて、pandocのマークダウンから直接、日本語ditaaを使用してみる。

作業ディレクト

jarファイルなどパスが通っているところに置かれていれば、どこでも良いと思うが、今回は~/binにパスを通して使用する。

jditaa.jarの入手

$ cd ~/bin
$ wget https://github.com/luozengbin/dot.emacs.d/raw/master/extra/org-ditaa/jditaa.jar

pandoc filter(codeblock-diagrams.pl)の入手

$ cd ~/bin
$ wget https://gist.githubusercontent.com/bpj/5454765371a4e3c1a8354fedced1cc6b/raw/0802b99341be3ca5abb3e1d49b1e6f5f79d367f3/codeblock-diagrams.pl
$ chmod +x ./codeblock-diagrams.pl

フィルタをjditaaに対応するために修正する。

--- codeblock-diagrams.pl~   2016-10-31 11:20:08.963133308 +0900
+++ codeblock-diagrams.pl 2016-10-31 11:21:13.333003211 +0900
@@ -93,7 +93,7 @@ my %ditaa;
 {
     my $loc = dirname(abs_path($0));
     my $home = abs_path($ENV{HOME});
-    my %jar = (png => "ditaa0_6b.jar", pdf => "DitaaEps.jar");
+    my %jar = (png => "jditaa.jar");
     JAR:
     while ( my($fmt, $name) = each %jar ) {
         PATH:

Pandoc::Elemntsの入手

$ cpan install Pandoc::Elements

実行コマンド

次のように使用する。

$ pandoc -F codeblock-diagrams.pl [-M dia_format=pdf|png] [PANDOC-OPTIONS] [FILE-NAME ...]

実行例

サンプル

```{.ditaa .no-separation scale=1.2 .fig_}

    +----------+      +--------+     +--------+  +-----+  +-----+  +-----+
    |          |      |        |     |        |  |     |  |     |  |     |
    | markdown |----->| pandoc |---->| output |  | img |  | img |  | img |
    | {d}      |      |        |     | {d}    |  | {d} |  | {d} |  | {d} |
    |          |      +--------+     |        |  |     |  |     |  |     |
    +----------+         |  ^        +--------+  +-----+  +-----+  +-----+
                         v  |                       ^        ^        ^ 
                      +--------+   +--------+       |        |        |     
                      |        |-->| ditaa  |-------+        |        |
                      | filter |   +--------+                |        |
                      |        |-->| dot    |----------------+        |
                      |        |   +--------+                         |
                      |        |-->| rdfdot |-------------------------+
                      +--------+   +--------+
```

次のようになる。

[f:id:mickey_happygolucky:20161101033910p:plain]

日本語

```{.ditaa .no-separation scale=1.0 .fig_}

    +----------+      +--------+     +--------+  +-----+  +-----+  +-----+
    |          |      |        |     |        |  |     |  |     |  |     |
    | マーク   |      |        |     |        |  |     |  |     |  |     |
    | ダウン   |----->| pandoc |---->| output |  | img |  | img |  | img |
    | {d}      |      |        |     | {d}    |  | {d} |  | {d} |  | {d} |
    |          |      |        |     |        |  |     |  |     |  |     |
    +----------+      +--------+     +--------+  +-----+  +-----+  +-----+
                         |  ^                       ^        ^        ^ 
                         v  |                       |        |        |
                      +--------+   +--------+       |        |        |     
                      |        |-->| ditaa  |-------+        |        |
                      | filter |   +--------+                |        |
                      |        |-->| dot    |----------------+        |
                      |        |   +--------+                         |
                      |        |-->| rdfdot |-------------------------+
                      +--------+   +--------+
```

次のようになる。

[f:id:mickey_happygolucky:20161101033916p:plain]

ditaaで絵を書くときはRictyなどの等幅フォントがよい。

「->classes is deprecated. Use [ split ‘ ’, $e->class ] instead」のエラー (2017/06/12 追記)

Ubuntu 16.04.2 LTSでこれを実行すると、当時とはPerlのバージョンが異なっているせいか、上記のようなエラーが発生する。

指示に従って次のように修正する。

--- codeblock-diagrams.pl.old    2017-06-12 23:08:06.907006140 +0900
+++ codeblock-diagrams.pl 2017-06-12 23:24:31.336718744 +0900
@@ -162,7 +162,7 @@ print $document->to_json;
 sub codeblock_dia {
     my($code_block) = @_;
     # 'CodeBlock' eq $code_block->name or return;
-    my($type, @classes) = @{ $code_block->classes };
+    my($type, @classes) = @{ [ split ' ', $code_block->class ] };
     return unless $type;
     return unless $diagramtypes{$type};
     my $kvs = $code_block->attr->[2];

これでエラーが回避できる。