まだタイマーは実装できていない…
準備したもの
RaspberryPiPico
windows10のPC
USB-microUSBケーブル
開発環境の構築
公式のドキュメントを参照
私はwindowsだったので「9.2.Building on MS Windows」を参考にした。
・ARM GCC compiler
・CMake
・Build Tools for Visual Studio 2019
・Python 3.7
・Git
をインストールすればいいらしい。
特に問題は無いはずだが私がつまずいた点だけあげておく。
- Visual Studio 2019のインストール時、チェックボックスが公式ドキュメントと異なる。
日本語ですから…とりあえず↓のようにしておいた。
- Gitのインストール時にvim以外を指定するようにドキュメントに書いてある。
ドキュメント曰くNotepad++にするようにと画像で示されているが、Notepad++をインストールしていなかったのでインストールした。 - [9.2.3. Building "Hello World" from the Command Line]にて
Windows > Visual Studio2019 > Developer Command Prompを開くように言われているのに無視してそのままcmd.exeで作業していました。
気を付けましょう。cmakeとnmakeができないと思います。
mruby/cを導入
mruby/cとmrbcをダウンロードします。(コマンドを使用しないでcode > DownlodeZipでコードを持ってくる男)
→ それぞれ解凍しておく。
mruby/cのzipファイルを解凍すると中にsrcフォルダがあると思うので、そのsrcフォルダをpico-examples/blink
へそのまま入れます。
ちなみに今回はpico-examples/blink
を改造して使っていきます。
pico-examples/blink
内にあるCMakeLists.txtを編集しなきゃならないですが、cmakeなんてはじめて触るので雑ですが↓のように編集しました。
add_compile_options(-D MRBC_NO_TIMER)
add_executable(blink
blink.c
src/alloc.c
src/c_array.c
src/c_hash.c
src/c_math.c
src/c_numeric.c
src/c_range.c
src/c_string.c
src/class.c
src/console.c
src/error.c
src/global.c
src/keyvalue.c
src/load.c
src/mrblib.c
src/rrt0.c
src/static.c
src/symbol.c
src/value.c
src/vm.c
)
# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(blink pico_stdlib)
# create map/bin/hex file etc.
pico_add_extra_outputs(blink)
# add url via pico_set_program_url
example_auto_set_url(blink)
pico-examples/blink/src/vm_config.h
84行目にあるコメントアウトを外します。
/* 32it alignment
If 32-bit alignment is required, enable the following line.
*/
#define MRBC_REQUIRE_32BIT_ALIGNMENT
pico-examples/blink/src
内にあるhal_psoc5lp
フォルダをhal
へリネームします。
そのhalフォルダにあるhal.h
を↓のように編集します。
#ifndef MRBC_SRC_HAL_H_
#define MRBC_SRC_HAL_H_
#ifdef __cplusplus
extern "C" {
#endif
/***** Feature test switches ************************************************/
/***** System headers *******************************************************/
#include "pico/stdlib.h"
/***** Local headers ********************************************************/
/***** Constant values ******************************************************/
/***** Macros ***************************************************************/
#if !defined(MRBC_TICK_UNIT)
#define MRBC_TICK_UNIT_1_MS 1
#define MRBC_TICK_UNIT_2_MS 2
#define MRBC_TICK_UNIT_4_MS 4
#define MRBC_TICK_UNIT_10_MS 10
// You may be able to reduce power consumption if you configure
// MRBC_TICK_UNIT_2_MS or larger.
#define MRBC_TICK_UNIT MRBC_TICK_UNIT_1_MS
// Substantial timeslice value (millisecond) will be
// MRBC_TICK_UNIT * MRBC_TIMESLICE_TICK_COUNT (+ Jitter).
// MRBC_TIMESLICE_TICK_COUNT must be natural number
// (recommended value is from 1 to 10).
#define MRBC_TIMESLICE_TICK_COUNT 10
#endif
#ifndef MRBC_NO_TIMER
# define hal_init() ((void)0)
# define hal_enable_irq() ((void)0)
# define hal_disable_irq() ((void)0)
# define hal_idle_cpu() (sleep_ms(1), mrbc_tick())
#else // MRBC_NO_TIMER
# define hal_init() ((void)0)
# define hal_enable_irq() ((void)0)
# define hal_disable_irq() ((void)0)
# define hal_idle_cpu() (sleep_ms(1), mrbc_tick())
#endif
/***** Typedefs *************************************************************/
/***** Global variables *****************************************************/
/***** Function prototypes **************************************************/
int hal_write(int fd, const void *buf, int nbytes);
int hal_flush(int fd);
/***** Inline functions *****************************************************/
#ifdef __cplusplus
}
#endif
#endif // ifndef MRBC_HAL_H_
(タイマーの実装はできてないので同じ内容をダミーとして入れておきました)
今回使用するRubyのプログラムを用意します。
保存場所はコンパイラのフォルダ内がいいと思います。201904181318159501cbec95e/mruby-2.0.1-win
の下
Lチカしたいので、それらしいプログラムを書いておきます。
led1_writeによってオンボードLEDを制御することにします。
第一引数が1の時LEDがON、0の時OFFとなる予定です。
while文の無限ループ内にsleepも含めてプログラムします。1秒間隔でLEDが点滅する。
while true
led1_write(1)
sleep(1)
led1_write(0)
sleep(1)
end
sample1.rbを書き終えたらコマンドラインで201904181318159501cbec95e/mruby-2.0.1-win
まで移動しましょう。
移動したらコマンドを打ちますmrbc.exe -E -Bsample1 sample1.rb
すると同じフォルダ内にsample1.cができると思います。↓ sample1[]の中身をコピーしておきましょう。
/* dumped in big endian order.
use `mrbc -e` option for better performance on little endian CPU. */
#include <stdint.h>
extern const uint8_t sample1[];
const uint8_t
#if defined __GNUC__
__attribute__((aligned(4)))
#elif defined _MSC_VER
__declspec(align(4))
#endif
sample1[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x36,0xd1,0x25,0x00,0x00,0x00,0x83,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x00,0x65,0x30,0x30,
0x30,0x32,0x00,0x00,0x00,0xe7,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x2e,
0x21,0x00,0x23,0x10,0x01,0x07,0x02,0x2e,0x01,0x00,0x01,0x10,0x01,0x07,0x02,0x2e,
0x01,0x01,0x01,0x10,0x01,0x06,0x02,0x2e,0x01,0x00,0x01,0x10,0x01,0x07,0x02,0x2e,
0x01,0x01,0x01,0x11,0x01,0x22,0x01,0x00,0x03,0x0f,0x01,0x37,0x01,0x67,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0a,0x6c,0x65,0x64,0x31,0x5f,0x77,0x72,0x69,
0x74,0x65,0x00,0x00,0x05,0x73,0x6c,0x65,0x65,0x70,0x00,0x45,0x4e,0x44,0x00,0x00,
0x00,0x00,0x08,
};
続いてpico-examples/blink/blink.c
を編集していきます。
led1_writeという関数をRubyのプログラムで使えるように追加しておきます。
sample1[]には先ほどRubyプログラムをコンパイルしてできた配列を入れます。
#include "pico/stdlib.h"
#include "src/mrubyc.h"
#define MEMORY_SIZE (1024*20)
uint8_t sample1[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x36,0xd1,0x25,0x00,0x00,0x00,0x83,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x00,0x65,0x30,0x30,
0x30,0x32,0x00,0x00,0x00,0xe7,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x2e,
0x21,0x00,0x23,0x10,0x01,0x07,0x02,0x2e,0x01,0x00,0x01,0x10,0x01,0x07,0x02,0x2e,
0x01,0x01,0x01,0x10,0x01,0x06,0x02,0x2e,0x01,0x00,0x01,0x10,0x01,0x07,0x02,0x2e,
0x01,0x01,0x01,0x11,0x01,0x22,0x01,0x00,0x03,0x0f,0x01,0x37,0x01,0x67,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0a,0x6c,0x65,0x64,0x31,0x5f,0x77,0x72,0x69,
0x74,0x65,0x00,0x00,0x05,0x73,0x6c,0x65,0x65,0x70,0x00,0x45,0x4e,0x44,0x00,0x00,
0x00,0x00,0x08,
};
static uint8_t memory_pool[MEMORY_SIZE];
static void c_led1_write(mrb_vm *vm, mrb_value *v, int argc) {
int set_value = GET_INT_ARG(1);
gpio_put(25,set_value);
}
int hal_write(int fd, const void *buf, int nbytes) {
return 0;
}
int hal_flush(int fd) {
return 0;
}
int main() {
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
mrbc_init(memory_pool, MEMORY_SIZE);
mrbc_define_method(0, mrbc_class_object, "led1_write", c_led1_write);
mrbc_create_task(sample1, 0);
mrbc_run();
return 1;
}
プログラムの書き込み
Developer Command Promp
を使ってpico-examples/build
へ移動します。
nmake
コマンドを実行。↓のようにビルドがはじまります。
Scanning dependencies of target blink
[ 0%] Building C object blink/CMakeFiles/blink.dir/blink.c.obj
[ 0%] Building C object blink/CMakeFiles/blink.dir/src/alloc.c.obj
[ 0%] Building C object blink/CMakeFiles/blink.dir/src/c_array.c.obj
[ 0%] Building C object blink/CMakeFiles/blink.dir/src/c_hash.c.obj
[ 0%] Building C object blink/CMakeFiles/blink.dir/src/c_math.c.obj
[ 0%] Building C object blink/CMakeFiles/blink.dir/src/c_numeric.c.obj
............
エクスプローラーでpico-examples/build/blink
を開きます↓
ラズパイpicoをパソコンへ接続します。
すると勝手にエクスプローラが起動します。(一度書き込んだ後はBOOTSELボタンを押しながらパソコンへ接続)
pico-examples/build/blink
にあるblink.uf2
をラズパイpicoのディレクトリにドラッグアンドドロップすれば書き込み完了です。
Lチカが始まります。
動画:pic.twitter.com/D87VRTHXlr
まとめ(感想)
環境構築だけで数時間かかった(´;ω;`)こんなに手のかかったマイコンははじめてです。
現在はタイマーやスリープを実装したいのでドキュメントとにらめっこしています(*´Д`)
スリープのサンプルはあった。
https://github.com/raspberrypi/pico-playground