ESP-IDFでLチカした

ESP-IDFのexamplesに入ってるblinkを見て動かした。

FreeRTOSのドキュメントを見る。

gpio_pad_select_gpio( uint8_t gpio);

gpioをGPIOに設定する?0~0x27までらしい。 blink.cだとデフォルトだとIO5番が渡されている。

gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(BLINK_GPIO, 1);

で方向と電圧レベルを変えている。

電流は出しすぎると、容量が足りなくなるかもしれなかったので、低めで試した。

LED周りの計算

電源はhighのとき3.3V、LEDの標準電流は30mAほどで、電圧降下は1.9Vなので、 抵抗は46.7Ωだけど、近くにあったのが、100Ωだったので、100Ω(誤差+-5%)で行なった。 100Ωにすると、14mA。半分くらいになる。電力も1/4Wも大幅に下回るし大丈夫だと思う。

なんなら270Ωでも十分明るいと感じた。 測定値もだいたいあってたしおっけい。

f:id:b1u3:20190311011816j:plain

ESP-IDFでhello worldした

esp-wroom-32はarduino studioでしか使ったことがなかったので、esp-idfでやって見ようかなと思ったので、やった。

基本的に

docs.espressif.com

ここを進めた。

その際に起こったことを記録する。

FLAGSのエラー

まず、環境変数に、FLAGS関連の環境変数が設定されていると、

make flash

で、

/Users/b1u3/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find crt1-sim.o: No such file or directory
/Users/b1u3/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find _vectors.o: No such file or directory
/Users/b1u3/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find -lsim
/Users/b1u3/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find -lhandlers-sim
/Users/b1u3/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find -lhal
collect2: error: ld returned 1 exit status
make[1]: *** [/Users/b1u3/esp/hello_world/build/bootloader/bootloader.elf] Error 1
make: *** [/Users/b1u3/esp/hello_world/build/bootloader/bootloader.bin] Error 2

これは、環境変数にFLAGS関係の変数(LDFLAGS, CPPFLAGS)が設定されていることに起因しているので、消すなり、実行時だけ追加されるようにするのがいい。project.mkに?=が使われてるからだと思う。

monitorのエラー

make monitor

すると、

MONITOR
--- idf_monitor on /dev/cu.SLAB_USBtoUART 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---

Traceback (most recent call last):
  File "/Users/b1u3/Develop/esp/esp-idf/tools/idf_monitor.py", line 743, in <module>
    main()
  File "/Users/b1u3/Develop/esp/esp-idf/tools/idf_monitor.py", line 668, in main
    monitor.main_loop()
  File "/Users/b1u3/Develop/esp/esp-idf/tools/idf_monitor.py", line 337, in main_loop
    self.handle_serial_input(data)
  File "/Users/b1u3/Develop/esp/esp-idf/tools/idf_monitor.py", line 391, in handle_serial_input
    if self._output_enabled and (self._force_line_print or self._line_matcher.match(line)):
  File "/Users/b1u3/Develop/esp/esp-idf/tools/idf_monitor.py", line 256, in match
    m = self._re.search(line)
TypeError: cannot use a string pattern on a bytes-like object
make: *** [monitor] Error 1

というエラーが出る。 v3.1.3だと、idf_monitor.pyにエラーが出る。これはgithubからupstreamの物をそのままコピペして、内容を入れ替えると回避できる。

github.com

回避すると動く

f:id:b1u3:20190307002353j:plain
esp-idfのmonitor

タイガーブック(1)

コンパイラを作りたいのであれば、チャプター2からやればいい?って感じ。githubとかに完成品がたくさんゴロゴロ転がっているので、困ったらそれを見ればいいみたいな。

ちょっとずつ指針を書いていって実装していこうかなって思ってる。

チャプター2では、字句解析器の実装。 タイガーブックだと字句解析器ジェネレータとして、ML-Lexを使っている。

一応、字句解析器というのは、トークンに分ける作業のこと。

123+123;

こういう入力があった時に、123は数字で、+は"足す記号"、123は数字、;はセミコロンというように、順次認識してく過程。

この章は、ML-Lexの書き方をちゃんと理解するような章かな。 アルゴリズム実装はない感じがした。 いじるのは、配布されているディレクトリのchap2/tiger.lex。

ここに書いて、CM.make "sources.cm";して、parseして、、、っていうのをやって、字句解析過程を進めていく。わかんないとこは調べながら。

やっぱ完成品を理解していく方が早いな^^

golangインタープリタ実装だと、フロントエンドも自分で書いてたので、ツールの使い方の勉強だと思えばまぁ楽しいのかな。

POJ3176

蟻本の練習問題として載ってるPOJの問題3176。 簡単なDPの解答。 大雑把にO(n2)で収まるぐらいの計算量で解いた。以下、解答

#include <cstdio>
#include <algorithm>

using namespace std;

#define MAX_A 500

int n, a[MAX_A][MAX_A], dp[MAX_A+1][MAX_A+1];

int solve(int n) {
    int ans = 0;
    dp[0][0] = a[0][0];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= i+1; j++) {
            if (j-1>=0){
                dp[i+1][j] = max(dp[i][j-1], dp[i][j])+a[i+1][j];
            } else {
                dp[i+1][j] = dp[i][j]+a[i+1][j];
            }
            ans = max(ans, dp[i+1][j]);
        }
    }
    return ans;
}


int main() {
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        for(int j = 0; j <= i; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    printf("%d\n", solve(n));
    return 0;
}

C++だけどほぼCみたいな。 配列を2次元にしたけど、逆三角形の部分は使ってないからメモリがもったいないかなと思った。1 次元にすれば節約できる。

タイガーブックを読む前に2

前記事で、smlnjのインストールをやった。 そのあと本通りにやると、

CM.make();

で以下のようなエラーが。

stdIn:1.2-1.11 Error: operator and operand do not agree [tycon mismatch]
  operator domain: string
  operand:         unit
  in expression:
    CM.make ()

CM.makeは引数渡さなきゃいけないらしかった。

CM.make "sources.cm";

で、実行すると、

sources.cm:8.1-8.14 Error: Io: openIn failed on "/smlnj-lib.cm", No such file or directory

これは、実際はライブラリがインストールされてるけど、適切に探せてなかったらしい。 なので、sources.cmをsmlnj-lib.cmを以下に修正。

$/smlnj-lib.cm

で、次のエラーは

errormsg.sml:7.24-7.39 Error: unbound structure: TextIO in path TextIO.instream
errormsg.sml:21.26-21.38 Error: unbound structure: TextIO in path TextIO.stdIn
errormsg.sml:27.18-27.30 Error: unbound structure: TextIO in path TextIO.stdIn
errormsg.sml:36.12-36.24 Error: unbound structure: Int in path Int.toString
errormsg.sml:34.12-34.24 Error: unbound structure: Int in path Int.toString
errormsg.sml:49.8-49.23 Error: unbound structure: TextIO in path TextIO.flushOut
errormsg.sml:49.24-49.37 Error: unbound structure: TextIO in path TextIO.stdOut

こんなの。 次は、

takoeight0821.hatenablog.jp

この人のを参考にして、basisを追加。

$/basis.cm

そうすると、

Standard ML of New Jersey v110.85 [built: Sat Dec 22 16:51:02 2018]
- CM.make "sources.cm";
- Parse.parse;
val it = fn : string -> unit

Parse.parseが使えるようになっている。

タイガーブックを読む前に

コンパイラでそこそこ有名なタイガーブックを読む前に、MLについて知っておくべきだったと読む前に思った。その際のos x上でのインストールと構文を見るのに最適なところ。

brew install mlsnj

brewでインストールできる。 インストールしたらpathを通してsmlが実行できるようにする。

終わったら

https://www.cs.princeton.edu/courses/archive/fall08/cos441/notes/lect-SMLNJ.pdf

ここを見るのが良いと思われる。

smlを起動するとインタープリターになる。 ctrl+dで終了。

djangoとvueのテンプレート

djangoのテンプレートエンジンとvue.jsのテンプレートの構文が似ているので、同時に使うのは厳しいと思っていた時期が僕にもありました。

いちいち、別の静的ファイルに書き出してscriptタグで指定は正直だるかった。

たまたま検索かけてみたら、vue.jsのdelimitersを指定するだけで、回避できるっぽい。

<html>
    <head>
       <meta charset="utf-8" />
       <title>Delimiters Sample</title>
       <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   </head>
    <body>
        <div id="app">
            <p>[[message]]</p>
            <ul>
                <li v-for="m in items" :key="m.id">
                    [[m.text]]
                </li>
            </ul>
        </div>
        <script>
           var app = new Vue({
               delimiters: ['[[', ']]'],
               el: '#app',
               data: {
                   message: 'Hello Vue',
                   items: [{id: 1, text:"sample1"},{id: 2, text: "sample2"}],
               },
           })
       </script>
    </body>
</html>

delimitersで色々変えられるみたいなので、いちいち外部にやったりしなくてもいい!!最高!!