[[FrontPage]] #contents 2014/10/12からのアクセス回数 &counter; FM3上のuCLinuxの動作確認しながら、どうやってユーザ用のプログラムをビルドしたら良いのかとはたっと気づいた。 ** uclinuxeabiのToolchainを使う [#fdc80cc1] UserAppsディレクトリを作成し、その中にアプリケーション用のディレクトリを作成します。 #pre{{ $ mkdir UserApps $ mkdir UserApps/hello $ cd UserApps/hello }} uClinuxのコンパイルに使ったuclinuxeabiのToolchainを使い、インクルードファイル、ライブラリパスを 正しくセットすれば、uClinux上で動作することが分かりました。 #pre{{ export CFLAGS="-mcpu=cortex-m3 -march=armv7-m -mthumb -elf2flt -I/home/take/local/arm-2011.03/arm-uclinuxeabi/include -L/home/take/local/arm-2011.03/arm-uclinuxeabi/libc/thumb2/usr/lib -lc" arm-uclinuxeabi-gcc $CFLAGS -o hello hello.c }} そこで、以下のMakefileを使ってhello.cをビルドすることにします。 #pre{{ CC = arm-uclinuxeabi-gcc TOOL_DIR = /home/take/local/arm-2011.03 CFLAGS = -mcpu=cortex-m3 -march=armv7-m -mthumb \ -I$(TOOL_DIR)/arm-uclinuxeabi/include LDFLAGS = -elf2flt -lc -L$(TOOL_DIR)/arm-uclinuxeabi/libc/thumb2/usr/lib EXEC = hello OBJS = hello.o all: $(EXEC) $(EXEC): $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) clean: rm -f $(EXEC) *.elf *.gdb *.o }} initramfs_lfcq1_min.txtに以下の一行を追加してmake uImageをやり直します。 #pre{{ file /bin/hello UserApps/hello/hello 755 0 0 }} bootmで起動して、helloを動かして何とかHello Worldが出力できました。 #pre{{ / # hello Hello World / # }} ** CでLチカを試す [#ma3a0d9a] Hello Worldのコンパイルができたので、今度はCプログラムからLEDを点滅させる Lチカ(blink)を試してみます。 lbedのDigitalOutをuClinuxで実装してみます。 DigitalOut.hは、以下の様にしました。 #pre{{ #ifndefLBED_DIGITALOUT_H #defineLBED_DIGITALOUT_H typedefint PinName; class DigitalOut { public: DigitalOut(); DigitalOut(PinName pin); ~DigitalOut(); void setup(PinName pin); void write(int value); int read() { return _val; } DigitalOut& operator = (int value) { write(value); return *this; } DigitalOut& operator = (DigitalOut& rhs) { write(rhs.read()); return *this; } operator int() { return read(); } protected: PinName_pin; int_fd; int_val; }; #endif/* LBED_DIGITALOUT_H */ }} DigitalOut.cppは、/sys/class/gpioを使った実装になっています。 #pre{{ #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include "DigitalOut.h" #define NC (-1) #define SYSFS_GPIO_DIR "/sys/class/gpio" static char buf[64]; static int len; DigitalOut::DigitalOut() : _pin(NC), _fd(NC), _val(0) { } DigitalOut::DigitalOut(PinName pin) : _pin(NC), _fd(NC), _val(0) { setup(pin); } void DigitalOut::setup(PinName pin) { _pin = pin; len = sprintf(buf, "%s/export", SYSFS_GPIO_DIR); _fd = open(buf, O_WRONLY); if (_fd < 0) { printf("export error\n"); return; } len = sprintf(buf, "%d", _pin); ::write(_fd, buf, len); close(_fd); len = sprintf(buf, "%s/gpio%d/direction", SYSFS_GPIO_DIR, _pin); _fd = open(buf, O_WRONLY); if (_fd < 0) { printf("direction error: %s\n", buf); return; } ::write(_fd, "out", 4); close(_fd); write(_val); } void DigitalOut::write(int value) { if (_fd < 0) return; len = sprintf(buf, "%s/gpio%d/value", SYSFS_GPIO_DIR, _pin); _fd = open(buf, O_WRONLY); if (_fd < 0) { printf("set value error: %s\n", buf); return; } _val = value; if (value) ::write(_fd, "1", 2); else ::write(_fd, "0", 2); close(_fd); } DigitalOut::~DigitalOut() { len = sprintf(buf, "%s/unexport", SYSFS_GPIO_DIR); _fd = open(buf, O_WRONLY); if (_fd < 0) return; len = sprintf(buf, "%d", _pin); ::write(_fd, buf, len); close(_fd); } }} そしてこれらを使うblink.cppは、以下の様にします。 #pre{{ #include <unistd.h> #include "DigitalOut.h" main() { DigitalOut myled(243); for(int i = 0; i < 5; i++) { myled = ! myled; sleep(1); } } }} *** アップロードと実行 [#g81e793f] アップロードしてブートした後、/sysにsysfsをマウントしてblinkを実行して LEDが点滅することを確認しました。 #pre{{ Freeing init memory: 204K Welcome to ____ _ _ / __| ||_| _ _| | | | _ ____ _ _ _ _ | | | | | | || | _ \| | | |\ \/ / | |_| | |__| || | | | | |_| |/ \ | ___\____|_||_|_| |_|\____|\_/\_/ | | |_| Fujitsu FM3/FM4 port. For further information check: http://www.uclinux.org/ / # mount -t sysfs sysfs /sys / # blink }} ** 参考文献 [#n1fa22c3] + [[インタフェース2014/8月号 汎用軽量OS uClinuxを試す>http://www.kumikomi.net/interface/sample/201408/if08_125.pdf]] ** コメント [#u29eaa4f] #vote(おもしろかった,そうでもない,わかりずらい) #vote(おもしろかった[1],そうでもない[0],わかりずらい[0]) 皆様のご意見、ご希望をお待ちしております。勉強会で分からなかったこと等、お気軽に問い合わせて下さい。 スパム防止に画像の文字列も入力してください。 #comment_kcaptcha