2017年6月25日日曜日
りはびり:03
さて、話しは前後して、作ったプログラムを動かすマイコンボードの話。
パソコンプログラムと違って、組み込みプログラムはビルドしただけでは動かせない。
組み込みマイコンも市販品は数多くあるので何を使うかは迷うところだけれど、今回はストロベリー・リナックスさんのSTBee F4miniを使うことにする。
特にこれと言って理由はないけれど、あえて言えば、
・小さいこと
・手元にあること
・あまりネットに情報がないこと
、が選定理由でしょうか。
STBee Miniとはまた別の製品なので注意が必要です。
STBee F4miniの製品ページはこちら(https://strawberry-linux.com/catalog/items?code=32405)を参照。
使用マイコン:STM32F405RGT
メインクロック:12MHz
プッシュスイッチ:ポートA-0
ユーザLED:ポートD-2
ひとまず直近のプログラムでは、この情報がわかっていればいいです。
プログラムのライターソフトは、マイコンメーカのSTマイクロのDfuSeというソフトを使います。
リンクはこちら(http://www.st.com/ja/development-tools/stsw-stm32080.html)。
DfuSeを使ったプログラムの書き込み手順は、ストロベリー・リナックスのこちらのページ(http://strawberry-linux.com/stbee/dfuse)が詳しい。
※紹介ページのマイコンボードはSTBeeです。STBee F4miniとは違いますので注意です。
さて、DfuSeで書き込めるファイル形式は、*.dfuです。
前回gccで生成したmain.elfはそのままでは書き込めませんので、変換作業が必要です。
dfu形式のファイルを作るには、DFU File Managerを使いますが、このソフトで扱えるのはS19形式、HEX形式、BIN形式です。今回は、以下のコマンドでHEX形式のファイルを生成します。
> arm-none-eabi-objcopy -O ihex main.elf main.hex
他の作業はストロベリー・リナックスのサイトのやり方と同じです。
※GUI操作なので、超面倒です。
コマンドライン操作の方法は次回。
2017年6月21日水曜日
りはびり:02
前回の続き。
main.cをコンパイルしたらエラーになる話。
> arm-none-eabi-gcc.exe main.c -o main
arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2.exe: error: ld returned 1 exit status
この_exitは参照した覚えがない。
C言語の勉強をすると、ほぼ必ず、「C言語はmain関数から始まります」と教えられる。
基本的にはそれで正しいのだと思うけれど、組み込みC言語の目線では正しくない。
組み込みの世界ではmain関数を呼び出すためのスタートアップルーチンという裏方さんに、どんな仕事をしてほしいか、きっちり教えて上げる必要がある。
教育の機会に恵まれない裏方さんは、とりあえず万人向けの仕事をしようとする。その仕事の一つが_exitという処理なのだ(難しい話なので抽象化して書いてます)。
ひとまず、裏方さんには大人しくしていて貰いたいので、「-nostartfiles」というオプションをつけてコンパイルしてみます。このオプションについてはgccの公式ページを見てください。
>arm-none-eabi-gcc main.c -o main.o -nostartfiles
arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol _start; defaulting to 00008000
今度はwarningが発生しています。_startのエントリがないので、デフォルトの00008000にするよ、というメッセージです。
何を言っているのか、分かりませんね。
うまく説明できないので強引に対策だけいうと、リンカスクリプトをオプションで指定します。
「-T ./STM32F405RGT6.ld」です。
STM32F405RGT6.ld ファイルは、ねむいさんが公開されているサンプルコードから流用させてもらいました。STマイクロのサンプルコード集にも別マイコン用のリンカスクリプトがあるので、それをもとに自分で作れる人は頑張ってください。
ちなみに、「STM32F405RGT6.ld」は内部で「STM32F40_41xxx_FLASH.ld」を呼び出しているので、同じフォルダにおいておきます。
>arm-none-eabi-gcc main.c -o main.o -nostartfiles -T ./STM32F405RGT6.ld
ひとまずエラーはでなくなった。
最後に、main.oをgccが出力する実行形式のelf形式に変換します。
>arm-none-eabi-gcc -nostartfiles -T ./STM32F405RGT6.ld main.o -o main.elf
今日はここまで。
エラーが出なくなったからって、動くものが出来たわけではないのが、組み込みの怖いところ。(笑)
main.cをコンパイルしたらエラーになる話。
> arm-none-eabi-gcc.exe main.c -o main
arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2.exe: error: ld returned 1 exit status
この_exitは参照した覚えがない。
C言語の勉強をすると、ほぼ必ず、「C言語はmain関数から始まります」と教えられる。
基本的にはそれで正しいのだと思うけれど、組み込みC言語の目線では正しくない。
組み込みの世界ではmain関数を呼び出すためのスタートアップルーチンという裏方さんに、どんな仕事をしてほしいか、きっちり教えて上げる必要がある。
教育の機会に恵まれない裏方さんは、とりあえず万人向けの仕事をしようとする。その仕事の一つが_exitという処理なのだ(難しい話なので抽象化して書いてます)。
ひとまず、裏方さんには大人しくしていて貰いたいので、「-nostartfiles」というオプションをつけてコンパイルしてみます。このオプションについてはgccの公式ページを見てください。
>arm-none-eabi-gcc main.c -o main.o -nostartfiles
arm-none-eabi/bin/ld.exe: warning: cannot find entry symbol _start; defaulting to 00008000
今度はwarningが発生しています。_startのエントリがないので、デフォルトの00008000にするよ、というメッセージです。
何を言っているのか、分かりませんね。
うまく説明できないので強引に対策だけいうと、リンカスクリプトをオプションで指定します。
「-T ./STM32F405RGT6.ld」です。
STM32F405RGT6.ld ファイルは、ねむいさんが公開されているサンプルコードから流用させてもらいました。STマイクロのサンプルコード集にも別マイコン用のリンカスクリプトがあるので、それをもとに自分で作れる人は頑張ってください。
ちなみに、「STM32F405RGT6.ld」は内部で「STM32F40_41xxx_FLASH.ld」を呼び出しているので、同じフォルダにおいておきます。
>arm-none-eabi-gcc main.c -o main.o -nostartfiles -T ./STM32F405RGT6.ld
ひとまずエラーはでなくなった。
最後に、main.oをgccが出力する実行形式のelf形式に変換します。
>arm-none-eabi-gcc -nostartfiles -T ./STM32F405RGT6.ld main.o -o main.elf
今日はここまで。
エラーが出なくなったからって、動くものが出来たわけではないのが、組み込みの怖いところ。(笑)
2017年6月15日木曜日
りはびり:01
しばらく組み込みから離れていたので、リハビリがてらARMマイコンで動くプログラムをコマンドラインでコンパイル・ビルドする方法を勉強しなおす。
基本的な開発環境は「ねむいさんのぶろぐ(http://nemuisan.blog.bai.ne.jp/?eid=188089)」を参考に構築しています。
コーディングに使うエディタは秀丸エディタを使用します。
coreutilsとかlaunchpadとかへのパスはwindowsの環境変数にセットしています。
まずは、とてもシンプルなプログラムを作ってみます。
main.c
int main(void) { return 10; }
これをコンパイルしてみます。
> arm-none-eabi-gcc.exe hello.c -o hello arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit': exit.c:(.text.exit+0x2c): undefined reference to `_exit' collect2.exe: error: ld returned 1 exit status
なにやらエラーになりました。
未定義の_exitを参照していると言われています。そんなの参照している覚えはないのですけどね。
続きは次回。
登録:
投稿 (Atom)