2022年11月30日水曜日

TOPPERS/ASP - MSP430版 目次

ようやく全部書き終えたので、以下MSP430版に関する記事の目次です。


■TOPPERS/ASP - MSP430版 その1

TOPPERS/ASP - MSP430版 概要

必要なもの

ダウンロード/GitHub


■TOPPERS/ASP - MSP430版 その2

開発環境の構築(コンパイラ編)


■TOPPERS/ASP - MSP430版 その3

開発環境の構築(IDE編)


■TOPPERS/ASP - MSP430版 その4

プロジェクトの作成


■TOPPERS/ASP - MSP430版 その5

プログラムの転送とデバッグ


■TOPPERS/ASP - MSP430版 その6

サンプルプロジェクトの説明

MSP430版カーネルについて

ライセンスについて


■TOPPERS/ASP - MSP430版 その7

デバッグ・シリアル出力の問題



なお、Qiitaにも上記の記事を1ページにまとめたダイジェスト版を投稿しました。

こっちの方が読み易いです。

是非参考にしてください。

Qiita

2022年11月28日月曜日

TOPPERS/ASP - MSP430版 その7

前回からの続きです。

このテーマを最初からご覧になる場合はこちらからどうぞ。


デバッグ・シリアル出力の問題

さて、TOPPERS/ASPのMSP430版の説明は全て書き終えたつもりですが、どうしても納得行かない点が一つだけ残っています。

気が付いている方は慧眼でいらっしゃる。

サンプルプログラムの実行中にTeraTermへ出力されるメッセージの出方がどうも気に入らないのです。

スムーズじゃないサンプルプログラムの出力


他のターゲットでは「task1 is running...」が一行ずつスムーズに出力されるのに対し、今回の評価ボード「MSP-EXP430F5529LP」にTOPPERSを載せた場合に、これが何故か二行ずつ出力されるのです。

ダラダラっ、ダラダラっと…。

気持ち悪いです。

最初はOSに実装したシリアル通信ドライバのバグかと思って修正を試みましたが、特に悪い点は見つからず、ドライバの問題ではないと結論付けました。

その証拠に…。

サンプルプログラムが動作している最中にプログラムを停止させます。

プログラムの停止ボタン


すると、ターゲットはリセットに入り、フラッシュROMに書き込まれたプログラム、すなわちサンプルプログラムをまた最初から実行します。

その際の出力メッセージはちゃんと「task1 is running...」が一行ずつスムーズに出力されます。


何故でしょう…?


今回の評価ボード「MSP-EXP430F5529LP」はデバッガを積んでいます。

このデバッガは「eZ-FET lite」といって、その正体はデバッガの機能をプログラミングされた「MSP430F5528」という型番の、これまたMSP430マイコンです。

ナナメに付いている石がそれです。

(メインCPUと1文字違いの型番っていうのも、なんだかなぁ…。)

eZ-FET lite


で、この「eZ-FET lite」のMSP430マイコン、デバッガのお仕事の他にUSB/シリアル通信変換機能をも司っているようです。

もしかして、出力メッセージがスムーズじゃないのは、デバッガの機能とUSB/シリアル通信変換を同時に行っているため、処理が一杯一杯になっているのでは?

であるならば、少なくともUSB/シリアル通信変換は「eZ-FET lite」にはやらせず、別の手段で代用してみよう、と思いました。

幸いにして、以下のように「eZ-FET lite」の脇にメインCPUからのシリアル信号(RXDとTXD)が出ています。

ジャンパーピン


この部分のジャンパーピンを外して「eZ-FET lite」をUSB/シリアル通信変換から開放してあげましょう。

そして、以下のような市販のUSB/シリアル通信変換ケーブルを用意します。

市販のUSB/シリアル通信変換ケーブル


このケーブルをジャンパーピンを外した「MSP-EXP430F5529LP」のシリアル信号(RXDとTXD)と接続します。

GNDは適当な所から引っ張ってきましょう。

「MSP-EXP430F5529LP」側の配線


シリアルの信号を横から掻っさらう感じですね。

市販のUSB/シリアル通信変換ケーブル側の配線


こんな感じ。

評価ボードとケーブルの接続


さて、市販のUSB/シリアル通信変換ケーブルをパソコンに接続し、TeraTermの接続ポートをこのケーブルのものに変更して、サンプルプログラムを実行してみると…。

スムーズに「task1 is running...」が一行ずつ出力されるじゃありませんか!

スムーズなサンプルプログラムの出力


推測通り、評価ボード「MSP-EXP430F5529LP」に内蔵されている「eZ-FET lite」は、非力なマイコンで処理を行っているため、負荷がかかるとシリアル出力の処理落ちが発生することが分かりました。

まあ、タダで付いてくるデバッガだから文句は言えませんし、ただデバッグメッセージを表示したいだけなら何もスムーズでなくて構いません。

何より肝心のデバッグ機能に問題が出るわけではないので良しとしましょうか!

…バグだと思って、ちょっと焦ったじゃないか!


<終わり>

2022年11月26日土曜日

1chipMSXを発掘!?

こちらの記事で触れた会社のデスクのダンボール。

今日も探し物をしていると、ダンボールの一番奥底からコレを発見!

1chipMSX本体


中身は新品同様だけど箱はそれなりにボロボロ!

1chipMSXの外箱


2006年頃に発売されたMSX2相当の機能を持つ「1chipMSX」です。

そういや買った覚えがあるな~。

家でMSXを使う時は、パナソニックの「FS-A1」が現役なので、そればかりで遊んでいます。

なので、この1chipMSX、最近家で見ないなぁ~と思っていたら、まさか会社に置いてあるとは!

なにか仕事で使おうとしていたのでしょうか?

というのも、この1chipMSXは全てFPGAでMSX2相当の機能を実装しており、優れたFPGAの評価ボードとしての利用価値も持ち合わせています。

当時のツワモノは、独学でこれにロジックを付け加えて本来の「MSX2」より上位の「MSX2+」の機能を実装した方も居たとか居ないとか。

私がこれを会社に持ってきた理由は、おそらくこれを使ってVerilogやらVHDLやらの言語を学習したかったのでしょうかね。

さて内容物は以下の通り。


●本体

●ACアダプター

●取扱説明書

●CD-ROM

1chipMSXの内容物


付属のCD-ROMの中にはFPGAのソースを含む技術情報が満載。

これは貴重なデータ!

良い機会なので、CD-Rが劣化して読めなくなる前に中身をバックアップしましたよ…。

さて、本体のインターフェースは…?

先ずは前面。

左から…


●USBホスト(確か使えない)

●PORT A/B(コントローラーを接続して使えます!)

●SD/MMCスロット(仮想FDドライブ)

1chipMSXのインターフェース - 前面


次に背面のインターフェース。

左から…


●PS/2ポート(キーボードを接続)

●VGA15ピン(モニターを接続)

●S端子

●ビデオ・サウンド同軸コネクタ

●電源(5V)

1chipMSXのインターフェース - 背面


PS/2ポートとVGA15ピンというのが、時代を感じますなぁ。

問題は、コイツはまだ生きているのか?

動作確認をしてみましょう。

昔の私が変な改造をして、壊れてなければ良いけれど…。

電源ON!

おお!ノスタルジックなロゴ!!

1chipMSX起動画面


やった!BASIC動いた!

よしよし、壊れてはいないみたい。

念のため持ち帰って、スロットにゲームを刺して検証してみましょうか。

1chipMSXのBASIC


この1chipMSX、当時の価格が20790円、そして現在はプレミアが付いてヤフオクなどでは5万円から、箱付きであれば10万円くらいで取引されているようです。

(私は売らないよ?食べるものが無くなったら考えますが…)

ただねぇ…よっぽどのマニアでもない限りは手を出すのは止めておいたほうが良いでしょうね。

というのも、以前このブログで書いた「MSX DEVCON 1 Tokyo」の記事の中にあるように、西さん、これとよく似た筐体を「MSX3」としてツイートしてるんですよね。

ということは、この1chipMSXよりも遥かに高性能で完成度が高い新型が今後出てくることは間違いないです。

守秘義務の関係で詳しくは言えませんが、更に本来のMSXの形に近い製品の発売も予定されています。

なので、そういった物に備えてお金を取っておいたほうが良いですよ。

それでも落札するって人は尊敬します!

真の「」だからです。


さてさて、私の不思議なダンボール。

今度は何が出てくるかな?

いいかげんに整理整頓しろ!って言わないで。

2022年11月23日水曜日

TOPPERS/ASP - RL78版 その1

TOPPERS/ASP - RL78版 概要

半導体メーカー大手、ルネサスエレクトロニクスの16Bitマイコン「RL78」です。

ルネサスエレクトロニクスの16Bitマイコン「RL78」


ルネサスエレクトロニクスは、いくつかの種類の16Bitマイコンを販売していますが、新規の採用を推奨されているものは、このシリーズと「R8C」だけです。

むか~しむかし、日立製作所は「H8」という16Bitマイコンを売っていました。

一方同じ頃、三菱電機が「M16C」という16Bitマイコンを売っていました。

ある時、この2社それぞれの半導体部門が分社、その半導体部門同士が合併し「ルネサステクノロジ」という会社ができました。

ルネサステクノロジは「M16C」の後継として、新たに「R8C」という16Bitマイコンを作りました。

しばらくして、そこへNECエレクトロニクスがやってきました。

NECエレクトロニクスは「78K0R」という16Bitマイコンを売っていました。

NECエレクトロニクスは仲間になりたそうにルネサステクノロジを見ています。


な なんと 半導体メーカーたちが・・・!

半導体メーカーたちが どんどん がったいしていく!


なんと ルネサスエレクトロニクスに なってしまった!


ルネサステクノロジとNECエレクトロニクスが合併、「ルネサスエレクトロニクス」という会社ができました。

ルネサスエレクトロニクスは「78K0R」の後継として、新たに「RL78」という16Bitマイコンを作りました。

さて、合併を繰り返して成立したルネサスエレクトロニクスは、この時点で多くの16Bitマイコンのシリーズを抱えていることになりました。

当然、同じようなカテゴリーの製品が重複するのは経営効率が悪いのでシリーズの淘汰が始まります。

まず「M16C」と「78K0R」に関しては、それぞれの後継機種が出ているので収束。

「R8C」は低コスト化、コンパクト化を推し進めて、さながら8Bitマイコンとしての立ち位置に移行。

残るは「H8」と「RL78」です。

この頃、私は「H8」を仕事に趣味にとジャンジャン愛用しており、性能、入手性の良さ、ラインナップの豊富さやペリフェラルの使い易さを気に入っていたので、「H8」だけ後継機種が出ていなくとも今後もメーカーで開発が続けられるものと信じていました。

が…!

2010年代初頭、ルネサスエレクトロニクスは「H8」シリーズの開発を収束、16Bitマイコンの開発リソースを「RL78」シリーズに集中する…というアナウンスを出しました。

なんてこった。

一般論として「RL78」が「H8」よりも優れているから、こういう結論になったはず。

ならば「RL78」とは一体!?

そういや「RL78」って地球連邦軍のMSみたいだな。

見せてもらおうか…「H8」を倒した「RL78」の性能とやらを!

…というわけで「μITRON4.0」準拠のRTOS(リアルタイムOS)であるTOPPERS/ASPを移植してみました。

(なんでやねん!)


必要なもの

今回は、RL78の中でも比較的ハイエンドな「RL78/G14」を搭載した「RL78/G14 Fast Prototyping Board」という評価ボードを使います。

こちらで買うと、3,300円くらいです。

「RL78/G14 Fast Prototyping Board」評価ボード


他の型番への移植も可能ですが、TOPPERS/ASPを搭載して動作させるならROM:128KB/RAM:8KB以上の容量を持つ型番を選びましょう。

また「RL78/G14 Fast Prototyping Board」を使用する場合、デバッガーは必要ありません。

この評価ボードには既にデバッガーも実装されています。

「RL78/G14 Fast Prototyping Board」を使用しない場合は「E2 emulator Lite」というRL78に対応したデバッガを使用する必要があります。

こちらで買うと、12,000円くらいですね。

「E2 emulator Lite」デバッガ


デバッガーとしては良心的な価格ですが、それを搭載している「RL78/G14 Fast Prototyping Board」がそれより遥かに安価なので、如何にお買い得かが分かりますね。

このブログでは「RL78/G14 Fast Prototyping Board」を使用した場合の例を説明していきたいと思います。


ダウンロード/GitHub

ソースコードの入手は、こちらからどうぞ。

なるべく定期的にメンテナンスするようにしています。

記事を書きながら再検証もしていますので、ちょこちょこ修正が入るかもしれません。

動きがおかしいな?という場合は最新版に更新をお願いします。

一連の記事が完結する頃には安定したバージョンができるかな~?


このカーネルは、かなり昔に実装したので色々忘れてます。

なんとか思い出しながら、次回以降、開発環境の構築やビルド方法を書いていきます!


<続く>

2022年11月21日月曜日

TOPPERS/ASP - MSP430版 その6

前回からの続きです。

このテーマを最初からご覧になる場合はこちらからどうぞ。


サンプルプロジェクトの説明

このページ(TOPPERS/ASPのビルドからデバッグまで~サンプルプロジェクトで遊ぼう)を参照してください。


MSP430版カーネルについて

以下、このカーネルにおける備考です。


●割り込み優先度の設定不可

このカーネルでは、割り込み優先度の設定はできません。

コンフィグレーションファイルなどにおいて、他のアーキテクチャからの移植性を考慮して、-1(優先度最低)から-6(優先度最高)を設定してもエラーが起きないようになっていますが、実際の動作に反映しません。

これはMSP430に搭載されている割り込みコントローラーがシンプルな設計であり、割り込み優先度を変更する機能が存在しないためです。

MSP430における割り込み優先度は、割り込み番号が大きいほど優先度が高くなるように固定されています。


当然「System Reset」が最優先ですが、マスカブル(マスクできる割り込み)ではアナログ電圧コンパレータの「Comp_B」の割り込み優先度が高いですね。

割り込み番号の定義は「..\arch\msp430x_gcc\include_gcc\msp430f5529.h」にあり、以下の通りです。

上の表と上下逆ですが一致するでしょう?

  1. ...
  2. /************************************************************
  3. * Interrupt Vectors (offset from 0xFF80)
  4. ************************************************************/
  5. #define RTC_VECTOR (42)         /* 0xFFD2 RTC */
  6. #define PORT2_VECTOR (43)       /* 0xFFD4 Port 2 */
  7. #define TIMER2_A1_VECTOR (44)   /* 0xFFD6 Timer2_A5 CC1-4, TA */
  8. #define TIMER2_A0_VECTOR (45)   /* 0xFFD8 Timer2_A5 CC0 */
  9. #define USCI_B1_VECTOR (46)     /* 0xFFDA USCI B1 Receive/Transmit */
  10. #define USCI_A1_VECTOR (47)     /* 0xFFDC USCI A1 Receive/Transmit */
  11. #define PORT1_VECTOR (48)       /* 0xFFDE Port 1 */
  12. #define TIMER1_A1_VECTOR (49)   /* 0xFFE0 Timer1_A3 CC1-2, TA1 */
  13. #define TIMER1_A0_VECTOR (50)   /* 0xFFE2 Timer1_A3 CC0 */
  14. #define DMA_VECTOR (51)         /* 0xFFE4 DMA */
  15. #define USB_UBM_VECTOR (52)     /* 0xFFE6 USB Timer / cable event / USB reset */
  16. #define TIMER0_A1_VECTOR (53)   /* 0xFFE8 Timer0_A5 CC1-4, TA */
  17. #define TIMER0_A0_VECTOR (54)   /* 0xFFEA Timer0_A5 CC0 */
  18. #define ADC12_VECTOR (55)       /* 0xFFEC ADC */
  19. #define USCI_B0_VECTOR (56)     /* 0xFFEE USCI B0 Receive/Transmit */
  20. #define USCI_A0_VECTOR (57)     /* 0xFFF0 USCI A0 Receive/Transmit */
  21. #define WDT_VECTOR (58)         /* 0xFFF2 Watchdog Timer */
  22. #define TIMER0_B1_VECTOR (59)   /* 0xFFF4 Timer0_B7 CC1-6, TB */
  23. #define TIMER0_B0_VECTOR (60)   /* 0xFFF6 Timer0_B7 CC0 */
  24. #define COMP_B_VECTOR (61)      /* 0xFFF8 Comparator B */
  25. #define UNMI_VECTOR (62)        /* 0xFFFA User Non-maskable */
  26. #define SYSNMI_VECTOR (63)      /* 0xFFFC System Non-maskable */
  27. #define RESET_VECTOR ("reset")  /* 0xFFFE Reset [Highest Priority] */
  28. ...


●割り込み番号の指定方法

たとえば、「CFG_INT」などで割り込み番号を指定する場合は、上記の割り込み番号の定義から-1した値を入れてください。

例としては、OSタイマーの「..\target\msp_exp430f5529lp_gcc\target_timer.h」が分かり易いでしょうか。

OSタイマーは「TIMER0_A0_VECTOR」を使っているのですが、以下のように-1しています。

ここで定義された「INTNO_TIMER」が「..\target\msp_exp430f5529lp_gcc\target_timer.cfg」によって、コンフィグレーションとして使われているのです。

  1. ...
  2. /*
  3.  * タイマ割込みハンドラ登録のための定数
  4.  */
  5. #define INHNO_TIMER (TIMER0_A0_VECTOR - 1)  /* 割込みハンドラ番号 */
  6. #define INTNO_TIMER (TIMER0_A0_VECTOR - 1)  /* 割込み番号 */
  7. #define INTPRI_TIMER (-6)                   /* 割込み優先度 */
  8. #define INTATR_TIMER TA_EDGE                /* 割込み属性 */
  9. ...


●多重割り込みには未対応

デフォルトでは、割り込みハンドラやタスクコンテキスト以外のプログラムのための(非タスクコンテキスト用)スタック領域は、0x200(512バイト)としています。

これは「..\target\msp_exp430f5529lp_gcc\target_config.h」の以下の箇所で「DEFAULT_ISTKSZ」という名前で定義されています。

  1. /*
  2.  * デフォルトの非タスクコンテキスト用のスタック領域の定義
  3.  */
  4. #define DEFAULT_ISTKSZ      0x200U
  5. #define DEFAULT_ISTK        (void *)(0x00004400U - DEFAULT_ISTKSZ)

このスタックサイズは、今回使った評価ボード「MSP-EXP430F5529LP」に搭載されている「MSP430F5529」チップのRAMのサイズがわずか8KBであることを考えれば、妥当と考えています。

しかし、これにより多重割り込みのサポートを諦めています。

0x200(512バイト)というスタックサイズでは、割り込みをネストするのには十分ではなく、あっという間に暴走してしまう危険性が高くなりますので、そのリスクを避けました。

もっとも、多重割り込みが必要なほどの処理がシビアなアプリケーションには、このターゲットは使われないだろうと判断した結果です。


●例外ハンドラは未対応

コンフィグレーションファイルなどにおいて、他のアーキテクチャからの移植性を考慮して、例外ハンドラの作成はできるようになっているものの動作はしません。

理由はMSP430に例外処理が存在しないためです。


●一部サービスコールは未対応

割り込みIDを指定して、これを有効/無効化するための「ena_int()」と「dis_int()」サービスコールはサポートしていません。

これはMSP430に搭載されている割り込みコントローラーがシンプルな設計であり、割り込み要因ごとに有効/無効化するためのフラグを設けていないためです。

どうしても一時的に割り込みを有効/無効化したい場合は、各ペリフェラルのレジスタを設定するか、CPU全体の割り込みを一括で設定しても良いのであれば、以下のような処理で代用してください。

  1. /* すべての割込みの禁止 */
  2. Asm("nop");
  3. Asm("dint");
  4. Asm("nop");
  1. /* すべての割込みの許可 */
  2. Asm("nop");
  3. Asm("eint");
  4. Asm("nop");

または、以下のようなマクロが使えますが、その場合はこれを使用するソースに「#include <msp430.h>」を一行加えてあげてください。

  1. _disable_interrupts();  /* すべての割込みの禁止 */
  2. _enable_interrupts();   /* すべての割込みの許可 */


また、性能評価用システム時刻取得のための「get_utm()」サービスコールは未実装です。


●内蔵フラッシュROMのメモリマップ

この「MSP430F5529」というモデル、フラッシュメモリのマッピングが変です。

というよりMSP430シリーズの中で内蔵フラッシュが60KB以上の型番は、ちょっと癖があります。

内蔵フラッシュのメモリマップを以下に示します。


内蔵フラッシュ領域の中盤にベクタテーブル(VECTORS)が配置されています。

そして、このベクタテーブルは固定されており自由に移動させることができません。

すなわち、これはベクタテーブルのせいで、読み取り専用データセクション(.rodata)やプログラムコードのためのテキストセクション(.text)に使用するための領域が上下2つに分断されていることを意味します。

で、これら3つの領域の総和である128KBが「MSP430F5529」の内蔵フラッシュの容量ですよ~と言っているわけです。

これは「../target/msp430f5529.ld」のリンカスクリプトでも確認できます。

  1. ...
  2. MEMORY {
  3.   SFR : ORIGIN = 0x0000, LENGTH = 0x0010        /* END=0x0010, size 16 */
  4.   BSL : ORIGIN = 0x1000, LENGTH = 0x0800
  5.   RAM : ORIGIN = 0x2400, LENGTH = 0x2000        /* END=0x43FF, size 8192 */
  6.   USBRAM : ORIGIN = 0x1C00, LENGTH = 0x0800
  7.   INFOMEM : ORIGIN = 0x1800, LENGTH = 0x0200    /* END=0x19FF, size 512 as 4 128-byte segments */
  8.   INFOA : ORIGIN = 0x1980, LENGTH = 0x0080      /* END=0x19FF, size 128 */
  9.   INFOB : ORIGIN = 0x1900, LENGTH = 0x0080      /* END=0x197F, size 128 */
  10.   INFOC : ORIGIN = 0x1880, LENGTH = 0x0080      /* END=0x18FF, size 128 */
  11.   INFOD : ORIGIN = 0x1800, LENGTH = 0x0080      /* END=0x187F, size 128 */
  12.   ROM (rx) : ORIGIN = 0x4400, LENGTH = 0xBB80   /* END=0xFF7F, size 48000 */
  13.   VECTORS : ORIGIN = 0xFF80, LENGTH = 0x0080
  14.   HIROM (rx) : ORIGIN = 0x00010000, LENGTH = 0x00014400
  15. }
  16. ...


今回のMSP430版カーネルは、テキストセクション(.text)をHIROM領域に(一般的に.rodataよりも.textの方が容量が大きくなるため、容量の大きいHIROMを選択)、読み取り専用データセクション(.rodata)をROM領域に配置するように設計しています。

HIROM領域に収まる程度のそれほど大きくないアプリケーションならば問題はありませんが、もし一杯になってしまったら?

当然、読み取り専用データセクション(.rodata)が格納されているROM領域に空きがあれば、その領域を使いたいですよね?

内蔵フラッシュ領域がリニアでない場合、こういう時に面倒くさいことになりますが、以下のようなテクニックでやり過ごしましょう。

仮に以下のような関数をアプリケーションに追加したいとします。

  1. int8_t add(int8_t a, int8_t b)
  2. {
  3.     return a + b;
  4. }


でも、HIROM領域が一杯でこの関数が入らないので、これをROM領域に配置したいと考えます。

これはあくまで例ですので小さな関数ですが、もっと大きい関数でもやり方は同じです。

  1. int8_t __attribute__ ((section (".subtext"))) add(int8_t a, int8_t b)
  2. {
  3.     return a + b;
  4. }


このように「__attribute__ ((section (".subtext")))」を関数名の前に追記してあげます。

この記述によって、この関数を「.subtext」というセクションに配置してください…ってリンカにお願いをすることになります。

では「.subtext」ってセクションはどっから出てきたのか?

それは「../target/msp430f5529.ld」のリンカスクリプトを参照してください。

  1. ...
  2. SECTIONS
  3. {
  4.     .handlers : {} > ROM
  5.     .rodata :
  6.     {
  7.         *(.rodata)
  8.         *(.rodata.*)
  9.         *(.eh_frame_hdr)
  10.         KEEP (*(.eh_frame))
  11.     } > ROM
  12.     .subtext : {} > ROM /* 「.subtext」はここで定義されています! */
  13.     __idata_start = . ;
  14.     .data : AT(__idata_start)
  15.     {
  16.         __data_start = . ;
  17.         *(.data)
  18.         *(.data*)
  19.         __data_end = .;
  20.     } > RAM
  21.     __idata_end = __idata_start + SIZEOF(.data) ;
  22.     .vectors : {} > VECTORS
  23.     .text :
  24.     {
  25.         *(.text)
  26.         *(.text.*) /* .text.libgcc */
  27.      _etext = . ;
  28.     } > HIROM
  29. ...


14行目で「.subtext」セクションの定義を行っています。

これでビルドを行えば「add()」関数は、本来のHIROM領域ではなく、ROM領域に配置されることになります。

関数の呼び出し方は、ROM領域に配置されたからといって特に変わることはなく、通常通りに行えます。

面倒くさくて申し訳ありませんが、こんな感じでどーでっしゃろ?


●LPM(ローパワーモード)への対応

さて、MSP430を使用する上で最も重要なのが低消費電力化です。

今回使用した「MSP430F5529」には、以下の通り「Active」、「LPM0」~「LPM4」まで全部で6種類の動作モードがあります。

(「LPM3.5」と「LPM4.5」については今回は割愛します。)

通常…ていうかフルパワーで動作している状態が「Active」であり、「LPMx」はxの数が多いほど低消費電力のローパワーモードとなります。


この表を読んでみると、CPUの中で動いている様々なクロックを「LPMx」の段階に応じて停止させることにより低消費電力化を実現していることが分かります。

今回使用した「MSP430F5529」とは違う型番のデータですが、MSP430の動作モードと消費電力の関係は以下のグラフで表されます。

(多分「MSP430F5529」は全体的にもっと電力を食う…。)


CPUの中で動いているクロックは、ざっくり3つあります。


●MCLK…CPUのコアを動作させるクロック

●SMCLK…周辺機器を動作させるクロック(高速)

●ACLK…周辺機器を動作させるクロック(低速)


さて、OSというものは一定の間隔で割り込みを受け取り、それを基準にディスパッチなどの処理を行っています。

この一定の間隔を生み出すために、CPUに内蔵されているタイマーなどの周辺機器を使用するのが一般的で、このMSP430版カーネルでも同様です。

タイマーの精度はリアルタイムOSそのものの精度に直結するため、それを駆動するソースクロックは、ある程度高速であることが求められます。

したがって、このMSP430版カーネルでは低速のACLKではなく、高速のSMCLKをソースクロックとするタイマーを使用しました。

その結果、MSP430版カーネルでは「LPM1」までしかローパワーモードを下げられないことになってしまいました。

上の動作モードの表をもう一度ご覧ください。


OSが使用するタイマーのソースクロックはSMCLKですから「LPM2」まで下げてしまうとタイマーが停まりカーネルが動かなくなってしまいます。

ならばタイマーのソースクロックをACLKに変更すれば「LPM3」まで下げられるのでは?

…実際やってみましたがACLKの周波数が遅すぎて(32.768kHz)精度に難がある結果となってしまいました。

またSMCLKはデバッグ用のシリアル通信でも使用しているため、これをACLKに置き換えた場合、9600bpsのボーレートでも動作が怪しくなります。

となれば、SMCLKは使わざるを得ず「LPM1」までで妥協するしかないか…。

したがって、このMSP430版カーネルではタスクが一つも動作していないアイドル状態の時には、ぼぼ「LPM1」の状態までに留まります。

(正確にはタイマーの割り込み処理の間だけ定期的に「Active」モードになる。)


しかし、カーネルを停めても良いのであれば手はありまぁす!


ここから更に低消費電力化を図ろうとするならば、アプリケーションに以下のインクルードと、任意の場所にコードを記述してください。

  1. #include <msp430.h>
  2. __bis_SR_register(LPM3_bits + GIE);


これによりCPUは即座に「LPM3」に移行します。

処理はこの行で停止し、当然カーネルも動きを停めます。

これ以降は、ACLKで動作する周辺機器からの割り込みか、そもそもクロックに依存しないGPIOなどからの割り込みが発生するまで「Active」には戻りません。

割り込みが発生して「Active」に戻れば次の行から処理は再開され、カーネルも動作を再開します。

ソースクロックをACLKに指定したRTCなどを動作させて、一定の時間毎に割り込みを発生させて起床するようなアプリケーションでは、このモードが有効です。

更に以下のコードでは「LPM4」に移行します。

  1. #include <msp430.h>
  2. __bis_SR_register(LPM4_bits + GIE);


「LPM4」ではACLKすらも停止しますので、実質的にクロックに依存しないGPIOなどからの割り込みでなければ復帰しません。

GPIOに繋がれたスイッチを押すと起床するようなアプリケーションでは、このモードが有効です。

「LPM1」よりも更に低消費電力化が必要な場合は、カーネルは停まってしまいますが、上記の方法をお試しください。


ライセンスについて

このカーネルは「TOPPERSライセンス」で配布しております。

無償ですが、使用に関しては自己責任です。

このカーネルを商用利用するもの好きな方場合は、このリンク先の条項に従ってください。

ちなみに、商用利用ならば商用の製品をオススメします。

株式会社IPR様の「IPR-430RTOS」です!

TOPPERS/ASPと同じ「μITRON4.0」準拠の「HOS(Hyper Operating System)」ベースの製品です。

名前がアレですが、アニメと違って暴走なんかしません!

おっと、こちらの会社さん、私の住んでいる街のご近所。

地元企業を応援です!


さて、MSP430版関連の記事、補足事項がもう一つ…。

頑張って書きます。


<続く>

2022年11月17日木曜日

TOPPERS/ASP - MSP430版 その5

前回からの続きです。

このテーマを最初からご覧になる場合はこちらからどうぞ。


プログラムの転送とデバッグ

まずは、評価ボード「MSP-EXP430F5529LP」をUSB経由で開発用のパソコンと接続しましょう。


次にパソコン上でデバイスマネージャーを開きます。

ポート(COMとLPT)のサブカテゴリーとして「MSP Application UART1」と「MSP Debug Interface」というポートが追加されているはずです。

(私のパソコンでは、それぞれ「COM13」と「COM12」として認識されていますね。)

今回は、その内で「MSP Application UART1」の方に注目してください。


次に「TeraTerm」をご用意ください。

インストールしていない方は、このページ(TOPPERS/ASPのビルドからデバッグまで~サンプルプロジェクトのデバッグ)の「TeraTermの導入」の項目を参考にしてください。

もちろん、シリアル通信のターミナルであれば、他のものもお使いいただけます。

今回のTOPPERS/ASPのサンプルプログラムは、シリアル通信のメッセージを出力しますので、先程「MSP Application UART1」として認識されたシリアルポート番号でターミナルを立ち上げておきましょう。

設定は、こんな感じです。

ボーレートは「9600」です。

(私のパソコンは、「MSP Application UART1」をCOM13として認識していました。)


さて、Code Composer Studioに戻りましょう。

まだサンプルプログラムをビルドしていない場合は、画面右側の「Build Targets」タブの中、「OBJ」ディレクトリ直下の「all」をダブルクリックして、ビルドを完了させましょう。


次にデバッガの設定を行います。

画面上部にある緑色の「虫マーク」。

その脇に「▼」ボタンがありますので、それをクリック。

そこで現れた「Debug Configurations...」という項目をクリックしましょう。


すると以下のようなダイアログが現れます。

左側のリストから「Code Composer Studio - Device Debugging」という項目をダブルクリックしてください。


ダイアログ右側がガラリと変わりましたね?


まずは上部の「Name:」の部分に、このデバッグ設定の分かりやすい名前を付けてあげましょう。

(例では「OBJ」としています。)

続いて「Use default target configuration」のチェックボックスをクリックしてチェック状態にします。

それと同時に中央のリストボックスに「MSP430」というチェックボックスがチェック状態で表示されることを確認しておいてください。


さて、お次は現在の「Main」タブから「Program」タブへ切り替えます。

クリックです。


まずは、プロジェクトを指定します。

「Project」テキストボックスの右端の「Workspace...」ボタンをクリックします。


以下のようなダイアログが表示されますので、これから実機に転送するプログラムのプロジェクトを選択します。

今回の場合は、この記事の通りに作業いただいた場合は「asp_1.9.2」(もし他の名称でプロジェクトを作成した方は、そのプロジェクト名)一つしか無いはずですので、これをクリックした後「OK」ボタンをクリックします。


次に、実機に転送するプログラムを指定します。

「Program」テキストボックスの右端の「File System...」ボタンをクリックします。


以下のように、ファイル選択ダイアログが開きますので、プログラムが保存されている場所に移動しましょう。

これまで、この記事の通りに作業いただいた場合は以下のパスにあるはず…


C:\cygwin64\home\<ユーザ名>\asp_1.9.2\OBJ


…って、無いじゃん!

そう、ファイル選択ダイアログで上記のパスに移動しても「targetConfigs」ディレクトリ以外は、デフォルトでは何も表示されないのです。

なので、ダイアログ右下の「Program Files」のドロップダウンリストをクリックしてください。


ここで「All Files (*)」を選択してください。


そうすると色々なファイルが表示されるようになります。

この中で「asp.exe」というのが、ビルドして今回実機に転送したいプログラムの実体なのですが、拡張子が「.exe」と特殊なので、デフォルトのフィルタに引っかからなくて表示されなかっただけなんです。

実はこの「asp.exe」、拡張子こそ「.exe」ですが、中身はまんま「.elf」ファイルです。

もし「asp.exe」が見つからない場合は、まだビルドされていない可能性が考えられますので、再度ビルド作業を行なってください。

見つかった場合は「asp.exe」を選択して「開く」ボタンをクリックします。


さて、以上で設定は終わりです。

ダイアログ下部の「Apply」ボタン、「Debug」ボタンの順にクリックするとデバッガが起動します。


以下のような表示が出ることがあります。

気にせずに「Proceed」ボタンをクリックしてください。

毎度出てきて鬱陶しい!と思う方は「Always launch without asking」チェックボックスにチェックを入れちゃってください。

もう二度と聞かれなくなります。


デバッグ設定中らしいです。

地味に時間がかかります。


プログラムの転送と書き込みが始まりましたかね?


プログラムの転送と書き込みが完了すると、以下のような画面の状態になるはずです。

View Disassembly...」というボタンをクリックしてみましょう。


左側に「Disassembly」タブが追加され、アセンブラのリストが表示されます。

そして、どうやら004400というアドレスでプログラムが停止しているようですね。

これで良いんです!

004400というのはMSP430マイコンのスタートアップアドレスです。

ターゲットである「MSP-EXP430F5529LP」評価ボードに「asp.exe」というプログラムが転送され、それが書き込まれた後にリセットが発生し、それによって現在004400番地で処理が停まっている様子がコレです。


さて、この状態から実際にプログラムを続行させてみましょう。

画面上部の「」ボタンをクリックすると、プログラムが続行されます。


はい、ここで長らく放置していた「TeraTerm」を見てみましょう。

以下のように、サンプルプログラムが動作していることが確認できます。

(…ん?ちょっと出力に違和感あるよ?という方は、後ほどコチラを御覧ください)


プログラムを停止する場合は、画面上部の「」ボタンをクリックします。

停止させてみましょう。


ブレークポイントを仕掛けましょう。

画面右の「Project Explorer」のソースコードリストの中から「sample1.c」をダブルクリックし、ソースコードを表示します。

このソースコードの丁度中盤くらい、メインタスクの始めに仕掛けましょうか。


ブレークポイントは、ソースコードビューの左端をダブルクリックすると丸が表示され、セットできる…って思うでしょう?

ところが、このCode Composer Studioでは通用しないようです。

ブレークポイントを仕掛けるには、ソースコードビューの左端を右クリックして出てきたメニューの「Brakepoint(Code Composer Studio)」→「Brakepoint」を順にクリックしなければいけません。


すると、以下のように該当のソースコードの左端に丸マークが表示されて、ブレークポイントが設定されたことが分かります。

と同時に「Brakepoint」タブが画面上部に出現し、該当のソースコードがリストアップされます。


めんどくさ…。

因みに、普通にソースコードビューの左端をダブルクリックしてブレークポイントを設定しようとすると、丸マークも正しく表示されて一見問題ないように見えますが…。

実際にデバッグしてみると、見事に空振りするので注意です。

ともあれ、これで本当にブレークポイントがかかるのか、試してみましょう。

画面上部にある緑色の「虫マーク」。

(ほんとコレ、何虫がモデルなんだ?…カメムシ?)

その脇に「▼」ボタンがありますので、それをクリック。

すると今後は、さっき色々と入力した「OBJ」のデバッグ設定が登録されていますので、これをクリックすると、デバッガが起動します。


しばらくして、プログラムの転送と書き込みが完了すると、前と同じように004400番地でプログラムが停止しますので、画面上部の「」ボタンをクリックして、プログラムを続行させます。


程なくして、以下のように正しくブレークポイントを仕掛けた位置でプログラムが停止するはずです。

ここからは、「F6」キーでステップオーバー、「F5」キーでステップインなど、おなじみの操作が使用できます。

因みに、ステップオーバーやステップインなどを行っている時に命令が飛んでしまったり前後したりする場合は、最適化のせいです。

デバッグ時は、このページ(TOPPERS/ASPのビルドからデバッグまで~サンプルプロジェクトのデバッグ)の「サンプルプログラムのデバッグ」の項目を参考に最適化を解除しましょう。


さて、次回はサンプルプログラムの動きの説明や、今回のMSP430用ASPカーネルのウンチクを書いていきます。

MSP430の特徴である低消費電力をどうやって実現しているか?(…ていうか実現できてるの?)などなど、けっこう色々あります。


<続く>

TOPPERS/ASP - Arduino UNO R4版 その7

前回からの続き です。 このテーマを最初からご覧になる場合は こちら からどうぞ。 プログラムの転送とデバッグ ターゲットの「Arduino UNO R4」とデバッガの「E2 emulator Lite」を 前々回 作成したケーブルで接続します。 こんな感じ。 これからTOPPE...