= TOPPERS/SSP Kernel for ARMv6-M (separate package) = * ARMv6-Mプロセッサ向けTOPPERS/SSPカーネルの個別パッケージです. * 動作確認済みターゲットボード * [https://www.nxp.com/design/microcontrollers-developer-resources/lpc-microcontroller-utilities/lpc812-lpcxpresso-board:OM13053 LPC812-LPCXpresso Board] * [https://www.nxp.com/design/microcontrollers-developer-resources/lpc-microcontroller-utilities/lpcxpresso812-max-board-for-lpc81x-family-mcus:OM13055 LPCXpresso812-MAX Board] * 動作確認方法 * [https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE MCUXpresso IDE]を利用する方法 * NXPが提供しているマイコン向けの統合開発環境です.上記のどちらのボードでも利用可能です. * [http://openocd.org/ OpenOCD] + [https://www.gnu.org/software/gdb/ GDB] を利用する方法 * LPCXpresso812-MAX ボードはCMSIS-DAPをサポートしたデバッグインタフェース回路を搭載しており,OpenOCDとGDBを利用してリモートデバッグできます. = ソースコードのセットアップ == あらかじめ必要なもの * [https://www.docker.com/ Docker] : 「コンテナ」と呼ばれる仮想環境を動かすために使います.仮想環境にLinuxプログラムの実行環境を構築します.[http://releases.ubuntu.com/xenial/ Ubuntu xenial] ベースのLinuxシステムをお使いの場合は手順2.で使用するスクリプトを直接実行することもできます. * [https://git-scm.com/ Git] : バージョン管理システム.ここではDockerのスクリプトを取得するのに使います.コンテナ内でもGitを使用してソースコードを取得するのに利用しています. * コマンドライン環境:コマンドの実行にbashシェルを使います.Mac ならターミナルアプリ,Windowsなら [https://docs.microsoft.com/en-us/windows/wsl/about Windows Subsystems for Linux] などでも利用可能です. 以下ではMacOSのターミナルアプリで作業する際の様子を示します.他のホストOSで使用する場合もほぼ同様と思います.行頭の '$' はプロンプトを示します. === 1. Dockerコンテナの構築およびシェルの起動 ==== 1-1 Dockerスクリプトの取得 カレントディレクトリに docker-toppers というディレクトリが作成されます. {{{ $ git clone https://github.com/nmiri-nagoya-nsaito/docker-toppers.git }}} ==== 1-2 スクリプトのディレクトリへ移動し,コンテナのシェルを起動(詳細はスクリプト参照) {{{ $ cd docker-toppers $ ./start_shell.sh specified service: cli Building cli Step 1/19 : FROM ubuntu:xenial xenial: Pulling from library/ubuntu fe703b657a32: Pull complete (略) Step 19/19 : ENTRYPOINT ["sh", "-c", "./scripts/common/entrypoint.sh"] ---> Running in 47ee7ac43559 Removing intermediate container 47ee7ac43559 ---> 18d4bf66fc44 Successfully built 18d4bf66fc44 Successfully tagged docker-toppers_cli:latest Creating network "docker-toppers_default" with the default driver Creating docker-toppers_cli_1 ... done saito@06f7b820ab63:~$ ls }}} この時点で Linux コンテナ内のシェルが起動しており,以降の作業はこのシェルで行います.次はカーネルのソースコードをセットアップおよびビルドします. === 2. ソースコードのセットアップおよびビルド ==== 2-1 作業ディレクトリへ移動 {{{ saito@06f7b820ab63:~$ cd workdir }}} ==== 2-2 本パッケージをダウンロード ssp_armv6m というディレクトリにファイルがダウンロードされます. {{{ saito@06f7b820ab63:~/workdir$ svn co http://dev.toppers.jp/svn_user/contrib/ssp_armv6_m_gcc/trunk ssp_armv6m A ssp_armv6m/install.sh A ssp_armv6m/armv6_m_gcc A ssp_armv6m/armv6_m_gcc/arm_m.h (以下略) }}} ==== 2-3 カーネルコードのセットアップ及びビルド 注意 * このスクリプトは$HOME/workdirが存在することを仮定 * dockerを使わずにスクリプトを実行する場合は,カレントディレクトリに toppers_workdirというディレクトリが作成され,作業が継続される {{{ saito@06f7b820ab63:~/workdir$ ssp_armv6m/build_ssp.sh ヒット:1 http://archive.ubuntu.com/ubuntu xenial InRelease 取得:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [109 kB] ヒット:3 http://security.ubuntu.com/ubuntu xenial-security InRelease (略) patching file target/cq_frk_fm3_gcc/Makefile.target Generating Makefile from ../sample/Makefile. ruby ../cfg/cfg.rb --pass 1 --kernel ssp -I. -I../include -I../arch -I../target/lpcxpresso_lpc812_gcc -I../arch/armv6_m_gcc -I.. -I../sample -I./gen -I../tecs_kernel --api-table ../kernel/kernel_api.def --symval-table ../kernel/kernel_sym.def --symval-table ../syssvc/syssvc_sym.def --symval-table ../target/lpcxpresso_lpc812_gcc/target_sym.def --symval-table ../arch/armv6_m_gcc/prc_sym.def \ -M deps/cfg1_out_c.d ../target/lpcxpresso_lpc812_gcc/target_kernel.cfg ../sample/sample1.cfg [cfg.rb] Generated cfg1_out.c arm-none-eabi-gcc -c -MD -MP -MF deps/cfg1_out.d -O2 -Wall -g -mcpu=cortex-m0 -mthumb -DTOPPERS_OMIT_TECS -D__NEWLIB__ -DTOPPERS_LABEL_ASM -I. -I../include -I../arch -I../target/lpcxpresso_lpc812_gcc -I../arch/armv6_m_gcc -I.. -I../sample -I./gen -I../tecs_kernel -DTOPPERS_CB_TYPE_ONLY -DALLFUNC -fno-strict-aliasing -I../kernel -I ../extension cfg1_out.c arm-none-eabi-gcc -c -O2 -Wall -g -mcpu=cortex-m0 -mthumb -DTOPPERS_OMIT_TECS -D__NEWLIB__ -DTOPPERS_LABEL_ASM -I. -I../include -I../arch -I../target/lpcxpresso_lpc812_gcc -I../arch/armv6_m_gcc -I.. -I../sample -I./gen -I../tecs_kernel -DALLFUNC -fno-strict-aliasing -I../kernel -I ../extension ../arch/armv6_m_gcc/start.S (略) arm-none-eabi-ranlib libkernel.a arm-none-eabi-gcc -O2 -Wall -g -mcpu=cortex-m0 -mthumb -DTOPPERS_OMIT_TECS -D__NEWLIB__ -DTOPPERS_LABEL_ASM -I. -I../include -I../arch -I../target/lpcxpresso_lpc812_gcc -I../arch/armv6_m_gcc -I.. -I../sample -I./gen -I../tecs_kernel -nostdlib -nostdlib --entry=_start -T ../target/lpcxpresso_lpc812_gcc/lpcxpresso_lpc812.ld -L. -o ssp \ sample1.o log_output.o vasyslog.o banner.o serial.o syslog.o logtask.o kernel_cfg.o \ -lkernel -lc -lgcc arm-none-eabi-nm -n ssp > ssp.syms arm-none-eabi-objcopy -O srec -S ssp ssp.srec ruby ../cfg/cfg.rb --pass 3 --kernel ssp -O -I. -I../include -I../arch -I../target/lpcxpresso_lpc812_gcc -I../arch/armv6_m_gcc -I.. -I../sample -I./gen -I../tecs_kernel -T ../target/lpcxpresso_lpc812_gcc/target_check.trb \ --rom-symbol ssp.syms --rom-image ssp.srec configuration check passed }}} 以上まで終了すると <カレントディレクトリ>/ssp/build/ に実行プログラムファイル(ssp)が生成されます. = 実行確認 == 必要なもの サンプルプログラムはシリアルポートを使用しますので,あらかじめ以下のものが必要です. * UART通信モジュール * PCとシリアル通信するために使用します.たとえば[http://akizukidenshi.com/catalog/g/gK-01977 こちら]のようなものがあればよいでしょう * マイコンボード(LPC812)とUART通信モジュールとの結線: * LPC812ボードの GND, P0_0(RX), P0_4(TX) を使用 * ブレッドボードを使用すると簡単に結線して試すことが出来ます. * '''ボードの入出力ピンの電圧は 3.3v''' であるため,UARTモジュール側の電圧もそれにあわせること * 端末エミュレータソフト. * シリアル通信結果を確認するために使用します.Windowsの場合,たとえば [http://osdn.jp/projects/ttssh2/ Tera Term] のようなものがあればよいと思います. * 通信条件 19200bps, 8bit, 1stop, parity-none, no-flow ターゲットボードへのプログラム転送および実行の方法として,MCUXpresso IDEを使う方法と,OpenOCD+GDBを使う方法があります. == [https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE MCUXpresso IDE] を用いた動作確認 ホスト上で MCUXpresso IDE を使用してビルド,デバッグします.docker-composeの設定により,コンテナのworkdir ディレクトリは共有されていてホストマシンから参照できますので,その中の ssp ディレクトリをIDEからインポートします. === 必要なもの * [https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE MCUXpresso IDE] * コンパイルやデバッグに使用します.ダウンロードにはユーザ登録が必要です.またダウンロードの際はホストマシン上で動作するものを選びます.動作確認にはMCUXpresso IDE v11.1.1 を使用しました. === プロジェクトのインポート * メニュー「File --> Import」でダイアログを開く. * ダイアログで「Makefile Project with Existing Code」を選び,Nextを押す. * 「Import Existing Code」ダイアログで設定を入力し,Finish を押す.するとプロジェクトが生成される. * Project Name :適当な名称をつける * Existing Code Location:「Browse」ボタンを押し,ssp ディレクトリを選択してOpen を押す. * Toolchain for Indexer Settings:NXP MCU Tools を選ぶ * Project Explorer で作成したプロジェクトを選択し,メニュー「Project --> Properties」を選ぶ.するとプロジェクトのプロパティ設定ダイアログが開く. * プロジェクト設定のダイアログで以下の設定をし,「Apply and Close」 ボタンを押す. * C/C++ Build * Build location の Build directory:「${workspace_loc:/ssp}/build」 * C/C++ Build --> Environment に環境変数を追加 * 変数名:「RUBYOPT」,値:「-EUTF-8」 * C/C++ Build --> MCU Setteings * SDK MCUs から LPC812 を選択 === ビルド * メニュー「Project --> Build Project」を選び,ビルドする. === デバッグ設定 * メニュー「Run --> Debug Configurations」を選ぶ.ダイアログが表示される. * ダイアログで,設定を行い,「Apply」で設定反映 および「Debug」を押してデバッグを開始する. * C/C++(NXP Semiconductors) MCU Application --> <デバッグ設定名> * 「Main」タブの「C/C++ Application」に実行ファイルを指定する * 「Search Project」ボタンを押し,一覧から「ssp」を選んでOKを押す. * 「GDB Debugger」タブの「GDB Debugger」が「arm-none-eabi-gdb」であることを確認 * デバッグ開始すると,デバッグ用プローブの選択ダイアログが表示される.「LPC11U3x CMSIS-DAP」を選択して「OK」を押す. * プログラムの実行が開始される. ステップ実行やブレークポイントの設定,MTB(Micro Trace Buffer) など使用方法の詳細についてはツールの説明文書を参照してください. == [http://openocd.org/ OpenOCD] + [https://www.gnu.org/software/gdb/ GDB] を用いた動作確認 ホスト上でOpenOCDを起動し,それをGDBサーバとしてコンテナ内のGDBからリモート接続する方法です. === 必要なもの * [http://openocd.org/ OpenOCD] * ホストマシン上で動作し,ターゲットボードと接続して状態の確認やフラッシュメモリへの書き込みに使います.[https://www.gnu.org/software/gdb/ GDB] を利用したリモートデバッグではGDBサーバとしても機能します. * Linux(Ubuntu)の場合は APT, MacOS の場合は [https://brew.sh/index_ja HomeBrew]などのパッケージマネージャでインストールできます. * ターゲット向けGDB(arm-none-eabi-gdb) * コンテナ内で動作し,ビルドした実行ファイルをOpenOCD経由でターゲットに転送および実行確認するのに使います. コンテナ環境でのソースのビルドは先の「2-3 カーネルコードのセットアップ及びビルド」の手順で完了しているので,ここではGDBでターゲットに転送する手順を示します. === OpenOCDの起動 カレントディレクトリが workdir ディレクトリであるとします. {{{ $ openocd -f ssp/target/lpclpcxpresso_lpc812_gcc/openocd_lpc812max.cfg Open On-Chip Debugger 0.10.0 Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : auto-selecting first available session transport "swd". To override use 'transport select '. adapter speed: 10 kHz adapter_nsrst_delay: 200 cortex_m reset_config sysresetreq Info : CMSIS-DAP: SWD Supported Info : CMSIS-DAP: Interface Initialised (SWD) Info : CMSIS-DAP: FW Version = 1.10 Info : SWCLK/TCK = 1 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1 Info : CMSIS-DAP: Interface ready Info : clock speed 10 kHz Info : SWD DPIDR 0x0bc11477 Info : lpc8xx.cpu: hardware has 4 breakpoints, 2 watchpoints }}} OpenOCD はこの状態でポート3333番で接続を待ち続けるため,コンテナからGDBで接続します. 終了する時は Ctrl-C を押します. === ターゲット向けGDBの起動 ssp/build に移動し,gdb を起動します. {{{ saito@06f7b820ab63:~/workdir/ssp/build$ arm-none-eabi-gdb ssp GNU gdb (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 8.3.0.20190709-git Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-apple-darwin10 --target=arm-none-eabi". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ssp... }}} === ターゲットへの接続および実行プログラムの転送 ==== 接続 {{{ (gdb) target remote localhost:3333 Remote debugging using localhost:3333 _kernel_prc_terminate () at ../arch/armv6_m_gcc/prc_config.c:198 198 ; }}} [https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds MacOSでコンテナ内部からホストに接続する際は特別なホスト名を使用します.] {{{ (gdb) target remote host.docker.internal:3333 Remote debugging using host.docker.internal:3333 _kernel_prc_terminate () at ../arch/armv6_m_gcc/prc_config.c:198 198 ; }}} ==== 設定 {{{ (gdb) set remotetimeout 10000 (gdb) monitor reset (gdb) monitor halt target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000170 msp: 0x10000730 }}} ==== 転送 {{{ (gdb) load Loading section .text, size 0x28d4 lma 0x0 Loading section .rodata, size 0x928 lma 0x28d4 Loading section .data, size 0x8 lma 0x31fc Start address 0xc0, load size 12804 Transfer rate: 962 bytes/sec, 4268 bytes/write. }}} === 実行開始 {{{ (gdb) c Continuing. }}} プログラムの実行を止める時は Ctrl-C を押します. また,GDBのプロンプトで quit コマンドを実行するとGDBを終了します. {{{ ^C Program received signal SIGINT, Interrupt. _kernel_prc_terminate () at ../arch/armv6_m_gcc/prc_config.c:198 198 ; (gdb) q A debugging session is active. Inferior 1 [Remote target] will be detached. Quit anyway? (y or n) y Detaching from program: /Users/saito/work/toppers/docker-toppers/workdir/ssp/build/ssp, Remote target Ending remote debugging. }}} == コンテナの終了および再開 コンテナのシェルを抜ける場合は exit を実行します. 再度シェルを起動する場合は ./start_sherll.sh を実行します. {{{ saito@06f7b820ab63:~/workdir/ssp/build$ exit ログアウト $ }}} == 注意事項 * SSP-1.3.0 のパッケージに含まれるファイルの文字コードは EUC-JP でしたが,Ruby版コンフィギュレータを使用するために UTF-8 に変換しています.したがってファイルを追加,編集する場合は UTF-8 を使用してください. * Windows版のgitで core.autocrlf が true に設定されている場合,シェルスクリプトの実行に失敗することがあるようです.その場合は `git config` コマンドで `core.autocrlf` を `false` に設定してみてください.