2021年8月25日水曜日

Lichee Pi Zeroで無線LANを使いたい ESP8266 その1

Lichee Pi向け?の無線LANモジュールはあるみたいだけど、TELEC取得していないので
普通に使うことはできない。
そこで、気にはなっていたけど使ったことがなかったESPを最近使い始めたので、調子に乗ってLicheePIと接続してみたいと思う。
ESP8266(ESP-WROOM-02D (2MB))

UART1を有効にする

コミニュティの手順書を参考にUART1を有効にする
http://zero.lichee.pro/驱动/UART.html

ブロック図では
http://zero.lichee.pro/入门/board_intro.html#id5

IO-E21、IO-E22の割り当てをUART1に変更できる


dts、dtsiファイルの変更

手順書では、sun8i-v8s.dtsiやsun8i-v3s-licheepi-zero.dtsを書き換える手順になっているが、変更箇所を分離して自分の管理下に置きたかったので、別ファイルに記載することにした。

buildrootの外部ツリーに
board/dts/sun8i-v3s-licheepi-zero-dock-with-lcd.dts
を作成


#include "sun8i-v3s-licheepi-zero-dock.dts"

/ {
	backlight: backlight {
		compatible = "pwm-backlight";
		pwms = <&pwm 0 1000000 0>;
		brightness-levels = <0 30 40 50 60 70 100>;
		default-brightness-level = <6>;
	};

	soc {
		pio: pinctrl@01c20800 {
			uart1_pins_a: uart1@0 {
				pins = "PE21", "PE22";
				function = "uart1";
				bias-pull-up;
			};
		};
	};
};

&pwm {
	pinctrl-names = "default";
	pinctrl-0 = <&pwm0_pins>;
	status = "okay";
};

&uart1 {
	pinctrl-0 = <&uart1_pins_a>;
	pinctrl-names = "default";
	status = "okay";
};

これを読むようにconfigファイルを変更(menu menuconfig)する

BR2_LINUX_KERNEL_CUSTOM_DTS_PATH="$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/dts/sun8i-v3s-licheepi-zero-dock-with-lcd.dts"

dtsとdtbの相互変換

device-tree-compiler が必要

dtsからdtb

#!/bin/bash

LINUX_KERNEL_SRC=output/build/linux-zero-4.14.y
DTS_SRC_FILE=$1
DTB_OUT_FILE=${DTS_SRC_FILE%.*}.dtb

gcc -E -P -x assembler-with-cpp -I $LINUX_KERNEL_SRC/arch/arm/boot/dts -I $LINUX_KERNEL_SRC/include $DTS_SRC_FILE | dtc -I dts -O dtb -i $LINUX_KERNEL_SRC/arch/arm/boot/dts -o $DTB_OUT_FILE

dtbからdts

作成されたdtbが意図したものになっているかを確認する

dtc -I dtb -O dts -o result.dts sun8i-v3s-licheepi-zero-dock-with-lcd.dtb

動作確認

適当なシリアルターミナルをインストールして確認する
今回はminiconにしてみた
uart1をループさせて、入力したものが返ってくるかを確認する

Lichee PiからESP8266のファーム書き込み

ファーム書き換えの毎にPCに接続するのも大変なので、LicheePiから書き込めるようにする

これには、esptool.pyを使用するとできるようだ
流れとしてはVScodeやArduino IDEでコンパイル→生成したバイナリをLicheePIに転送→LicheePiからESP8266を書き換える といった流れ

まずは、Arduinoは作成したファーム(バイナリ)が残らない?ので、残す方法
以下を参考にやってみる
https://www.jh4vaj.com/archives/8548

Arduino IDEの場合

スケッチ→コンパイルしたバイナリを出力



ワークスペースに[〜〜.ino.generic.bin]というファイル名でバイナリが作成される

VScodeの場合

/home/adeno/.arduino15/preferences.txt

build.path=/home/adeno/develop/Arduino/

を追加すると
コンパイル時にここにバイナリを保存しておいてくれる
このときのファイル名は[〜〜.ino.bin]というファイル名でバイナリが生成させる

方法によって、ファイル名が異なるので注意が必要。。

書き込み

esptool.py --port /dev/ttyS1 write_flash 0x0 sketch_mar29a.ino.bin

こんな感じでどーんっ
これで、ようやく環境が出来た、、まだ先は長い



2021年8月18日水曜日

ESP-WROOM-02D(ESP8266)を使ってみる2

本当は、今年の3月くらいにやっていたのだけど、なぜかブログにアップするのを忘れていた。
なんだかなー案件Orz



official AT firmwareでATコマンドを駆使した簡単なhttpリクエストは成功したので
少し調子に乗って、Arduino core for ESP8266 WiFi chipを使って同じようなことをしてみたい。
初めてArduino使うわ。
なので、Arduino環境の構築から。

Arduino環境構築

この手順に従ってやっていく
https://github.com/esp8266/Arduino#installing-with-boards-manager

参考
https://www.indoorcorgielec.com/resources/arduinoide設定/esp-wroom-02搭載製品
https://keijirotanabe.github.io/blog/2017/02/07/esp8266-Arduino-170207/

Arduino IDE

https://www.arduino.cc/en/software

今回は、ディストリビューションのソフトウェア管理からインストールしちゃう。
apt install

後のVScode連携でハマった(IDEの場所をVSCodeから見つけられない)ので、
公式からインストールすることにした。
https://www.arduino.cc/en/Guide/Linux

ボードマネージャーに追加

https://arduino.esp8266.com/stable/package_esp8266com_index.json

HelloWorld

巷のサンプルのままだけど。

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("Hello World");
  delay(1000);
}


これがArduinoかー。わずか3行でこんなことができちゃうんだ。すごい世界観だ。

VSCode

なにやら、VSCodeの拡張機能があるみたい。すてき。
https://github.com/Microsoft/vscode-arduino
https://qiita.com/narikei/items/847613a8f01a9e1527d7#arduinoに書き込む
https://qiita.com/kamata1729/items/10226444bc89e2533e4f

上記を参考に導入。


Arduinoでhttpリクエストしてみる

Arduinoはサンプルコードがいっぱいある。
参考にテストコードを作成

#include <ESP8266WiFi.h>
#include <time.h>

WiFiClient client;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  testRun();
}

void printScanResult(int networksFound)
{
  Serial.printf("%d network(s) found\r\n", networksFound);
  for (int i = 0; i < networksFound; i++)
  {
    Serial.printf("%d: %s, Ch:%d (%ddBm) %s %s\r\n", 
      i + 1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), 
      WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "",WiFi.BSSIDstr(i).c_str());
  }
  Serial.printf("End\r\n");
}

void show_WifiStatus(){
  char result[32];
  switch(WiFi.status()){
    case WL_CONNECTED:
      strcpy(result,"connection is established.");
      break;
    case WL_NO_SSID_AVAIL:
      strcpy(result,"SSID cannot be reached.");
      break;
    case WL_CONNECT_FAILED:
      strcpy(result,"connect failed.");
      break;
    case WL_IDLE_STATUS:
      strcpy(result,"idle.");
      break;
    case WL_DISCONNECTED:
      strcpy(result,"disconnect.");
      break;
    default:
      strcpy(result,"unknown.");
      break;
  }
  Serial.printf("Connection status: %s\r\n",result);
}

void testRun(){
  Serial.printf("Scan AP\r\n");
  delay(100);
  WiFi.scanNetworksAsync(printScanResult);
  
  delay(10000);
  const char ssid[] = "************";
  Serial.printf("Connect AP\r\n");
  show_WifiStatus();
  Serial.printf("Connecting to %s\n", ssid);
  WiFi.begin(ssid, "************");
  show_WifiStatus();
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  show_WifiStatus();
  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  configTzTime("JST-9", "pool.ntp.org", "jp.pool.ntp.org"); 

  delay(10000);

  time_t t;
  struct tm *tm;
  static const char *wd[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};

  t = time(NULL);
  tm = localtime(&t);
  Serial.printf("ESP8266 :  %04d/%02d/%02d(%s) %02d:%02d:%02d\r\n",
        tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
        wd[tm->tm_wday],
        tm->tm_hour, tm->tm_min, tm->tm_sec);

  delay(3000);
  Serial.println("\r\nStarting connection...");
  if (client.connect("httpbin.org", 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /ip HTTP/1.0");
    client.println();

    delay(3000);
    while(client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }

    client.stop();
  }

  WiFi.disconnect();
  delay(3000);
  show_WifiStatus();
}

void loop() {
  delay(500);
}

なんとなく、わかったような。。
久しぶりにCだなぁ。

2021年8月17日火曜日

ESP-WROOM-02D(ESP8266)を使ってみる1

安価に無線LANモジュールを入手出来ないかと模索中。 Lichee Pi Zeroにつなげたいじゃん。
ESP-WROOM-02D https://akizukidenshi.com/catalog/g/gM-13289/とか安いじゃん @360
開発ボード https://www.digikey.jp/product-detail/ja/espressif-systems/ESP8266-DEVKITC-02D-F/1965-1001-ND/9649768

技適も問題なし。


本当は、今年の3月くらいにやっていたのだけど、なぜかブログにアップするのを忘れていた。
なんだかなー。

準備

用意したもの

※フラッシュメモリの容量は2MB

ドキュメント

書き込みツール

  • windowsはESPFlashDownloadTool
  • pythonツールもある[rsptool.py]

SDKなど

技適のメモ

カスタムファームでの技適問題はスイッチサイエンスさんが確認してくれている
https://mag.switch-science.com/2016/01/20/esp-wroom-02_telec/

なので、

ファーム 技適
The official AT firmware (ESP8266_NONOS_SDK) OK
RTOS (ESP8266_RTOS_SDK) OK
Arduino core for ESP8266 WiFi chip OK
MicroPython ?
FreeRTOS https://github.com/aws/amazon-freertos ?

初期ファームで起動・最新バージョンに書き換え

ready
AT+GMR
AT+GMR
AT version:1.6.2.0(Apr 13 2018 11:10:59)
SDK version:2.2.1(6ab97e9)
compile time:Jun  7 2018 19:34:26
Bin version(Wroom 02):1.6.2
OK

Quick Start Guideの手順書通りにファーム書き換え、windowsが必要になったけどね。。
rsptool.py使えば、linuxでもできる気がするけど試していない。

ready
AT+GMR
AT+GMR
AT version:1.7.4.0(May 11 2020 19:13:04)
SDK version:3.0.4(9532ceb)
compile time:May 27 2020 10:12:22
Bin version(Wroom 02):1.7.4
OK

The official AT firmwareでhttpリクエストしてみる

ATコマンドを駆使してhttpリクエストをやってみる
ATコマンドは
https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf
https://www.espressif.com/sites/default/files/documentation/4b-esp8266_at_command_examples_en.pdf
を参考にした

今勉強中のPythonでやってみる
pyserialを使うので

pip3 install pyserial

が必要。

テスト用プログラム

import serial
import threading
import time
import io

busy_flg = False
rcv_flg = True

def _rcv() :
    global busy_flg
    global rcv_flg
    global sio
    while rcv_flg:
        rawline = sio.readline()
        line = rawline.replace("\r","").replace("\n","")
        if (line == "OK") or (line == "SEND OK") :
#            print("Found \"OK\".")
            busy_flg = False
        elif (line == "FAIL") or (line == "ERROR") :
#            print("Found \"FAIL\" or \"ERROR\".")
            busy_flg = False

        if len(line) > 0 :
            print(line)

def _send(data,nocr=False) :
    global busy_flg
    global sio
    while busy_flg == True :
        time.sleep(1)
        print("*")
    busy_flg = True

    print("snd>"+data)
    if nocr:
        sio.write(data)
    else :
        sio.write(data+"\r\n")
    sio.flush()


ser = serial.Serial('/dev/ttyUSB1',115200,timeout=0.5)
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))

rcv_thread = threading.Thread(target=_rcv)
rcv_thread.daemon = True
rcv_thread.start()

try:
    _send(data = "AT+GMR")

    _send(data = "AT+CWMODE=1")     # Station mode 
    _send(data = "AT+CWLAP")        # Lists Available APs
    _send(data = "AT+CWJAP_CUR=\"[ESSID]\",\"[password]\"")        # Connects to an AP

    _send(data = "AT+CIFSR")        # Gets the local IP address 
    _send(data = "AT+CIPSTA?")  

    _send(data = "AT+CIPSNTPCFG=1,9,\"pool.ntp.org\",\"jp.pool.ntp.org\"") # Sets the Configuration of SNTP 
    _send(data = "AT+CIPSNTPTIME?") # Checks the SNTP Time

    _send(data = "AT+CIPSTART=\"TCP\",\"203.137.163.123\",80")        #protocol,server IP and port
    
    http_body="GET / HTTP/1.0\r\n"
    http_body+="\r\n\r\n"
    http_body_length = len(http_body)

    _send(data = "AT+CIPSEND="+str(http_body_length))
    _send(data = http_body,nocr=True)
    time.sleep(10)

    _send(data = "AT+CIPCLOSE")
    _send(data = "AT+CWQAP")        # Disconnects from the AP 

except KeyboardInterrupt:
    print("Bye.")
    

print("Exit.")
busy_flg = False
rcv_flg = False
rcv_thread.join()
ser.close()

やってること

ATコマンドを順に実行している。エラー処理などは未実装。

  1. バージョン表示
  2. ステーションモード(STA)に変更
  3. アクセスポイント(AP)を検索
  4. APに接続
  5. APからもらったIPアドレスなどを表示
  6. NTPサーバーを設定(“pool.ntp.org”,“jp.pool.ntp.org”)
  7. NTPサーバーから時刻を取得
  8. WEBサーバーに接続(今回は、自分のグローバルIPアドレスを確認できるサービス http://ipaddr.show/ のIPを設定[203.137.163.123])
  9. WEBサーバーにリクエスト送信
  10. 10秒待つ
  11. TCPセッション切断
  12. APから切断

実行結果

adeno@drakorange:~/develop/ESP8266$ python3 test.py 
snd>AT+GMR
AT+GMR
AT version:1.7.4.0(May 11 2020 19:13:04)
SDK version:3.0.4(9532ceb)
compile time:May 27 2020 10:12:22
Bin version(Wroom 02):1.7.4
OK
*
snd>AT+CWMODE=1
AT+CWMODE=1
OK
*
snd>AT+CWLAP
AT+CWLAP
*
*
+CWLAP:(4,"****************",-79,"**:**:**:**:**:**",1,5,0,4,4,7,1)
(省略)
OK
*
snd>AT+CWJAP_CUR="SSID","PASSWORD"
AT+CWJAP_CUR="SSID","PASSWORD"
*
*
*
WIFI CONNECTED
*
*
WIFI GOT IP
OK
*
snd>AT+CIFSR
AT+CIFSR
+CIFSR:STAIP,"192.168.1.19"
+CIFSR:STAMAC,"**:**:**:**:**:**"
OK
*
snd>AT+CIPSTA?
AT+CIPSTA?
+CIPSTA:ip:"192.168.1.19"
+CIPSTA:gateway:"192.168.1.1"
+CIPSTA:netmask:"255.255.255.0"
OK
*
snd>AT+CIPSNTPCFG=1,9,"pool.ntp.org","jp.pool.ntp.org"
AT+CIPSNTPCFG=1,9,"pool.ntp.org","jp.pool.ntp.org"
OK
*
snd>AT+CIPSNTPTIME?
AT+CIPSNTPTIME?
+CIPSNTPTIME:Wed Mar 31 06:19:39 2021
OK
*
snd>AT+CIPSTART="TCP","203.137.163.123",80
AT+CIPSTART="TCP","203.137.163.123",80
CONNECT
OK
*
snd>AT+CIPSEND=20
AT+CIPSEND=20
OK
*
snd>GET / HTTP/1.0



> 
Recv 20 bytes
SEND OK
+IPD,133:HTTP/1.0 200 OK
Date: Tue, 30 Mar 2021 21:19:43 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8
***.***.***.***
CLOSED
snd>AT+CIPCLOSE
AT+CIPCLOSE
ERROR
*
snd>AT+CWQAP
Exit.
AT+CWQAP

いい感じ
なんとなく、わかってきた。

2021年8月2日月曜日

GEOのノイキャン付きワイヤレスイヤホンを使ってみる


最近、ストレスのはけ口が物欲に向かっている気がする。イケない傾向だ。。
ツイッターかなんかで、安くて性能もそこそこと評判だったものを、気づいたら手もとにあった。

GRFD-SWE500HT01


ちょっとだけ集中したいときに、ノイキャンあると嬉しいし
マスク外出が増えてきたので、ケーブル付きだとマスクと絡まってうっとおしい。

スペックは
https://geo-online.co.jp/campaign/special/other/geoselection/earphones/swe500ht01.html

プレスリリースには、QCYのGEO専売パッケージって書いてあった。
https://www.geonet.co.jp/news/news2020/20820/



ネットの記事を見ると、CQYのアプリがそのまま使える的なことが書いてあった。
https://watchmono.com/e/geo-swe-ht01-bg-review-check

ほえー割り切っているね。
こういうビジネスが今後どうなるか興味ある。
裾野が広がるんじゃなかと思う。

良い点

  • 件のCQYアプリで、左右のタッチ機能の割当を変更できる
  • 超シンプルなデザイン 主張がないのがとても良い
  • 耳から外すと音楽一時停止する
  • 音楽の音量が小さくても聞こえる気がする(これがノイキャンの効果?)

悪い点

  • レビュー通り高音がサラサラ?している
    プレーヤーの方で調整している人がいた。
  • アプリの通知がうっとおしい
  • アプリの個人情報登録がちょっと抵抗がある
    よくわからないが、個人登録しない状態でも使えている
  • たまーに「ブツッ」という20分に1回くらい。
    出先だと起きない気がするからwifiとの干渉かしら?
  • 結構早めに耳が痛くなる まぁ休憩の目安ということでいいんだけど。

よくわからない点

  • ペアリングは無条件に受け入れ?
    スマホでペアリングしていて、ChromeBookでペアリングできた。これって横取りできるってことけ? ちがった。 スマホと接続になっていないときの話だった。

  • ChromeBookとペアリングして音楽聴きながら、スマホのQCYアプリでノイキャンの切り替えができた
    そういうもんなのか??便利だからいいんだけど。

  • ノイキャンの効果は
    体感できたのは、「アウトドアモード」で風斬り音が弱まった
    ANCで音よりも振動に意識が向くようになった。
    もちろん音も聞こえるんだけど。
    高級なiPodsとかWH-1000XM4だとどんな感じになるんだろうか。気になる。
    これは、沼だ。あぶないあぶない。

  • ハンズフリーは
    まだ試していない。ワイヤレスだと、完全に独り言みたいになるので、ちょっと勇気が出ない。

その他

取説はここに電子がある
https://product.geo-online.co.jp/wp-content/uploads/GRFD-SWE500HT01_manual.pdf

これでしばらくは物欲の虫がおとなしくしてくれるといいのだが。
にしても、マスクのつけ外しやちょっとした動きのときにケーブルを気しないってこんなに快適なんだとびっくりした。

2021年7月25日日曜日

ChromeBookを使ってみる

入手したのは、これ
https://www.asus.com/jp/Laptops/For-Home/Chromebook/ASUS-Chromebook-Detachable-CM3-CM3000/

本当は、この機会にiPadでも良かったんだけど、自分の使用用途を考えたら、こっちのほうがいいような気がした。
物書きしたり、サーバーに接続したり、pdf閲覧して手書きするくらい。
なので、2in1とペン入力が標準でついているCM3が丁度いいと思った。

気づいたら、身の回りものがASUSになっていく

環境構築をメモがてら

セットアップ

googleのアカウントが必要。
特に、ハマるところはない。

マイクラウド環境(NextCloud)への接続

nextcloudアプリと、カレンダー同期用にopensyncを入れた。
スマホのときと変わらず。違和感なし。
大きい画面でカレンダー見れたり。とても便利。

物書き・手書きとして

squidをインストールしてみた。
手書きメモは、絵を書くわけではないので筆圧感知を無効にした。

linux仮想環境

これも試してみたかったやつ。可能性が広がるね。

サーバー接続用

スマホのときはconnecBotを使用していたけど
この環境ではどうしようか。

結果的にはconnectBotを使わなくてもやりたいことができた。

linuxシェルから

ssh -L 3000:localhost:3000 username@servername -p port

で、linuxからもchromeのブラウザからもlocalhost:3000にアクセスできた!
これはとても便利だ。

VS Code

この手順の通り
https://code.visualstudio.com/blogs/2020/12/03/chromebook-get-started

ダウンロードするときに、ARM64のdebパッケージを選択しないとハマる。

日本語化はコマンドパレットから「Configure Display Language」
日本語入力は以下を参考にした
https://gotoblog.org/chromebook-vscode-japanese/

エクステンション

とりあえず

  • MPE Markdown Pereview Enhanced
  • Paste Image

あとは、使い続けて試行錯誤していこう。

git

gitとgit-guiをインストール
こちらもふつーに使えた。嬉しい。


その他

誰か指摘している方がいたが、音量の最小でも大きい。
特にヘッドホン使用時もう少し小さくしたいことがある。
多分なにかやり方あるんだろうけど、まだわからない。

2021年5月8日土曜日

Lichee Pi Zeroで母艦PCとファイル同期させる

あまり手をつけていないが、少しずつやっている
母艦PCとのファイル同期に、開発中はsftpとかで良いんだろうが
例えば、何か作った後に、データを更新させたいといった時
sshはなんか心理的にやだった(何が

フォトフレームとした場合も、写真の更新取得先はdropboxやnextcloudなどクラウドストレージかもしれないし。何かしら同期させる手段が欲しい。

でも個別にサービスに対応させるのはしんどい。
davfs2を最初考えたけど、うまいことマウント出来ずに挫折した。
webdav以外にもつながりたいかもしれないし。
そんなことを悩んでいたら、rcloneというソフトに出会った。

rcloneはすごそう

  • Rclone syncs your files to cloud storage

すごいたくさん対応してるー!
https://rclone.org/#providers

Dropboxもあるし、Google Photos、Nextcloud、webdavなんかもある!
これを導入できれば、スッキリできるかもしれない。

お試し導入してみる

まずはどんなものかを味わうために、ビルド済みのやつを持ってきてみる。
https://rclone.org/downloads/
の[ARMv6 - 32 Bit][linux]というやつ

rclone-v1.54.0-linux-arm.zip

これを展開して、LicheePiに転送。

# ./rclone version
rclone v1.54.0
- os/arch: linux/arm
- go version: go1.15.7

さすが golang すんなり起動するのがすごいね。

対向サーバーは?

さてさて、対向となるサーバーはどうしようかと、あまり手間かけたくないし。
簡易的なwebサーバーで良いんだけど。
なんとなくwebdav使ってみたくて、あれこれ探していたら、wsgidavというソフトに出会った。

https://wsgidav.readthedocs.io/en/latest/index.html
https://qiita.com/Brad-55/items/5b596b76ef7dc1be9a39

インストールはとっても簡単

pip install --upgrade wsgidav

これでOK!
起動もとても簡単!

wsgidav --host=0.0.0.0 --port=8888 --root=/home/adeno/develop/wsgidav --auth=anonymous

これで、とりあえず、認証なしのwebdavサービスが出来上がる。すてき。


 

さて、やってみよう

これもとても簡単
https://rclone.org/webdav/

に従いやっていくだけ

# ./rclone ls chihiro:
1970/01/02 08:10:10 NOTICE: Time may be set wrong - time from "192.168.100.10:8888" is -448164h47m5.409855313s different from this computer
   476690 Screenshot from 2020-04-17 15-46-39.png
   540108 Screenshot from 2020-04-17 15-48-22.png
   272475 chihiro001.jpg
   376802 chihiro002.jpg
   441756 chihiro003.jpg
   297234 chihiro004.jpg
   160027 chihiro005.jpg
   224296 chihiro006.jpg
   276833 chihiro007.jpg
   296495 chihiro008.jpg

おっと、日時設定してなかった。

日時設定

とりあえず手動で

# date --set "2021-02-17 6:00:00"
Wed Feb 17 06:00:00 UTC 2021

あれ、UTCだ。

    BR2_TARGET_TZ_INFO=y
    BR2_TARGET_TZ_ZONELIST="default"
    BR2_TARGET_LOCALTIME="Asia/Tokyo" 

これで、再度ビルドして

# date --set "2021-02-20 19:38:00"
Sat Feb 20 19:38:00 JST 2021

これでOK

NTP導入

手動でうまく行くことがわかったので、今度は自動で調時させたい。

クライアント側

chronyというのを使ってみる。

    BR2_PACKAGE_CHRONY=y

サーバー側

特に何も考えずに、以下を参考に
https://tecadmin.net/setup-time-synchronisation-ntp-server-on-ubuntu-linuxmint/

$ sudo apt install ntp

/etc/ntp.confに追記

restrict 192.168.100.0 mask 255.255.255.0 nomodify notrap

あとはリロード

sudo service ntp reload

ファイアウォールも忘れてはいけない
123/tcpを許可する

実行

# cat /etc/chrony.conf 
server 192.168.100.10
leapsecmode slew
makestep 1.0 3

# /etc/init.d/S49chrony restart
# chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^? 192.168.100.10                3   6     1    30  -18678d[-18678d] +/-  134ms
# chronyc makestep
200 OK
<3分くらい後に>
# date
Mon Feb 22 06:18:51 JST 2021

makestep 1.0 3

により、サービス起動時に1.0秒以上のズレがあった場合には即時調時されるっぽい。

buildrootと連携(rcloneパッケージの作成)

今後も見据えてmenuconfigから選択できるようにしたい。
このあたりを参考に

https://buildroot.org/downloads/manual/manual.html#outside-br-custom
https://buildroot.org/downloads/manual/manual.html#adding-packages

パッケージの追加

構成を考える
br2-externalにて指定している外部ツリー

ex_licheepizerodock

の下にpackageディレクトリを作成してもろもろ置いていく。
今回は思考停止して「rclone」とした。

tabが重要なので、エディタのtab→スペース変換はoffにしないとハマる。

ex_licheepizerodock$ tree
.
├── Config.in
<>
├── external.desc
├── external.mk
├── package
│   └── rclone
│       ├── Config.in
│       └── rclone.mk

Config.inとexternal.mkの変更

Config.inの変更

source "$BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH/package/rclone/Config.in"

external.mkの変更

include $(sort $(wildcard $(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/package/*/*.mk))

package内のConfig.inと.mkの作成

Config.inの作成

config BR2_PACKAGE_RCLONE
    bool "rclone sync"
    help
        Rclone syncs your files to cloud storage

rclone.mkの作成

超絶シンプル。zip展開して、バイナリをコピーするだけ。

################################################################################
#
# Rclone syncs.
#
################################################################################

RCLONE_SOURCE = rclone-current-linux-arm.zip
RCLONE_SITE = https://downloads.rclone.org
RCLONE_LICENSE = MIT
RCLONE_SOURCE_BASENAME = rclone
RCLONE_BIN_NAME = rclone

define RCLONE_EXTRACT_CMDS
	unzip -j $(DL_DIR)/$(RCLONE_SOURCE_BASENAME)/$(RCLONE_SOURCE) -d $(@D)
endef

define RCLONE_INSTALL_TARGET_CMDS
	@echo BR2_PACKAGE_RCLONE_INSTALL_TARGET_CMDS
	$(INSTALL) -D -m 0755 $(@D)/$(RCLONE_BIN_NAME) $(TARGET_DIR)/usr/bin
endef

$(eval $(generic-package))

これでOK!


 

2021年3月21日日曜日

Lichee Pi Zeroのソフト開発環境構築6

ようやくバージョンアップの手段を準備できたので、「ソフト開発環境」の準備の入り口を作りたい。

プログラム作成→実行までを考える

簡単なものとして、シェルスクリプトを作成して、LicheePi側で実行したい場合

VScode

とりあえずこれがPC側に
あとは拡張機能をいくつか

SFTP
SSH FS

LicheePi側

sshサーバー

これが無いと始まらないかな。
軽微な修正時に、シリアルコンソールの出番を減らせるし!

BR2_PACKAGE_DROPBEAR

sftpサーバー

これも、入れておくと、VSCodeから更新が簡単にできる!

BR2_PACKAGE_GESFTPSERVER

これで、プログラム作成からファイル転送、実行までVSCode内で完結できる!素敵!


 

ちょっとしたGUIインターフェースにTck/Tk

なつかしー

BR2_PACKAGE_TK
BR2_PACKAGE_TCL

ちょっとしたGUIが簡単に?できるのは素晴らしいと思う。


 

今は、環境構築すすめているので、詳細は別途まとめる

これで、シェルスクリプトの環境がなんとなく整った。
あとは、必要に応じて入れていこうかな、pythonやc/c++が候補。

Python

Lichee Piのスペックで動くか知らないけど、とりあえず入れてみる。

BR2_PACKAGE_PYTHON3

TKINTERは・・・?
https://sourceforge.net/p/armadeus/code/ci/master/tree/patches/buildroot/2017.02/012-armadeus-add-tkinter-support-to-python.patch
を参考に、書き換えてみた。

patch ../../../package/python3/Config.in < 0001-add-tkinter-support-to-python3_Config.in.patch 
patch ../../../package/python3/python3.mk < 0002-add-tkinter-support-to-python3_python3.mk.patch 
--- Config.in	2020-10-12 21:55:06.000000000 +0900
+++ Config.in	2020-12-28 19:28:44.925240000 +0900
@@ -82,6 +82,18 @@
 	help
 	  _ssl module for Python3 (required for https in urllib etc).
 
+config BR2_PACKAGE_PYTHON3_TKINTER
+	depends on BR2_PACKAGE_XORG7
+	depends on BR2_PACKAGE_TCL
+	select BR2_PACKAGE_TK
+	bool "tkinter"
+	help
+	  Tkinter module for Python3.
+
+comment "tkinter needs a X server and tcl"
+	depends on !BR2_PACKAGE_XORG7
+	depends on !BR2_PACKAGE_TCL
+
 config BR2_PACKAGE_PYTHON3_UNICODEDATA
 	bool "unicodedata module"
 	default y
--- python3.mk	2020-12-28 19:29:41.261031000 +0900
+++ python3.mk	2020-12-28 19:30:25.632867000 +0900
@@ -124,6 +124,12 @@
 PYTHON3_CONF_OPTS += --disable-ossaudiodev
 endif
 
+ifeq ($(BR2_PACKAGE_PYTHON3_TKINTER),y)
+PYTHON_DEPENDENCIES += tk
+else
+PYTHON_CONF_OPTS += --disable-tk
+endif
+
 # Make python believe we don't have 'hg', so that it doesn't try to
 # communicate over the network during the build.
 PYTHON3_CONF_ENV += \
@@ -157,7 +163,6 @@
 	--disable-pydoc \
 	--disable-test-modules \
 	--disable-lib2to3 \
-	--disable-tk \
 	--disable-nis \
 	--disable-idle3 \
 	--disable-pyc-build

これで、menuconfigに

BR2_PACKAGE_PYTHON3_TKINTER
が表示される

buildrootのconfig.inやmkファイルにパッチをあてる方法がよくわからない。
なので、手動でパッチをあてた。

#!/bin/bash


apply(){
    patch ../../../package/python3/Config.in < 0001-add-tkinter-support-to-python3_Config.in.patch 
    patch ../../../package/python3/python3.mk < 0002-add-tkinter-support-to-python3_python3.mk.patch
}

redo(){
    patch -R ../../../package/python3/Config.in < 0001-add-tkinter-support-to-python3_Config.in.patch 
    patch -R ../../../package/python3/python3.mk < 0002-add-tkinter-support-to-python3_python3.mk.patch
}

echo "----------------------------------------"
echo " add tkinter support to python3."
echo "----------------------------------------"
case "$1" in
    apply|redo)
		"$1";;
    *)
		echo "Usage: $0 {apply|redo}"
		exit 1
esac

2021年3月15日月曜日

Lichee Pi Zeroのソフト開発環境構築5

SWupdateを使ってみる(整理2)

結局まだ試行錯誤になっているが、段々と形になってきた。気がする。

ルートパーティションの拡張

ルートパーティションの拡張を、raspiなどを参考にして、初回起動時にいい感じに実施するようにしたい。
https://github.com/Squonk42/buildroot-licheepi-zero-old/wiki/Fresh-image-–-Expand-the-root-partition-and-filesystem
http://nahitafu.cocolog-nifty.com/nahitafu/2019/08/post-2df6c8.html

cat S01resize2fs_once
#!/bin/sh

function get_current_root_device
{
	for i in `cat /proc/cmdline`; do
		if [ ${i:0:5} = "root=" ]; then
			CURRENT_ROOT="${i:5}"
            # /dev/mmcblk0p3
		fi
	done
}

case "$1" in
    start)
        echo "Starting resize2fs_once"
        get_current_root_device
        resize2fs $CURRENT_ROOT &&
        rm /etc/init.d/S01resize2fs_once
        ;;
    *)
        echo "Usage: $0 start" >&2
        exit 3
        ;;
esac

これをex_licheepizerodock/board/rootfs-overlay/etc/init.d/に保存した

usb0のネットワークインターフェースを起動時に有効にする

起動時に固定IPでusb0を有効にしておきたい

cat interfaces
auto lo
iface lo inet loopback

auto usb0
iface usb0 inet static
    address 192.168.100.1
    netmask 255.255.255.0

これをex_licheepizerodock/board/rootfs-overlay/etc/network/に保存した

dhcpサーバーを有効にする

どうしようか悩んだけど、usb刺すたびにPC側でIPアドレスの設定をするのも大変だし
なぜか、毎回違うインターフェースとして認識されるみたいだし。
MACアドレスが毎回ランダムで生成されているみたいだからか。。
このあたりは、まだ興味の対象外なので、hdcpサーバーを入れてしまって楽をしようと思う。

BR2_PACKAGE_BUSYBOX_SHOW_OTHERS
BR2_PACKAGE_DHCP
BR2_PACKAGE_DHCP_SERVER

また、設定ファイルとして

cat dhcpd.conf
option subnet-mask 255.255.255.0;
option routers 192.168.100.1;
subnet 192.168.100.0 netmask 255.255.255.0 {
    range 192.168.100.10 192.168.100.250;
}

をex_licheepizerodock/board/rootfs-overlay/etc/dhcp/に保存した

これで、PCとusbつなぐとネットワークが有効化されるようになった

$ ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=0.246 ms

avahi

まだ、ちゃんと試していないけど、avahiを入れると、host名でアクセスできたり
はたまた、dhcpサーバー建てなくてもローカルリンクアドレスで通信できるようになるみたい。

avahi
IPv4LL network address configuration daemon
mDNS/DNS-SD daemon
libdns_sd compatibility (Bonjour)

IPv4LLがローカルリンクアドレス
mDNSが「host名.local」でのアクセスを可能にする
うーん。どうしようかな。
今は、こういう仕組みがあるという理解だけしておこう。

swupdateのwebサーバーを自動起動させる

init.dにスタートアップはすでにあったので、それを参考に修正する。

/etc/init.d/S80swupdate

にて

/usr/lib/swupdate/swupdate.sh

が呼び出されて、その中で

/etc/swupdate/conf.d and /usr/lib/swupdate/conf.d/

内のファイルを読み込んでいる
なので、/etc/swupdate/conf.d/swupdate.confみたいなファイルを用意しておく

mkdir /swutmp
export TMPDIR=/swutmp
SWUPDATE_ARGS="-p 'reboot'"
SWUPDATE_WEBSERVER_ARGS="--document-root /var/www/swupdate"

これで、起動時からswupdateのwebサービスが動いている
もしも、自動起動させたくないときは、S80swupdateを削除or空ファイルで上書いてしまおうかな。

2021年1月4日月曜日

Lichee Pi Zeroのソフト開発環境構築4

SWupdateを使ってみる(整理)

いろいろ手探りだったので、まとまりがなくなってしまった。
まとめると

パーティションの準備

まずはrootfsを2つ用意する。いわゆる2面持ちをやってみる。
genimage.cfgを修正して、u-boot領域の拡張と、rootfs1、rootfs2を準備した。

#genimage.cfg
image boot.vfat {
	vfat {
		files = {
			"zImage",
			"sun8i-v3s-licheepi-zero-dock-with-lcd.dtb",
			"boot.scr"
		}
	}
	size = 8M
}

image sdcard.img {
	hdimage {
	}

	partition u-boot {
		in-partition-table = "no"
		image = "u-boot-sunxi-with-spl.bin"
		offset = 8192
        size = 679936 #664K 32KB(SPL) + 504KB(Uboot) + Env(128KB)
        #size = 516096 # 512KB - 8192
	}

	partition boot {
		partition-type = 0xC
		bootable = "true"
		image = "boot.vfat"
	}

	partition rootfs1 {
		partition-type = 0x83
		image = "rootfs.ext2"
		size = 200M
	}
	partition rootfs2 {
		partition-type = 0x83
		size = 200M
	}
}

カーネルコンフィング

BR2_PACKAGE_LIBUBOOTENV=y
BR2_PACKAGE_UBOOT_TOOLS=y
BR2_PACKAGE_SWUPDATE=y
BR2_PACKAGE_SWUPDATE_CONFIG="$(BR2_EXTERNAL_LICHEEPI_ZERO_DOCK_EX_PATH)/board/package/swupdate/swupdate.config"
BR2_TARGET_ROOTFS_EXT2_GZIP=y

swupdateの設定は、上記の通り別ファイルに書き出している

swupdate.config

デフォルトからの変更点は

CONFIG_UBOOT=y
CONFIG_UBOOT_FWENV="/etc/fw_env.config"
CONFIG_UBOOT_DEFAULTENV="/etc/u-boot-initial-env"
CONFIG_GUNZIP=y
CONFIG_SHELLSCRIPTHANDLER=y

fw_setenvの準備

linux側からu-boot環境変数の参照と書き換えをするために、/etc/fw_env.configを用意する。

cat ex_licheepizerodock/board/rootfs-overlay/etc/fw_env.config
# device name   Device offset   Env. size
/dev/mmcblk0    0x88000 0x20000

boot.scrの変更

u-boot起動時に、rootfsを切り替えれるように、boot.cmdを変更する

echo -------------------- checking rootfspart ----------
if printenv rootfspart; 
    then echo rootfspart found; 
    else echo rootfspart not found; setenv rootfspart 2; setenv modify_save 1; 
fi

setenv bootargs console=ttyS0,115200 panic=5 console=tty0 rootwait root=/dev/mmcblk0p${rootfspart} earlyprintk rw
load mmc 0:1 0x41000000 zImage
load mmc 0:1 0x41800000 sun8i-v3s-licheepi-zero-dock-with-lcd.dtb

# echo -------------------- printenv --------------------
# printenv
# echo wait 10 sec ...
# sleep 10

echo -------------------- checking modify_save flag -------------------- 
if printenv modify_save; 
    then; 
        if test "${modify_save}" = "1"; 
            then echo modify_save is on.; setenv modify_save 0; saveenv; 
            else echo modify_save is off.;
        fi; 
    else echo modify_save is not found.; 
fi

bootz 0x41000000 - 0x41800000

sw-descriptionの作成

アップデート前後にシェルスクリプトを実行できることがわかったので
書き換え対象のパーティションを自動で切り替えるようにする
http://www.variwiki.com/index.php?title=SWUpdate_Guide
https://sbabic.github.io/swupdate/sw-description.html#scripts
https://translate.google.com/translate?sl=auto&tl=ja&u=https://groups.google.com/g/swupdate/c/26vZgqWNuKY

ただし、「installed-directly = true;」にしていると、プレスクリプトよりも先にファームアップ処理が実施されてしまう仕様みたい。
この一行を削除する。

software =
{
    version = "0.0.2";

        hardware-compatibility: [ "1.0" ];

        images: (
            {
                filename = "rootfs.ext2.gz";
                compressed = "zlib";
                //installed-directly = true;
                device = "/dev/swupdate_rootfs_target";
            }
        );
	    scripts: (
		    {
			    filename = "toggle_partition.sh";
			    type = "shellscript";
		    }
	    );
}

で、スクリプトは

#! /bin/sh

INIT_ACTIVE_PARTITION_NO=2
INIT_STANDBY_PARTITION_NO=3
TARGET_DEVICE_NAME=/dev/swupdate_rootfs_target

echo "======================================"
echo " toggle_partition                     "
echo "======================================"

if [ $# -lt 1 ]; then
    exit 0;
fi


function get_current_root_device
{
	for i in `cat /proc/cmdline`; do
		if [ ${i:0:5} = "root=" ]; then
			CURRENT_ROOT="${i:5}"
            # /dev/mmcblk0p3
		fi
	done
}

function get_update_partition
{
	CURRENT_PARTITION="${CURRENT_ROOT: -1}"
    echo Current Partition is $CURRENT_PARTITION
    UPDATE_PARTITION="$INIT_STANDBY_PARTITION_NO"
	if [ $CURRENT_PARTITION = "$INIT_ACTIVE_PARTITION_NO" ]; then
		UPDATE_PARTITION="$INIT_STANDBY_PARTITION_NO"
	else
		UPDATE_PARTITION="$INIT_ACTIVE_PARTITION_NO"
	fi

    UPDATE_DEVICE_NAME=${CURRENT_ROOT%p?}p$UPDATE_PARTITION
}

function create_symbolic_link
{
    echo Create Symbolic link
    if [ -L $TARGET_DEVICE_NAME ]; then
        echo symbolic link is already exist.
        rm -f $TARGET_DEVICE_NAME
    fi
    ln -s $UPDATE_DEVICE_NAME $TARGET_DEVICE_NAME
    ls -l $TARGET_DEVICE_NAME
}

function delete_symbolic_link
{
    echo Delete Symbolic link
    if [ -L $TARGET_DEVICE_NAME ]; then
        rm -f $TARGET_DEVICE_NAME
    fi
}

function change_active_rootfs_partition
{
    fw_setenv rootfspart $UPDATE_PARTITION
}

get_current_root_device
echo Current ROOT divece is $CURRENT_ROOT
get_update_partition

if [ $1 == "preinst" ]; then
    echo "run pre install script."

    echo SW Update Target Partition is $UPDATE_PARTITION
    echo SW Update Target Device is $UPDATE_DEVICE_NAME
    
    create_symbolic_link
fi

if [ $1 == "postinst" ]; then
    echo "run post install script."

    delete_symbolic_link
    echo "change rootfs partition($CURRENT_PARTITION -> $UPDATE_PARTITION)"
    change_active_rootfs_partition
    echo Partition to be active on reboot is $UPDATE_PARTITION
    
fi

これで、準備ができた。

swuアーカイブを作成する

make後にswuを作成する。

#!/bin/bash

TARGET_DIR=../output/images/
cp sw-description ${TARGET_DIR}
cp toggle_partition.sh ${TARGET_DIR}
cd ${TARGET_DIR}

CONTAINER_VER="1.0.0"
PRODUCT_NAME="my-software"
FILES="sw-description toggle_partition.sh rootfs.ext2.gz"

for i in $FILES;do 
    echo $i;done | cpio -ov -H crc > ${PRODUCT_NAME}_${CONTAINER_VER}.swu

これで、imagesディレクトリにswuファイルが作成される。

アップデートを実行する

# swupdate -v -i /mnt/my-software_1.0.0.swu 
Swupdate v2020.04.0

Licensed under GPLv2. See source distribution for detailed copyright notices.

Registered handlers:
	dummy
	raw
	rawfile
	rawcopy
	shellscript
	preinstall
	postinstall
[TRACE] : SWUPDATE running :  [listener_create] : creating socket at /tmp/swupdateprog
[TRACE] : SWUPDATE running :  [network_initializer] : Main loop Daemon
[TRACE] : SWUPDATE running :  [listener_create] : creating socket at /tmp/sockinstctrl
[TRACE] : SWUPDATE running :  [extract_sw_description] : Found file:
	filename sw-description
	size 432
	checksum 0x6d0c VERIFIED
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.0.2
[TRACE] : SWUPDATE running :  [parse_images] : Found compressed Image: rootfs.ext2.gz in device : /dev/swupdate_rootfs_target for handler raw (installed from stream)
[TRACE] : SWUPDATE running :  [parse_scripts] : Found Script: toggle_partition.sh
[TRACE] : SWUPDATE running :  [cpio_scan] : Found file:
	filename toggle_partition.sh
	size 1947
	REQUIRED
[TRACE] : SWUPDATE running :  [cpio_scan] : Found file:
	filename rootfs.ext2.gz
	size 29271755
	REQUIRED
[DEBUG] : SWUPDATE running :  [preupdatecmd] : Running Pre-update command
[TRACE] : SWUPDATE running :  [extract_next_file] : Copied file:
	filename toggle_partition.sh
	size 1947
	checksum 0x24691 VERIFIED
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] :  toggle_partition                     
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current ROOT divece is /dev/mmcblk0p3
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current Partition is 3
[TRACE] : SWUPDATE running :  [run_system_cmd] : run pre install script.
[TRACE] : SWUPDATE running :  [run_system_cmd] : SW Update Target Partition is 2
[TRACE] : SWUPDATE running :  [run_system_cmd] : SW Update Target Device is /dev/mmcblk0p2
[TRACE] : SWUPDATE running :  [run_system_cmd] : Create Symbolic link
[TRACE] : SWUPDATE running :  [run_system_cmd] : lrwxrwxrwx    1 root     root            14 Jan  6 09:33 /dev/swupdate_rootfs_target -> /dev/mmcblk0p2
[TRACE] : SWUPDATE running :  [run_system_cmd] : /tmp/scripts/toggle_partition.sh preinst  command returned 0
[TRACE] : SWUPDATE running :  [install_single_image] : Found installer for stream rootfs.ext2.gz raw
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] :  toggle_partition                     
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current ROOT divece is /dev/mmcblk0p3
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current Partition is 3
[TRACE] : SWUPDATE running :  [run_system_cmd] : run post install script.
[TRACE] : SWUPDATE running :  [run_system_cmd] : Delete Symbolic link
[TRACE] : SWUPDATE running :  [run_system_cmd] : change rootfs partition(3 -> 2)
[TRACE] : SWUPDATE running :  [run_system_cmd] : Partition to be active on reboot is 2
[TRACE] : SWUPDATE running :  [run_system_cmd] : /tmp/scripts/toggle_partition.sh postinst  command returned 0
Software updated successfully
Please reboot the device to start the new software
[INFO ] : SWUPDATE successful ! 
[DEBUG] : SWUPDATE running :  [postupdate] : Running Post-update command

できたできた!

webUIからアクセス

調子に乗って、WebUIからやってみる。

ifconfig usb0 192.168.100.1
swupdate -v -w "--document-root /var/www/swupdate"


 

しかし、容量不足で失敗Orz

[INFO ] : SWUPDATE started :  Software Update started !
[TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file:
	filename sw-description
	size 389
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.0.2
[TRACE] : SWUPDATE running :  [parse_images] : Found compressed Image: rootfs.ext2.gz in device : /dev/swupdate_rootfs_target for handler raw
[TRACE] : SWUPDATE running :  [parse_scripts] : Found Script: toggle_partition.sh
[DEBUG] : SWUPDATE running :  [preupdatecmd] : Running Pre-update command
[TRACE] : SWUPDATE running :  [extract_files] : Found file:
	filename toggle_partition.sh
	size 1947 required
[TRACE] : SWUPDATE running :  [extract_files] : Found file:
	filename rootfs.ext2.gz
	size 31060334 required
[  513.054095] swupdate invoked oom-killer: gfp_mask=0x14201ca(GFP_HIGHUSER_MOVABLE|__GFP_COLD), nodemask=(null),  order=0, oom_score_adj=0
[  513.066533] CPU: 0 PID: 184 Comm: swupdate Not tainted 4.14.14-licheepi-zero #1
[  513.073837] Hardware name: Allwinner sun8i Family
[  513.078575] [<c010e894>] (unwind_backtrace) from [<c010b548>] (show_stack+0x10/0x14)
[  513.086318] [<c010b548>] (show_stack) from [<c0673428>] (dump_stack+0x88/0x9c)
[  513.093542] [<c0673428>] (dump_stack) from [<c01b1288>] (dump_header.constprop.4+0x94/0x1b8)
[  513.101976] [<c01b1288>] (dump_header.constprop.4) from [<c01b0970>] (oom_kill_process+0x2fc/0x508)
[  513.111013] [<c01b0970>] (oom_kill_process) from [<c01b0e70>] (out_of_memory+0xfc/0x434)
[  513.119097] [<c01b0e70>] (out_of_memory) from [<c01b5430>] (__alloc_pages_nodemask+0x9bc/0xd90)
[  513.127787] [<c01b5430>] (__alloc_pages_nodemask) from [<c01ae318>] (filemap_fault+0x308/0x5dc)
[  513.136480] [<c01ae318>] (filemap_fault) from [<c0284f94>] (ext4_filemap_fault+0x28/0x3c)
[  513.144656] [<c0284f94>] (ext4_filemap_fault) from [<c01d30e0>] (__do_fault+0x18/0x68)
[  513.152568] [<c01d30e0>] (__do_fault) from [<c01d6fbc>] (handle_mm_fault+0x414/0x964)
[  513.160396] [<c01d6fbc>] (handle_mm_fault) from [<c011295c>] (do_page_fault+0x12c/0x36c)
[  513.168481] [<c011295c>] (do_page_fault) from [<c0101370>] (do_PrefetchAbort+0x38/0xa0)
[  513.176478] [<c0101370>] (do_PrefetchAbort) from [<c010c688>] (ret_from_exception+0x0/0x18)
[  513.184815] Exception stack(0xc31adfb0 to 0xc31adff8)
[  513.189862] dfa0:                                     000005b4 00000002 00000000 017b8d3e
[  513.198030] dfc0: b66445ca 00002d0e 000012f2 00000009 b6643278 00000000 b664b344 00000050
[  513.206197] dfe0: 00000000 b6642a18 00014e70 00014e70 00030010 ffffffff
[  513.212882] Mem-Info:
[  513.215175] active_anon:4942 inactive_anon:6094 isolated_anon:0
[  513.215175]  active_file:23 inactive_file:30 isolated_file:0
[  513.215175]  unevictable:0 dirty:0 writeback:0 unstable:0
[  513.215175]  slab_reclaimable:372 slab_unreclaimable:1169
[  513.215175]  mapped:16 shmem:6114 pagetables:84 bounce:0
[  513.215175]  free:231 free_pcp:17 free_cma:0
[  513.247045] Node 0 active_anon:19768kB inactive_anon:24376kB active_file:92kB inactive_file:120kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:64kB dirty:0kB writeback:0kB shmem:24456kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no
[  513.269541] Normal free:924kB min:924kB low:1152kB high:1380kB active_anon:19768kB inactive_anon:24376kB active_file:92kB inactive_file:120kB unevictable:0kB writepending:0kB present:64036kB managed:54536kB mlocked:0kB kernel_stack:464kB pagetables:336kB bounce:0kB free_pcp:68kB local_pcp:68kB free_cma:0kB
[  513.296613] lowmem_reserve[]: 0 0 0
[  513.300103] Normal: 35*4kB (UME) 24*8kB (UE) 13*16kB (UM) 0*32kB 4*64kB (U) 1*128kB (M) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 924kB
[  513.312558] 6169 total pagecache pages
[  513.316311] 0 pages in swap cache
[  513.319622] Swap cache stats: add 0, delete 0, find 0/0
[  513.324837] Free swap  = 0kB
[  513.327722] Total swap = 0kB
[  513.330597] 16009 pages RAM
[  513.333386] 0 pages HighMem/MovableOnly
[  513.337224] 2375 pages reserved
[  513.340361] [ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name
[  513.348898] [   76]     0    76      547        9       5       0        0             0 syslogd
[  513.357685] [   80]     0    80      547        9       4       0        0             0 klogd
[  513.366296] [   91]     0    91     2614       97       6       0        0         -1000 udevd
[  513.374898] [  126]     0   126     5645     1089      10       0        0             0 Xorg
[  513.383424] [  133]     0   133     9203       15       9       0        0             0 swupdate
[  513.392295] [  135]     0   135      547       19       4       0        0             0 startx
[  513.400992] [  136]     0   136      577       22       3       0        0             0 sh
[  513.409342] [  165]     0   165      712       17       4       0        0             0 xinit
[  513.417954] [  166]     0   166     5936     1400      12       0        0             0 X
[  513.426216] [  169]     0   169     3486     2062      10       0        0             0 feh
[  513.434644] [  181]     0   181     9203       36       9       0        0             0 swupdate
[  513.443517] [  183]     0   183     4593       46       5       0        0             0 swupdate
[  513.452389] Out of memory: Kill process 169 (feh) score 147 or sacrifice child
[  513.459637] Killed process 169 (feh) total-vm:13944kB, anon-rss:8240kB, file-rss:8kB, shmem-rss:0kB
[ERROR] : SWUPDATE failed [0] ERROR core/cpio_utils.c : copy_write : 131 : cannot write 16384 bytes: No space left on device
[ERROR] : SWUPDATE failed [1] Image invalid or corrupted. Not installing ...

ならば、容量不足の解消だ

ルートパーティションの拡張

今、ルートパーティションは200Mの領域を確保しているけど、実際には60Mとなっている。
まずは、これを拡張しようと思う。
https://github.com/Squonk42/buildroot-licheepi-zero-old/wiki/Fresh-image-–-Expand-the-root-partition-and-filesystem
http://nahitafu.cocolog-nifty.com/nahitafu/2019/08/post-2df6c8.html

# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                54.1M     52.1M         0 100% /
devtmpfs                 26.1M         0     26.1M   0% /dev
tmpfs                    26.6M         0     26.6M   0% /dev/shm
tmpfs                    26.6M     56.0K     26.6M   0% /tmp
tmpfs                    26.6M    104.0K     26.5M   0% /run

# fdisk -l
Disk /dev/mmcblk0: 3796 MB, 3980394496 bytes, 7774208 sectors
121472 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes

Device       Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
/dev/mmcblk0p1 *  0,21,22     1,26,25           1344      17727      16384 8192K  c Win95 FAT32 (LBA)
/dev/mmcblk0p2    1,26,26     26,152,62        17728     427327     409600  200M 83 Linux
/dev/mmcblk0p3    26,152,63   52,24,36        427328     836927     409600  200M 83 Linux
Disk /dev/mmcblk1: 3807 MB, 3991928832 bytes, 7796736 sectors
2087 cylinders, 83 heads, 45 sectors/track
Units: sectors of 1 * 512 = 512 bytes

resize2fsの有効化

BR2_PACKAGE_E2FSPROGS_RESIZE2FS [=y]

まずは手動で

# resize2fs /dev/mmcblk0p2 
resize2fs 1.45.6 (20-Mar-2020)
Filesystem at /dev/mmcblk0p2 is mounted on /; on-line resizing r[   46.549755] EXT4-fs (mmcblk0p2): resizing filesystem from 61440 to 204800 blocks
equired
old_desc_blocks = 1, new_desc_blocks = 1
[   46.640496] EXT4-fs (mmcblk0p2): resized filesystem to 204800
The filesystem on /dev/mmcblk0p2 is now 204800 (1k) blocks long.

# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root               190.1M     52.4M    128.1M  29% /
devtmpfs                 26.1M         0     26.1M   0% /dev
tmpfs                    26.6M         0     26.6M   0% /dev/shm
tmpfs                    26.6M     56.0K     26.6M   0% /tmp
tmpfs                    26.6M    104.0K     26.5M   0% /run

よし!

手動でスワップ領域を作成

現状

# free -m
              total        used        free      shared  buff/cache   available
Mem:             53          28           2           0          22          23
Swap:             0           0           0

作成

# dd if=/dev/zero of=/swap bs=1M count=128
128+0 records in
128+0 records out
# mkswap /swap 
Setting up swapspace version 1, size = 104853504 bytes
# chmod 0600 /swap
# swapon /swap
[   95.710423] Adding 131052k swap on /swap.  Priority:-2 extents:4 across:143352k SS
# free -m
              total        used        free      shared  buff/cache   available
Mem:             53          28           3           0          21          23
Swap:           127           0         127

再挑戦

[INFO ] : SWUPDATE started :  Software Update started !
[TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file:
	filename sw-description
	size 389
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.0.2
[TRACE] : SWUPDATE running :  [parse_images] : Found compressed Image: rootfs.ext2.gz in device : /dev/swupdate_rootfs_target for handler raw
[TRACE] : SWUPDATE running :  [parse_scripts] : Found Script: toggle_partition.sh
[DEBUG] : SWUPDATE running :  [preupdatecmd] : Running Pre-update command
[TRACE] : SWUPDATE running :  [extract_files] : Found file:
	filename toggle_partition.sh
	size 1947 required
[TRACE] : SWUPDATE running :  [extract_files] : Found file:
	filename rootfs.ext2.gz
	size 31060334 required
[ERROR] : SWUPDATE failed [0] ERROR core/cpio_utils.c : copy_write : 131 : cannot write 16384 bytes: No space left on device
[ERROR] : SWUPDATE failed [1] Image invalid or corrupted. Not installing ...

容量不足はメモリじゃなくて、作業領域のほうか・・・勘違い。

SWupdateが使用するテンポラリ領域

ちゃんと、ドキュメント読もう。 と後悔。
https://sbabic.github.io/swupdate/swupdate.html#streaming-feature

TMPDIRに指定すればいいみたい。

export TMPDIR=/swutmp

再挑戦

[INFO ] : SWUPDATE started :  Software Update started !
[TRACE] : SWUPDATE running :  [extract_file_to_tmp] : Found file:
	filename sw-description
	size 389
[TRACE] : SWUPDATE running :  [get_common_fields] : Version 0.0.2
[TRACE] : SWUPDATE running :  [parse_images] : Found compressed Image: rootfs.ext2.gz in device : /dev/swupdate_rootfs_target for handler raw
[TRACE] : SWUPDATE running :  [parse_scripts] : Found Script: toggle_partition.sh
[DEBUG] : SWUPDATE running :  [preupdatecmd] : Running Pre-update command
[TRACE] : SWUPDATE running :  [extract_files] : Found file:
	filename toggle_partition.sh
	size 1947 required
[TRACE] : SWUPDATE running :  [extract_files] : Found file:
	filename rootfs.ext2.gz
	size 31060334 required
[TRACE] : SWUPDATE running :  [extract_padding] : Expecting 20 padding bytes at end-of-file
[TRACE] : SWUPDATE running :  [network_initializer] : Valid image found: copying to FLASH
[INFO ] : SWUPDATE running :  Installation in progress
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] :  toggle_partition                     
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current ROOT divece is /dev/mmcblk0p2
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current Partition is 2
[TRACE] : SWUPDATE running :  [run_system_cmd] : run pre install script.
[TRACE] : SWUPDATE running :  [run_system_cmd] : SW Update Target Partition is 3
[TRACE] : SWUPDATE running :  [run_system_cmd] : SW Update Target Device is /dev/mmcblk0p3
[TRACE] : SWUPDATE running :  [run_system_cmd] : Create Symbolic link
[TRACE] : SWUPDATE running :  [run_system_cmd] : lrwxrwxrwx    1 root     root            14 Jan 10 13:21 /dev/swupdate_rootfs_target -> /dev/mmcblk0p3
[TRACE] : SWUPDATE running :  [run_system_cmd] : /swutmp/scripts/toggle_partition.sh preinst  command returned 0
[TRACE] : SWUPDATE running :  [install_single_image] : Found installer for stream rootfs.ext2.gz raw
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] :  toggle_partition                     
[TRACE] : SWUPDATE running :  [run_system_cmd] : ======================================
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current ROOT divece is /dev/mmcblk0p2
[TRACE] : SWUPDATE running :  [run_system_cmd] : Current Partition is 2
[TRACE] : SWUPDATE running :  [run_system_cmd] : run post install script.
[TRACE] : SWUPDATE running :  [run_system_cmd] : Delete Symbolic link
[TRACE] : SWUPDATE running :  [run_system_cmd] : change rootfs partition(2 -> 3)
[TRACE] : SWUPDATE running :  [run_system_cmd] : Partition to be active on reboot is 3
[TRACE] : SWUPDATE running :  [run_system_cmd] : /swutmp/scripts/toggle_partition.sh postinst  command returned 0
[INFO ] : SWUPDATE successful ! SWUPDATE successful !

ということで、swapは不要だった。テンポラリ領域の変更だけで済んだ。