tmct-web

電子工作・DIYの製作例やノウハウを公開しています

openMSP430を使ってみる[ファームウェア編]

 

※この記事は3部に分かれています。以下の記事も併せてどうぞ。

Link
(1) openMSP430を使ってみる[導入・開発環境整備編]
この記事は導入〜開発環境整備・デモプロジェクトの構成説明までの内容です
(2) openMSP430を使ってみる[ハードウェア編]
ハードウェア・RTLのカスタマイズを紹介します
(3) openMSP430を使ってみる[ファームウェア編]
※この記事です
デモプロジェクト: https://github.com/tmct-web/omsp430_demo_tmct
この記事で使用しているデモプロジェクトはこのリンクからダウンロードしましょう

 

opemMSP430テスト環境

ファームウェアのカスタマイズとコンパイル

ファームウェアのカスタマイズも一体何から手をつけてよいのか迷いますね。
少なくとも以下のカスタマイズは必須です。

  • makeファイル
    コンパイルを行うための条件などを設定します。
    環境を移行した場合やソースファイルを追加したい場合は中身を変更する必要があります。

  • リンカースクリプト
    主にメモリ配置に関する設定です。
    RTLに記述した通りに変更する必要があります。

makeファイルのカスタマイズ

makeファイルは /firmware/makefile です。
環境移行・新しいプロジェクトを作るetc…で弄る必要があるのは主に以下の項目です。
※ちなみにmakeルールの記述部分はTabコードによって字下げされていますが、ここはスペースに置き換えできません。知らずに書き換えるとエラーがてハマるので注意。

(1)TARGET

出力ファイル名を設定します。
デモプロジェクトでは以下のように設定されており、 omsp_demo.bin および omsp_demo.elf が出力されます。

TARGET      = omsp_demo

(2)SOURCES

コンパイルするソースファイル名をスペース区切りで列挙します。
デモプロジェクトでは main.c、per_uart.c、per_i2c.c、ihandler.c の4つが設定されており、これらがコンパイルされます。

SOURCES     = main.c per_uart.c per_i2c.c ihandler.c

(3)INCDIR

msp430-gcc の include フォルダへのパスを設定します。
デモプロジェクトでは以下のように設定されていますが、環境に合わせて変更が必要です。

INCDIR          = -I C:\dev\msp430-gcc\include

リンカースクリプトのカスタマイズ

RTLで定義したプログラムメモリ・データメモリ容量に合わせてリンカースクリプト(*.x)を変更します。この設定が適切でないと、ファームウェアが起動しない・起動はするが不可解な挙動をする、変数の内容が化ける・変更できない、などの原因になります。
RAM は データメモリサイズをそのまま LENGTH に設定します。ORIGIN は変更しなくて構いません。
ROM は ORIGINに 0x10000 - (プログラムメモリサイズ) の値を設定し、LENGTH に (プログラムメモリサイズ) - 0x20 を設定します。0x20 というのは割り込みベクタ分のサイズです。

リンカースクリプトはコンパイラに合わせて linker.msp430-elf.x か linker.msp430.x のどちらかが使われます。
いずれもリンカースクリプトの先頭あたりにある領域の設定を変更します。

 

linker.msp430-elf.xをいじる場合:

MEMORY {
  SFR              : ORIGIN = 0x0000, LENGTH = 0x0010
  PERIPHERAL_8BIT  : ORIGIN = 0x0010, LENGTH = 0x00F0
  PERIPHERAL_16BIT : ORIGIN = 0x0100, LENGTH = 0x0100
  /* RAM: LENGTHにデータメモリの容量を設定する */
  /* 以下の例は 0x2000 = 8192 Bytes */
  RAM              : ORIGIN = 0x0200, LENGTH = 0x2000
  /* ROM: ORIGIN と LENGTH の両方をプログラムメモリの容量に合わせて設定する */
  /* 以下の例は 0x8000 = 32768 Bytes */
  ROM (rx)         : ORIGIN = 0x8000, LENGTH = 0x8000-0x20
  VECT1            : ORIGIN = 0xFFE0, LENGTH = 0x0002
  VECT2            : ORIGIN = 0xFFE2, LENGTH = 0x0002
}

 

linker.msp430.xをいじる場合:

MEMORY {
  sfr              : ORIGIN = 0x0000, LENGTH = 0x0010
  peripheral_8bit  : ORIGIN = 0x0010, LENGTH = 0x00f0
  peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100
  /* RAM: LENGTHにデータメモリの容量を設定する */
  /* 以下の例は 0x2000 = 8192 Bytes */
  ram (wx)         : ORIGIN = 0x0200, LENGTH = 0x2000
  /* ROM: ORIGIN と LENGTH の両方をプログラムメモリの容量に合わせて設定する */
  /* 以下の例は 0x8000 = 32768 Bytes */
  rom (rx)         : ORIGIN = 0x8000, LENGTH = 0x8000-0x20
  vectors          : ORIGIN = 0xffe0, LENGTH = 0x0020
}

ファームウェアのコンパイル

コンパイルを行うには、プロンプトから各ツール類にパスが通った状態でmakeを実行します。

make[Enter]

 

/firmware フォルダからデモプロジェクトを make したときの出力例を以下に示します。ビルドが正常に終了したなら以下のような表示になるでしょう。

C:\Users\tmct-web\omsp430_demo_tmct\firmware>make
if not exist output md output
if not exist obj md obj
msp430-elf-gcc -D PFX_MSP430_ELF -I C:\dev\msp430-gcc\include -O2 -Wall -g -mcpu=msp430 -mhwmult=16bit -c -o obj\main.o main.c
if not exist output md output
if not exist obj md obj
msp430-elf-gcc -D PFX_MSP430_ELF -I C:\dev\msp430-gcc\include -O2 -Wall -g -mcpu=msp430 -mhwmult=16bit -c -o obj\per_uart.o per_uart.c
if not exist output md output
if not exist obj md obj
msp430-elf-gcc -D PFX_MSP430_ELF -I C:\dev\msp430-gcc\include -O2 -Wall -g -mcpu=msp430 -mhwmult=16bit -c -o obj\per_i2c.o per_i2c.c
if not exist output md output
if not exist obj md obj
msp430-elf-gcc -D PFX_MSP430_ELF -I C:\dev\msp430-gcc\include -O2 -Wall -g -mcpu=msp430 -mhwmult=16bit -c -o obj\ihandler.o ihandler.c
msp430-elf-gcc -D PFX_MSP430_ELF -I C:\dev\msp430-gcc\include -O2 -Wall -g -mcpu=msp430 -mhwmult=16bit -T linker.msp430-elf.x -o output\omsp_demo.elf obj\main.o obj\per_uart.o obj\per_i2c.o obj\ihandler.o msp430-elf-objcopy -O binary --gap-fill 255 output\omsp_demo.elf output\omsp_demo.bin
.\bin\mifwrite output\omsp_demo.bin output\omsp_demo.mif
msp430-elf-objcopy -O ihex output\omsp_demo.elf output\omsp_demo.a43
msp430-elf-objdump -dSt output\omsp_demo.elf >output\omsp_demo.lst
msp430-elf-size  output\omsp_demo.elf >output\omsp_demo.size
C:\Users\tmct-web\omsp430_demo_tmct\firmware>

 

プロンプト出力を見てもらえばわかる通り、binファイルからmifファイル(プログラムメモリの初期値ファイル)を生成しています。
このファイルはFPGAをコンパイルするときに構成論理の一部として組み込まれるので、ファームウェアをコンパイルした後は必ずQuartusの [Processing] - [Update Memory Initialization File] でプログラムメモリの初期値をアップデートした後、FPGAをコンパイルし直してください。(通常はファイルの更新を自動検出してアップデートしてくれますが、たまに検出してくれないことがあります)
…これを知らないとファームウェアのどこを弄ってもプログラムメモリには変更が適用されないため、ハマります。

 

ファイルや中間オブジェクトファイルを削除したい場合は clean ルールを使用します。

C:\Users\tmct-web\omsp430_demo_tmct\firmware>make clean
del /f output\omsp_demo.a43 output\omsp_demo.lst output\omsp_demo.bin output\omsp_demo.mif output\omsp_demo.elf
output\omsp_demo.size obj\*.o
C:\Users\tmct-web\omsp430_demo_tmct\firmware>

FPGAのコンパイル

最後にFPGAをコンパイルすればハードウェア・ファームウェアの一連のカスタマイズは完了です。

コンパイル対象のファイル

デモプロジェクトでコンパイル対象になっているファイルを以下に示します。
ポイントとしては、ほかのモジュールに影響を与えないよう openMSP430 関連のファイルはまとめて定義した上で openMSP430_defines.v をその最初に、 openMSP430_undefines.v をその最後に登録します。
それ以外にもプログラムメモリやデータメモリ、PLLなどのIPも含めるのを忘れないようにしましょう。

File name Remarks
sdc/omsp430_demo_tmct.sdc SDCファイルがないとタイミングに関する警告が消えないので含めています。
気にしないなら無くても構いません。
rtl/omsp430_demo_top.v ボード固有のトップレベルエントリファイルです。
ip/datamem/datamem.qip データメモリのIPファイルです。
ip/progmem/progmem.qip プログラムメモリのIPファイルです。
ip/pll/media_pll.qip PLLのIPファイルです。
rtl/openMSP430_defines.v 構成を定義したファイルです。
デモプロジェクトでは /omsp430/openMSP430_defines.v ではなくボード固有ファイルとして rtl/openMSP430_defines.v を使用しているのでそちらを参照するよう設定します。
rtl/omsp430/openMSP430.v
rtl/omsp430/omsp_watchdog.v
rtl/omsp430/omsp_wakeup_cell.v
rtl/omsp430/omsp_sync_reset.v
rtl/omsp430/omsp_sync_cell.v
rtl/omsp430/omsp_sfr.v
rtl/omsp430/omsp_scan_mux.v
rtl/omsp430/omsp_register_file.v
rtl/omsp430/omsp_multiplier.v
rtl/omsp430/omsp_mem_backbone.v
rtl/omsp430/omsp_frontend.v
rtl/omsp430/omsp_execusion_unit.v
rtl/omsp430/omsp_dbg_uart.v
rtl/omsp430/omsp_dbg_i2c.v
rtl/omsp430/omsp_dbg_hwbrk.v
rtl/omsp430/omsp_dbg.v
rtl/omsp430/omsp_clock_mux.v
rtl/omsp430/omsp_clock_module.v
rtl/omsp430/omsp_clock_gate.v
rtl/omsp430/omsp_and_gate.v
rtl/omsp430/omsp_alu.v
rtl/omsp430/openMSP430_undefines.v openMSP430_defines.v で定義された内容を打ち消すために配置されます。
このファイルは openMSP430 関連のファイルの最後に配置します。
rtl/omsp430_periph_regs/regs_uart.v
rtl/omsp430_periph_regs/regs_i2c.v
rtl/omsp430_periph_regs/basic_gpio.v
rtl/basic_uart_tmct/uart_tmct_top.sv
rtl/basic_uart_tmct/uart_brgene.sv
rtl/basic_uart_tmct/uart_tx.sv
rtl/basic_uart_tmct/uart_rx.sv
rtl/i2c_master/i2c_master_top.v
rtl/i2c_master/timescale.v
rtl/i2c_master/i2c_master_defines.v
rtl/i2c_master/i2c_master_byte_ctrl.v
rtl/i2c_master/i2c_master_bit_ctrl.v

FPGAのコンパイル

サンプルの論理合成結果は以下の通りです。

Quartus II 64-Bit Version : 13.1.0 Build 162 10/23/2013 SJ Web Edition
Revision Name : omsp430_demo_tmct
Top-level Entity Name : omsp430_demo_top
Family : Cyclone III
Device : EP3C16F484C6
Timing Models : Final
Total logic elements : 2,504 / 15,408 ( 16 % )
    Total combinational functions : 2,454 / 15,408 ( 16 % )
    Dedicated logic registers : 823 / 15,408 ( 5 % )
Total registers : 823
Total pins : 26 / 347 ( 7 % )
Total virtual pins : 0
Total memory bits : 327,680 / 516,096 ( 63 % )
Embedded Multiplier 9-bit elements : 0 / 112 ( 0 % )
Total PLLs : 1 / 4 ( 25 % )

デバッグ

openMSP430 のデバッグにはいくつかの手段が用意されています。
ハードウェアを実装したばかりでCPUコアも動くか怪しい、という場合はまずミニデバッガで一通りの動作を確認することをお勧めします。

シリアルコンソールを使う

ファームウェアとして実装されているシリアルコンソールを使用すると、ファームウェア用UARTからテキストベースのコマンド授受によってハードウェアにアクセスすることができます。
通信仕様は以下の通りです。
使用する場合は上記「ファームウェア用UART」にパソコンのCOMポート(またはUSB-COM変換)を接続します。

  • Baud-rate: 38400
  • Start bits: 1 bit
  • Data bits: 8 bit
  • Stop bits: 1 bit
  • Parity bit: None
  • Flow control: None
  • Line feed code:
    Receive = CR or LF
    Transmit = CR + LF

 

テスト環境では以下の写真のようにGPIOピンヘッダに基板を接続し、USB-COM変換を介してパソコンに接続しました。
写真では2.2kΩのPull Up抵抗だけが見えていますが、基板の裏にはI2C EEPROMが載っています。

opemMSP430テスト環境

 

シリアルコンソールファームウェアが正常に起動するとUARTから > が出力され、入力待ち状態になります。
制御コマンドに続いてラインフィードコードが入力されるとそのコマンドに応じた動作を行った後、再び > を出力して入力待ち状態になります。
戻り値がある場合は > の前に出力されます。
操作感としてはWindowsのプロンプトやmacOSのシェルなどと同じようなイメージです。

制御コマンドとその書式を以下に示します。
パラメータは16進数かつ桁数はすべて固定です。2バイトのパラメータの先頭ゼロを省略して与えることはできません。
たとえばCPUバス空間のアドレス 0x90 に 0x01 を Write する場合、 sw009001[CR] を送ります。

Command Format Details
sr srxxxx CPUバス空間の指定アドレスの値をReadします
xxxx = アドレス(4桁の16進数ASCII文字)
sw swxxxxyy CPUバス空間の指定アドレスに値をWriteします
xxxx = アドレス(4桁の16進数ASCII文字)
yy = 値(2桁の16進数ASCII文字)
pr prxx GPIOから値をReadします
xx = ポート番号
このハードウェア構成では 00 と 01 のみサポートしています。
pw pwxxyy GPIOに値をWriteします
xx = ポート番号(01 のみ正常に機能します)
yy = 値(2桁の16進数ASCII文字)
ir irxxyy I2Cバスの指定デバイス・指定アドレスの値をReadします
xx = スレーブアドレス(2桁の16進数ASCII文字)
yy = デバイス内のアドレス(2桁の16進数ASCII文字)
iw iwxxyyzz I2Cバスの指定デバイス・指定アドレスに値をWriteします
xx = スレーブアドレス(2桁の16進数ASCII文字)
yy = デバイス内のアドレス(2桁の16進数ASCII文字)
zz = 値(2桁の16進数ASCII文字)

ミニデバッガを使う

ミニデバッガは openMSP430 内のデバッグ支援ハードウェアと連携してデバッグ環境を提供するものです。CPU空間への直接アクセスのほか、FPGAを再コンパイルすることなくプログラムメモリにファームウェアを動的に転送することもできます。(もちろん電源を切ると元に戻りますが。)
openMSP430_defines.v 内でデバッグインターフェイスを有効、かつプロトコルで DBG_UART を選択した場合に使用できます。
起動するにはまず ./tools/bin フォルダに移動した後、TCLシェルを立ち上げます。

C:\Users\tmct-web\omsp430_demo_tmct\firmware>cd .\tools\bin
C:\Users\tmct-web\omsp430_demo_tmct\firmware\tools\bin>tclsh
% 

‘%’ はTCLシェルのプロンプトです。
ここにミニデバッガを起動させるためのコマンドを入力します。
このとき、openMSP430 の デバッガ用UART と パソコンのCOMポート(またはUSB-COM) を接続しておく必要があります。(COMポートが1つもない場合、ミニデバッガは起動せずエラーが表示されます。)

% source openmsp430-minidebug.tcl

 

正常に起動するとデバッガのGUIが表示されます。

openMSP430 miniDebugger

openMSP430に接続する

[Device Port]にデバッガ用UARTと接続したCOM番号を設定し、[Connect]をクリックするとデバッグインターフェイスに接続されます。(自動ボーレートのためボーレート設定はそのままでOK)
正常に接続されると以下のような画面になります。

openMSP430 miniDebugger: Connection Successful

 

ここで以下のような挙動になる場合、FPGA側のマイコンコアが正常に機能していないか、UARTの結線が正しくありません。(TXとRXが逆・GND接続を忘れている、など)
その場合は結線やRTLを見直す必要があります。

  • 実行時エラーのようなダイアログが表示される
  • デバッガが勝手に終了する
  • 何も操作していないのに CPU Status が Stopped になる
  • [Reset]・[Run]・[Stop]の制御が利かない

なお、openMSP430_defines.v 内で DBG_RST_BRK_EN を定義している場合、Stopped の状態で起動します。
動作させるには毎回デバッガから [Run] する必要があるので、支障がある場合はこの定義を外してください。
これを知らないと「起動しない」とハマるので注意。

情報を見てみる

デバッガに接続された状態で [More…] をクリックするとコアの構成情報が表示されます。
この内容がRTLの構成と一致すれば、デバッガとコアの通信 および CPUコアの動作は問題ないと判断できます。

openMSP430 miniDebugger: More

デバッガの機能を使ってみる

試しにプログラムメモリの内容を吸い出して表示してみましょう。
CPU Control で [Stop] を押下し、[Read Program Memory!] をクリックします。
数秒〜十数秒待つと以下のようにダンプ結果が表示されます。

openMSP430 miniDebugger: Dump

 

そのほか、elfファイルをFPGAに動的に転送することもできます。(ただしあまり安定しているとは言えません…)

まとめ

openMSP430についてファームウェアのカスタマイズ・コンパイルとデバッガを利用したデバッグの方法を紹介しました。

以下の3部にわたって openMSP430 について説明しましたが、理解できたでしょうか?
とてもよくできたマイコンコアなのでぜひ積極的に使ってみてください!

 

Link
(1) openMSP430を使ってみる[導入・開発環境整備編]
この記事は導入〜開発環境整備・デモプロジェクトの構成説明までの内容です
(2) openMSP430を使ってみる[ハードウェア編]
ハードウェア・RTLのカスタマイズを紹介します
(3) openMSP430を使ってみる[ファームウェア編]
※この記事です
デモプロジェクト: https://github.com/tmct-web/omsp430_demo_tmct
この記事で使用しているデモプロジェクトはこのリンクからダウンロードしましょう
最終更新: 2022-09-18
作成: 2022-09-18
  • FPGA

© 2025 tmct-web All Rights Reserved.
Powered by Hugo. Theme by TechDoc. Designed by Thingsym.