Shujima Blog

Apple製品,技術系の話をするブログ

zephyr memoのmemo

Arm LinuxもRTOSも知らない人が理解しようと奮闘した残渣

※ 内容に自信がないので、当記事を論拠とする引用はお控えください。 ※ やってみた的な引用、こう言ってる人もいる的な引用などはOK。

zephyr 2.7.99

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0   DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN    DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS  DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0   ""
#define PIN    0
#define FLAGS  0
#endif

void main(void)
{
    const struct device *dev;
    bool led_is_on = true;
    int ret;

    dev = device_get_binding(LED0);
    if (dev == NULL) {
        return;
    }

    ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
    if (ret < 0) {
        return;
    }

    while (1) {
        gpio_pin_set(dev, PIN, (int)led_is_on);
        led_is_on = !led_is_on;
        k_msleep(SLEEP_TIME_MS);
    }
}

include プリプロセッサ

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

6. #include <zephyr.h>

7. #include <device.h>

8. #include <devicetree.h>

9. #include <drivers/gpio.h>

define プリプロセッサ

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0   DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN    DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS  DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0   ""
#define PIN    0
#define FLAGS  0
#endif

11. #define SLEEP_TIME_MS 1000

よくあるスリープ秒数を決めるやつ。 デフォルトで1000[ms]

13. #define LED0_NODE DT_ALIAS(led0)

Zephyr API Documentation: Existence checks

led0というエイリアスがボードのdtsに存在するか調べて、そのノードidを返す。

Devicetree API — Zephyr Project Documentation

DT_ALIAS()マクロはzephyr/include/devicetree.h内で定義されている。

aaaaaを抽象化するのに役立つ。

エイリアスとは

led0などのほかによく使われるエイリアス名はあるの?

おそらく無い。ボードのdtsも自分達で作る想定だから。 ledだけ例外?

他のチュートリアルファイルを見るとわかるかも。

ボードのdtsとは

今回の場合nucleo-f746のdtsファイル。 dtsはデバイスツリーを記述している。

以下今回の参照先のdtsファイルから一部抜粋

zephyr/nucleo_f746zg.dts at main · zephyrproject-rtos/zephyr · GitHub

 leds { //←てきとうな名前
        compatible = "gpio-leds"; //←device Tree Binding(yamlファイル)の名前
        green_led: led_0 {
            gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>;
            label = "User LD1";
        };
        blue_led: led_1 {
            gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>;
            label = "User LD2";
        };
        red_led: led_2 {
            gpios = <&gpiob 14 GPIO_ACTIVE_HIGH>;
            label = "User LD3";
        };
    };

    aliases {
        led0 = &green_led;
        led1 = &blue_led;
        led2 = &red_led;
        sw0 = &user_button;
    };
デバイスツリーとは

デバイス固有の情報(プロパティ)を抽象化するために、Arm Linuxで設けられた仕組み。

デバイス固有のピン番号などの情報を他から隠蔽している。

今回の場合、上記ボードのdtsファイル、そしてSTM32のチップ自体のdtsiファイルがある。

dtsiファイル

zephyr/stm32f7.dtsi at main · zephyrproject-rtos/zephyr · GitHub

         gpiob: gpio@40020400 {
                compatible = "st,stm32-gpio";
                gpio-controller;
                #gpio-cells = <2>;
                reg = <0x40020400 0x400>;
                clocks = <&rcc STM32_CLOCK_BUS_AHB1 0x00000002>;
                label = "GPIOB";
            };
STMGPIOのbindingファイル
#

zephyr/st,stm32-gpio.yaml at main · zephyrproject-rtos/zephyr · GitHub

抜粋

description: STM32 GPIO node
compatible: "st,stm32-gpio"

include: [gpio-controller.yaml, base.yaml]

properties:
    reg:
      required: true
    label:
      required: true
    clocks:
      required: true
    "#gpio-cells":
      const: 2

gpio-cells:
  - pin
  - flags
LEDのbindingファイル
zephyr/dts/bindings/gpio/gpio-leds.yaml

zephyr/gpio-leds.yaml at main · zephyrproject-rtos/zephyr · GitHub

抜粋

description: GPIO LEDs parent node
compatible: "gpio-leds"

include:
    - name: base.yaml
      property-allowlist: [label]

properties:
    label:
      description: |
        Human readable string describing the device and used to set the device
        name. It can be passed as argument to device_get_binding() to retrieve
        the device. If this property is omitted, then the device name is set
        from the node full name.
child-binding:
    description: GPIO LED child node
    properties:
       gpios:
          type: phandle-array
          required: true
       label:
          required: false
          type: string
          description: |
            Human readable string describing the LED. It can be used by an
            application to identify this LED or to retrieve its number/index
            (i.e. child node number) on the parent device.
ノードIDとは

各ノードに自動的に振られるID。

ノードとは

green_ledblue_ledなど。

14. #if DT_NODE_HAS_STATUS(LED0_NODE, okay)

DT_NODE_HAS_STATUS()でボードが特定のノードを持っているか調べられる

Nucleoは"led0"を最初から持っているのでこの#if内に分岐する

15. #define LED0 DT_GPIO_LABEL(LED0_NODE, gpios)

Devicetree API — Zephyr Project Documentation

ノードID, phandleからラベルを取得する。

phandleとは

おそらくparent handle

Arm Linux デバイスツリーからの輸入。

とあるエンジニアの備忘log: Device Tree 入門

(今回ならLED0)にとっての親要素のハンドル(適当な整数値)。

今回はボードのdtsファイル内でgpiobを指定している。

するとdtsiファイル内のgpiobと紐づく。

phandleの書式

Introduction to devicetree — Zephyr Project Documentation

a-phandle = <&mynode>;
some-phandles = <&mynode0 &mynode1 &mynode2>;
a-phandle-array = <&mynode0 1 2 &mynode1 3 4>;
ラベルとは

"User LD1""User LD2"など

dtsファイル内に記載。

ノードの検索ワードみたいなもの?

何のために存在しているのか不明。

そもそもなぜ引数にphandleが必要なんだろう。

ノードIDがあれば特定できるものではないのかな?

ノードIDは親ごとに振られるのかな?

DT_GPIO_LABEL()マクロはzephyr/include/devicetree/gpio.h内で定義されている。ただし、当該ヘッダファイルはdevicetree.hからインクルードされているため、includeする必要はない。

16. #define PIN DT_GPIO_PIN(LED0_NODE, gpios)

Devicetree API — Zephyr Project Documentation

DT_GPIO_PIN_BY_IDX()の特別な場合。 こちらでは引数が1つ多く。 ` DT_GPIO_PIN_BY_IDX(node_id, gpio_pha, idx)となる。

ピンという名前のセルを持つ

DT_GPIO_PIN()マクロはzephyr/include/devicetree/gpio.h内で定義されている。ただし、当該ヘッダファイルはdevicetree.hからインクルードされているため、includeする必要はない。

セルとは

Devicetree bindings — Zephyr Project Documentation

phandleに記述する付加情報。引数。

例えばボードのdtsにある

gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>;

だったら、

0
GPIO_ACTIVE_HIGH

がセル。

dtsiファイルの中に

dt-cells = <2>;

とあり、これはセルを2つ持つという意味

またSTMGPIOのbindingファイルの中に

    "#gpio-cells":
        const: 2

gpio-cells:
  - pin
  - flags

とあり、これはセルを記述している。

なので、

gpios(gpioのphandle array) は gpiobである
pin = 0
flags =  GPIO_ACTIVE_HIGH

という意味になる。

17. #define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)

Devicetree API — Zephyr Project Documentation

DT_GPIO_FLAGS()マクロはzephyr/include/devicetree/gpio.h内で定義されている。ただし、当該ヘッダファイルはdevicetree.hからインクルードされているため、includeする必要はない。

#define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)

18-24 #else - #endif

単なるエラー処理。"led0"がなかった時の挙動を決めてる。

27 const struct device *dev;

30. dev = device_get_binding(LED0);

device_get_binding(LED0)

↓#define LED0 DT_GPIO_LABEL(LED0_NODE, gpios)

↓↓ #define LED0_NODE DT_ALIAS(led0)

↓#define LED0 DT_GPIO_LABEL( <"led0"のnode id>, gpios)

device_get_binding("User LD1")

defineマクロなのでgpiosに""はいらないッテコト!?

34. ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);

ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);

↓#define PIN DT_GPIO_PIN(LED0_NODE, gpios)

boardの.dtsにgpios = <&gpiob 0 GPIO_ACTIVE_HIGH>; 0とあるので

ret = gpio_pin_configure(dev, 0 , GPIO_OUTPUT_ACTIVE | FLAGS);

ret = gpio_pin_configure(dev, 0 , GPIO_OUTPUT_ACTIVE | FLAGS);

39. gpio_pin_set(dev, PIN, (int)led_is_on);

41. k_msleep(SLEEP_TIME_MS);

GPIO

GPIO — Zephyr Project Documentation

LED API

LED — Zephyr Project Documentation

Device Tree

とあるエンジニアの備忘log: Device Tree 入門

Device Tree Binding

Devicetree bindings — Zephyr Project Documentation

バスを考慮する Devicetree bindings — Zephyr Project Documentation

zephyr/dts/bindings/gpio/gpio-leds.yaml

LEDのbinding zephyr/gpio-leds.yaml at main · zephyrproject-rtos/zephyr · GitHub

draw.ioで大きなシートをPDF化・エクスポートできないときの対処法

Diagrams.netも同様

これすると...

f:id:masa_flyu:20211210113250p:plain f:id:masa_flyu:20211210113302p:plain

こうなる場合(404の場合もあり)の回避策です。

f:id:masa_flyu:20211210113432p:plain

根本解決ではありません。

1. include a copy of my diagramをなくす

ファイル構造の中に(PDFならPDFの中に)draw.io形式の(XML)データを入れる方式です。 正直全く不要なので、チェックを外します。 エクスポートが高速化し、エラーが出にくくなります。

f:id:masa_flyu:20211210113709p:plain

2. ページ数を減らす

一度にエクスポートするページ数を減らす。

3. ローカルでやる

こちらからローカル版のdraw.ioをインストールできます。

https://github.com/jgraph/drawio-desktop/releases/

f:id:masa_flyu:20211210114119p:plain

これであれば同じエラーは出ません。

4. コマンドで呼び出す。

ローカルインストール必須ですが、自分がやりたかった、PDFの1ページずつ個別出力などができます。

www.shujima.work

draw.io の個別PDF化 (1ページずつシート名をつけてエクスポート)

draw.io (Diagrams.net) のデータを個別にpdf化します。 python環境およびdraw.ioのデスクトップ版が必要です。

  • 仕様上1ページ目を飛ばしてしまいます。
    • コマンド上では1ページ目は0を指定するのですが、0にすると全ページが印刷されてしまいます。バグor仕様のようです
    • 1ページ目にいらないページを作って対処してください
  • デスクトップ版のインストールが必要です。
  • Windows版しか動作確認していません。
  • <draw.ioファイル名>-<シート名>の形で各シートが1枚ずつpdf化されます。

参考

以下の画像の変換を多大に参考にさせていただいております。 * 主要参考元:https://qiita.com/ryo_i6/items/6ebbeadd181da4d0b5b3 draw.ioの全ページを一括変換する * ヘルプ: https://qiita.com/u4da3/items/646cc46bff68b380cbfa draw.io をコマンドラインで実行して、画像ファイルをエクスポートする 詳細なセットアップなどは参考元をご覧ください。

セットアップ

(箇条書き。この下に画像付きの手順があります)

  1. ローカルのdraw.ioアプリをダウンロードする https://github.com/jgraph/drawio-desktop/releases/
  2. Windows PowerShellを開く
  3. pythonを打ってenter
  4. Microsoft Storeのウインドウが出てきたらインストールを押す。出てこなかったら、何もしない
  5. PowerShellを閉じる
  6. 添付のソースコードを「drawio_pdf_export.py」というファイル名でどこかに保存する
  7. 同じディレクトリに「drawio_pdf_export」というフォルダを作る
  8. pdf化したい.drawioファイルを用意する
  9. 拡張子が付いていない場合、拡張子を「.drawio」にする
  10. 先ほど作ったpdfフォルダに.drawioファイルを入れる
  11. PowerShellを新しく開く
  12. cdコマンドで先ほどのディレクトリに移動する
  13. 「python .\drawio_pdf_export.py」を打つ
  14. Enterを押すと変換が始まる

以上で完了

  1. ローカルのdraw.ioアプリをダウンロードする https://github.com/jgraph/drawio-desktop/releases/
  2. Windows PowerShellを開く
  3. pythonを打ってenter
  4. Microsoft Storeのウインドウが出てきたらインストールを押す。出てこなかったら、何もしない (この操作はPythonの初回インストール時のみ必要です。よって環境によっては出てこないことがあります。)
  5. PowerShellを閉じる
  6. 添付のソースコードを「drawio_pdf_export.py」というファイル名でどこかに保存する
  7. 同じディレクトリに「drawio_pdf_export」というフォルダを作る
  8. pdf化したい.drawioファイルを用意する(Web版draw.ioからダウンロードする場合は画像のようにSave as→Deviceを選ぶとダウンロードされます。
  9. 拡張子が付いていない場合、拡張子を「.drawio」にする
  10. 先ほど作ったpdfフォルダに.drawioファイルを入れる
  11. PowerShellを新しく開く
  12. cdコマンドで先ほどのディレクトリに移動する
  13. 「python .\drawio_pdf_export.py」を打つ
  14. Enterを押すと変換が始まる
  15. 完了 pdfフォルダ内に変換した後のpdfがある。

コード

from pathlib import Path
import xml.etree.ElementTree as et
import subprocess


def get_output_path(file_path, page_name, file_type):
    stem = '-'.join([str(file_path.stem), page_name])
    suffix = '.' + file_type
    return file_path.with_name(stem).with_suffix(suffix)


def generate_pdf(file_path):
    DRAWIO = '"C:\Program Files\draw.io\draw.io.exe"' #draw io デスクトップ版の場所
    FILE_TYPE = 'pdf' #各種オプションの調整が必要だが、これを変更するとそれぞれの形式にできる

    root = et.parse(file_path).getroot() # xmlのroot draw.ioの場合は<mxfile>というタグ
    print(root.get('pages')) #debug
    print(range(int(root.get('pages')))) #debug

    # 1ページずつ印刷
    # ページ番号はdraw.io コマンドでもxml.etreeでも0から始まる。draw.ioのGUIでは1ページから
    for i in range(1, int(root.get('pages')) ):
        page_name = root[i].get('name') 
        # 各オプションの中身
        g = ' '.join(['-g', str(i)+'..'+str(i)])
        o = ' '.join(['-o', '"' + str(get_output_path(file_path, page_name, FILE_TYPE)) + '"'])
        # run
        command = ' '.join([DRAWIO, '"' + str(file_path) + '"', '-x', g, o])
        print(command) #debug
        subprocess.run(command) #コマンドの実行
 

if __name__ == '__main__':
    root_dir = Path.cwd()
    for i in root_dir.glob('drawio_pdf_export\\*.drawio'):
        generate_pdf(i.relative_to(root_dir))


# 参考
# 主要参考元:https://qiita.com/ryo_i6/items/6ebbeadd181da4d0b5b3 draw.ioの全ページを一括変換する
# ヘルプ: https://qiita.com/u4da3/items/646cc46bff68b380cbfa draw.io をコマンドラインで実行して、画像ファイルをエクスポートする

秋月の商品とKiCADフットプリントの対応メモ(自分用)

ユーロブロック

無さそう。

代替

以下製品などはDigikey等で同等品が購入できる。また、そのE-CADを転用できると思われる。 * TE 796638-2 796638-2 TE Connectivity AMP Connectors | コネクタ、相互接続 | DigiKey * Phoenix 1757242 1757242 Phoenix Contact | コネクタ、相互接続 | DigiKey * CUI TBP01R1-508-02BE TBP01R1-508-02BE CUI Devices | コネクタ、相互接続 | DigiKey

スライドスイッチ

1回路2接点 (SPDT)

SS12D01G4 https://akizukidenshi.com/catalog/g/gP-12723/ SS-12D00G3 https://akizukidenshi.com/catalog/g/gP-15707/

など

KiCAD

なし?

2回路2接点 (DPDT)

https://akizukidenshi.com/catalog/g/gP-02627/

KiCAD
  • Button_Switch_THT
    • SW_CuK_JS202011CQN_DPDT_Straight
    • SW_E-Switch_EG1271_DPDT

上記のいずれか。SW_E-Switch_EG1271_DPDTは0.1mm穴位置がずれているが、パッドが大きめでハンダしやすそう。

2回路2接点 (DPDT)横向き

SK-22H09G5 https://akizukidenshi.com/catalog/g/gP-15702/

KiCAD
  • Button_Switch_THT
    • SW_CuK_JS202011AQN_DPDT_Angled

SW_E-Switch_EG2219_DPDT_Angledは補強用の穴が無い

Windowsでgit-filter-repo 書きかけ

自分はpython3.9がインストール済みだった

主にこちらに従っていく

sleepost.hatenablog.com

詰まったところ

そもそもscoopが入ってない

qiita.com

Powershell

Set-ExecutionPolicy RemoteSigned -scope CurrentUser
invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')

以下のようなエラーが出た

git filter-repo -hを実行したところ

Traceback (most recent call last):
  File "C:\Users\***\scoop\apps\git-filter-repo\current\git_filter_repo.py", line 1, in <module>
    git-filter-repo
NameError: name 'git' is not defined

これは以下の手順で解決 github-com.translate.goog

git

当ブログをご利用いただく際には免責事項をお読みください。