Help us understand the problem. What is going on with this article?

【第一弾】Zen言語でLチカをしてみた

はじめに

はじめまして、
組み込み系の会社に働く、もうすぐ社会人2年目になる二人組が、
Zen言語に魅了され、取り組んだ成果を投稿しています。
(Zen言語の詳細はここを見てください)

まったり見てってください(笑)

第一弾の今回は!!
RaspberyPi 3を使って組み込みの入門プログラミング『Lチカ』にチャレンジしました!

Lチカを実現する方法はいくつかあると思います。
ですが今回は、初心者であるという点からZen言語を使った「ハードウェア直叩き」ではなく、
Wiring Piライブラリ(GPIOアクセスライブラリ)を
Zen言語からアクセスするという方法で実現することにしました。

前提

  • Zen言語バージョン : 0.8.20191124+552247019(Mac)
  • モデル : Raspberry Pi 3 Model B

Let's Try!!

全体の流れ

Zen言語を用いたLチカは5ステップ!!
1. Wiring PiをGithubから取得する。
2. 最低限Lチカに必要な関数をZen言語から呼び出せるようにする。
3. Zen言語でLチカを行うプログラムを作成する。
4. Zen言語ソースとC言語ソースをコンパイルする。

【1ステップ】Wiring PiをGithubから取得する

#作業用ディレクトリの作成
mkdir wiringPi-zen

#Wiring Pi のソースコードを取得します。
git clone git://git.drogon.net/wiringPi

【2ステップ】Lチカに必要な関数をZen言語から呼び出せるようにする

サンプルを参考に最低限必要なソースコードは以下です。
  1. wiringPi/wiringPi.c
  2. wiringPi/piHiPri.c
  3. wiringPi/softTone.c
  4. wiringPi/softPwm.c
Lチカに必要な最低限の関数は以下です。
#include <wiringPi.h>
/* GPIO setup: Initialises the system into GPIO Pin mode and uses the
 *  memory mapped hardware directly. 
 * (GPIO初期化)
 */
int wiringPiSetup (void);

/* Sets the mode of a pin to be input, output or PWM output 
 * (ピンのモードを入力、出力、PWM 出力のいずれかに設定する)
 */
void pinMode (int pin, int mode);

/* Set an output bit 
 * (出力設定)
 */
void digitalWrite (int pin, int value);

/* Wait for some number of milliseconds 
 * (遅延)
 */
void delay (unsigned int howLong);
ラッパー関数の作成

では、実際にZen言語から必要な関数を呼び出せるようにしたいと思います。
公式ドキュメントによると方法は3つあるそうです。

  1. CソースファイルをZenソースファイルに変換する
  2. 手動でCインタフェースを作成する
  3. Cヘッダファイルからインポートする

今回は、3番目の方法で実現したいと思います。

公式ドキュメント

// Cヘッダファイルを、直接Zenソースへインポート
const c = @cImport ({
    @cInclude("wiringPi.h");
});

// ラッパー関数の定義
pub fn wiringPiSetup() void {
    _ = c.wiringPiSetup();
}

pub fn pinMode(pin: c_int, mode: c_int) void {
    _ = c.pinMode(pin, mode);
}

pub fn digitalWrite(pin: c_int, value: c_int) void {
    _ = c.pinMode(pin, value);
}

pub fn delay(howLong: c_uint) void {
    _ = c.delay(howLong);
}

【3ステップ】Zen言語でLチカを行うプログラムを作成する

wiring Piのサンプルプログラム(examples/blink.c)を参考に、
Lチカプログラムを作っていきたいと思います。

setup.zen
const std = @import("std");
const LED = 0;

pub fn main() anyerror!void {

    const stdout = try std.fs.getStdOut();

    try stdout.write("Raspberry Pi Blink\n");

    // 初期化
    wiringPiSetup();
    pinMode(LED, c.OUTPUT);

    // 無期限にLチカ
    while (true) {
        digitalWrite(LED, c.HIGH);
        try stdout.write("Raspberry Pi Blink[ON]\n");
        delay(500);

        digitalWrite(LED, c.LOW);
        try stdout.write("Raspberry Pi Blink[OFF]\n");
        delay(500);
    }

}

【4ステップ】Zen言語ソースとC言語ソースをコンパイルする

zen言語のコンパイラーは、ZenソースファイルとCソースファイルを同時にコンパイルする事が可能です。Cソースファイルをコンパイルするにの用いたオプションは以下になります。

  1. Cソースファイルをコンパイル対象にする
    zen build-exe --c-source <Cソースファイル>

  2. C言語の標準ライブラリを利用する
    zen build-exe --library c <XXX>

  3. C言語のヘッダファイルを探索するパスを追加する
    zen build-exe -isystem <C言語ヘッダファイルパス> <XXX>

cd wiringPi-zen

zen build-exe --c-source  WiringPi/wiringPi/wiringPi.c \
--c-source WiringPi/wiringPi/piHiPri.c \
--c-source  WiringPi/wiringPi/softTone.c \
--c-source WiringPi/wiringPi/softPwm.c \
setup.zen --library c  --name [実行バイナリ名] \
-target armv8_5a-linux-gnueabihf \
-I WiringPi/wiringPi -isystem WiringPi/wiringPi

完成

LEDが500ms毎にON,OFFしています!
led.gif

今回の「Zen言語でLチカをしてみた」は以上になります。

次回はこのプログラムを、Zen言語で記述するビルドスクリプト(build.zen)を用いてコンパイルしてみたいと思います。
C言語の代表的なビルドスクリプト(make)に変わるZen言語に標準に備わった、外部ビルドシステムに依存しないスクリプトらしいです笑

以上、最後まで読んで頂きありがとうございました。

freshers
プログラマー歴2年目(組み込み分野)の若手メンバ2人で取り組んだ成果を、アウトプットしています。積極的にチャレンジし、どんどん発信していきたいと思います。 (歴が浅い為に勘違いしている点がある場合はご指摘いただければ幸いです)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away