2014/10/12からのアクセス回数 3073
FM3上のuCLinuxの動作確認しながら、どうやってユーザ用のプログラムをビルドしたら良いのかとはたっと気づいた。
UserAppsディレクトリを作成し、その中にアプリケーション用のディレクトリを作成します。
$ mkdir UserApps $ mkdir UserApps/hello $ cd UserApps/hello
uClinuxのコンパイルに使ったuclinuxeabiのToolchainを使い、インクルードファイル、ライブラリパスを 正しくセットすれば、uClinux上で動作することが分かりました。
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をビルドすることにします。
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をやり直します。
file /bin/hello UserApps/hello/hello 755 0 0
bootmで起動して、helloを動かして何とかHello Worldが出力できました。
/ # hello Hello World / #
Hello Worldのコンパイルができたので、今度はCプログラムからLEDを点滅させる Lチカ(blink)を試してみます。
lbedのDigitalOutをuClinuxで実装してみます。
DigitalOut.hは、以下の様にしました。
#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を使った実装になっています。
#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は、以下の様にします。
#include <unistd.h> #include "DigitalOut.h" main() { DigitalOut myled(243); for(int i = 0; i < 5; i++) { myled = ! myled; sleep(1); } }
アップロードしてブートした後、/sysにsysfsをマウントしてblinkを実行して LEDが点滅することを確認しました。
Freeing init memory: 204K Welcome to ____ _ _ / __| ||_| _ _| | | | _ ____ _ _ _ _ | | | | | | || | _ \| | | |\ \/ / | |_| | |__| || | | | | |_| |/ \ | ___\____|_||_|_| |_|\____|\_/\_/ | | |_| Fujitsu FM3/FM4 port. For further information check: http://www.uclinux.org/ / # mount -t sysfs sysfs /sys / # blink
皆様のご意見、ご希望をお待ちしております。勉強会で分からなかったこと等、お気軽に問い合わせて下さい。
スパム防止に画像の文字列も入力してください。