MSP430 ISR 開 発 のノウハウとトラブル 防 止 [ msp430info, ISR and driver, trouble ] 2014.6.3 PIC 山 内 一 男 ペリフェラルの ISR を 開 発 するときの ノウハウとトラブル 防 止 の 留 意 事 項 について 解 説 いたします MSP430 のシリーズが 増 えて シリーズごとにペリフェラルのレジスタ 内 容 や 割 込 みフラッグの 仕 様 に 相 違 も 増 えてきましたの で 必 ずユーザガイドと data-sheet および code-example で 確 認 をお 願 いします ここでは 例 として G2553 を 使 い その data-sheet と 2xxx シリーズのユーザガイド および CCSv5/CCSv6 のデバイス ヘッダーとリンクコマンド リンクマップを 利 用 して 確 認 する 方 法 を 説 明 いたします 正 しく ISR が 組 み 込 まれているかを 事 前 にリンクマップで 確 認 することが トラブル 防 止 の point です code-example は 動 作 確 認 がされていますので これをベースにして 開 発 をお 願 いします 補 足 初 めて MSP430 を 開 発 される 方 むけに 下 記 のドキュメントを 用 意 してあります 説 明 は CCSv4 版 です TI-web の 右 上 検 索 欄 で jaja227 で 検 索 して 下 記 ドキュメントを 見 てください MSP430 導 入 用 マニュアル 目 次 1 割 込 み 要 因 とベクターの 確 認... 2 1.1 割 り 込 みベクター... 2 1.2 内 部 信 号 による 起 動... 2 2 ISR の pragma 名 称 確 認 方 法... 3 2.1 デバイスヘッダーファイルの 調 査... 3 2.2 リンクコマンドの 調 査... 3 2.3 ISR のコーディング... 3 2.4 リンクマップの 確 認... 4 2.5 未 登 録 ISR のトラブル 事 例... 4 3 ISR 作 成 の 留 意 点... 4 3.1 ISR の 特 性... 4 3.2 ISR の 留 意 点... 5 3.3 ISR での 割 り 込 みフラッグの 処 理... 5 3.4 ISR とランタイムルーチン(RTS)の 関 係... 5 3.5 LPM モード... 5 3.6 wake-up 時 間 の 確 認... 6 3.7 LPMx.5 モード... 6 4 ペリフェラル ライブラリ... 7 4.1 ドライバーとISR... 7 4.2 複 数 ペリフェラルを 並 行 動 作 させる 場 合... 7 1
1 割 込 み 要 因 とベクターの 確 認 1.1 割 り 込 みベクター 割 込 みを 間 違 えていて ISR が 未 登 録 だと CCS の version によって 暴 走 するか 無 限 ループすることになります ( 後 述 ) そのリスクを 回 避 するために data-sheet の Interrupt Vector Addresses の 表 で 割 込 み 要 因 と vector アドレスを 確 認 します priority が 大 きい 方 が 優 先 で かつ priority は 固 定 です 例 : G2553 data-sheet Table 5. Interrupt Sources, Flags, and Vectors 割 込 み 要 因 で 特 に 間 違 えやすい point は 下 記 です Timer に2つ 割 り 込 み 要 因 があり TAxCCR0 CCIFG は CCR1,CCR2,TAIFG とは 独 立 した 割 り 込 みです 2xxx は USCI_A0/USCI_B0 の 割 り 込 みベクターが 同 です ISR で A0/B0 の 割 込 みフラッグで 判 別 します G2553 Port1 の ISR を 開 発 する 例 で 説 明 します G2553 data-sheet Table 5. の Port P1 を 探 します I/O Port P1 (up to eight flags) P1IFG.0 to P1IFG.7(2) (4) maskable 0FFE4h 18 ここの FFE4 が vector アドレスになります これをキーにして2 項 で ISR の pragma 名 称 を 探 します 1.2 内 部 信 号 による 起 動 タイマーで ADC を 定 期 的 に 起 動 する 場 合 は 内 部 信 号 を 使 ってタイマーから ADC を 自 動 起 動 することができます タイマーの ISR で 割 り 込 みを 受 ける 必 要 はありません ADC の ISR で ADC 完 了 割 込 み(ADC10IFG)を 受 けて ADC-data を 格 納 します ADC の CTL レジスタの SHSx で timer 信 号 を 選 択 しますが デバイスシリーズごとに 確 認 方 法 に 相 違 があります 1) G2553 の 例 (2xxx ADC10) ユーザガイド Figure 22-3. Sample Timing の sampling start パルスの SHI 信 号 は Figure 22-1. ADC10 Block Diagram の SHSx で TA0 と TA1 から 選 択 できます この TA0と TA1は ADC10CTL1 レジスタ:SHS_1(timer0-OUT1:CCR1)/SHS_2(timer0-OUT0:CCR0) で 指 定 します 2) F5529 の 例 (F5/F6 ADC10/ADC12) ユーザガイドの Figure 27-4. Pulse Sample Mode または Figure 27-3. Extended Sample Mode の sampling start パルスの SHI 信 号 は Figure 27-1. ADC10_A Block Diagram の 3 inputs from Timers から 選 択 できます 2
3 inputs from Timers は data-sheet で 規 定 されていて TA0 TB0 に 記 載 されています F5529 data-sheet Table 14. TA0 Signal Connections ADC12SHSx ={1} Table 17. TB0 Signal Connections ADC12SHSx ={2} ADC12SHSx ={3} 2 ISR の pragma 名 称 確 認 方 法 CCSv5/CCSv6 で ヘッダー 内 容 が 変 更 されましたので それに 沿 って 説 明 をします PIO1の ISR を 例 に 説 明 します 2.1 デバイスヘッダーファイルの 調 査 CCSv5/v6 のプロジェクト 配 下 includes フォルダーにある G2553.h を 開 き 末 尾 の Interrupt Vectors を 調 べま す FFE4 Port1 があります #ifdef ASM_HEADER /* Begin #defines for assembler */ #define PORT1_VECTOR ".int02" /* 0xFFE4 Port 1 */ #else #define PORT1_VECTOR (2 * 1u) /* 0xFFE4 Port 1 */ #endif このヘッダーの 指 定 により PORT1_VECTOR 名 称 が Vector table 0xFFE4 に 割 り 付 けられます 2.2 リンクコマンドの 調 査 リンクコマンド link_msp430g2553.cmd の 末 尾 にも 下 記 があり PORT1_VECTOR がここにリンクされます /* MSP430 INTERRUPT VECTORS */ PORT1 : { * (.int02 ) } > INT02 type = VECT_INIT 2.3 ISR のコーディング 下 記 のように 登 録 するベクター:PORT1_VECTOR と ユーザが 作 成 して 登 録 する ISR 名 ( 例 port_1)を 定 義 して ISR を 組 み 込 みます #pragma vector=port1_vector interrupt void port1() { ISR の 機 能 コーディング } 3
2.4 リンクマップの 確 認 プロジェクト\Debug にある xxxxxx.map がリンクマップです この map ファイルを 調 べて ISR が 正 しく 組 み 込 ま れているか 確 認 します 例 で 挙 げている PORT1 の ISR が 下 記 のように build されています Port1_driverG.c がソースコード 名 で その obj がリンクされています PORT1 0 0000ffe4 00000002 0000ffe4 00000002 Port1_driverG.obj (.int02) CCSv5.5/CCSv6 では 未 登 録 のベクターにはランタイムライブラリー(rst430)からダミーISR が 組 み 込 まれます NMI 0 0000fffc 00000002 0000fffc 00000002 rts430_eabi.lib : int14.obj (.int14) 現 在 の CCSv5/CCSv6 では この ISR は 割 り 込 み 禁 止 無 限 ループのルーチンですので もし 仮 に 未 登 録 の 割 り 込 み が 来 ると このダミーISR で 無 限 ループして アプリケーションには 戻 りません 2.5 未 登 録 ISR のトラブル 事 例 1)CCSv5.5 以 降 の 場 合 ダミーISR で 無 限 ループしているとき suspend( 手 動 で 停 止 )すると Can't find a source file../isr_trap.asm" のエラーが 表 示 されます このメッセージが 出 たら 未 登 録 ISR があると 推 察 できます このエラーについては google で msp430info suspend で 検 索 して 下 記 の 記 事 を 見 てください MSP430 CCSv5 suspend 操 作 をすると Can't find a source file のメッセージがでるトラブル 2)CCSv5.4 以 前 の 場 合 build 時 に 未 使 用 の ISR があるとワーニングが 出 ます ワーニングを 止 める 方 法 は google で msp430info warning で 検 索 して 下 記 の 記 事 を 見 てください MSP430 CCSv5 で warning #10374-D の 表 示 を 消 す 方 法 3)CCSv4 の 場 合 未 登 録 の 場 合 に 暴 走 するリスクがあります 3 ISR 作 成 の 留 意 点 3.1 ISR の 特 性 ISR 内 部 は 割 り 込 み 禁 止 です 割 込 み 優 先 度 (priority)は 1 項 で 説 明 しましたが 固 定 です 多 重 割 込 み 処 理 には 対 応 していません 4
3.2 ISR の 留 意 点 ISR に 長 い 処 理 をするものが 有 ると 他 の ISR が 動 けません できるだけ 早 く 最 小 限 の 処 理 をして アプリケーションで 後 処 理 する 方 が 有 利 です 関 数 コールはオーバヘッドが 大 きくなるので 回 避 したほうが 有 利 です ISR 内 部 で 割 込 み 可 にすると 多 重 割 込 み 処 理 のリスクがあります ISR から 抜 けるときに active+ 割 り 込 み 可 に 戻 すときは _bic_sr_register_on_exit(lpm4_bits); を 使 います LPM3/LPM4 で wait している 状 態 では 割 込 のあと ISR が 動 けるまでに CPU の wake-up 時 間 が 必 要 です wake-up 時 間 は data-sheet で 確 認 が 必 要 です 特 に F5/F6/FR57 は LPM3,LPM4 からの wake-up 時 間 が 長 い( 約 140us)ケースが 有 ります ISR の 格 納 メモリは 下 位 の 64KB 以 内 と 制 限 があります CCS5/CCS6 では リンクコマンドに ISR 格 納 用 の section:.text:_isr が 設 けられここに 格 納 されます 3.3 ISR での 割 り 込 みフラッグの 処 理 ランタイムルーチン(RTS)が 割 り 込 みを1 次 処 理 してISRへ 渡 します このとき 基 本 的 に1ソースの 場 合 は 割 込 みフラッグはclearされてISRに 来 ます 複 数 の 割 り 込 みソースを 持 つ 場 合 は ISRにて 各 IFGフラッグの 判 定 とclearが 必 要 です ただし TA0IVのように1ソース 割 込 みを 検 出 してISRへくる 場 合 は ISRでTA0IVをreadすることで IFGとTAIVの 両 方 がclearされます 例 switch( even_in_range(ta0iv,0x0a)) この 判 定 文 は 範 囲 判 定 を 早 くするMSP430 特 殊 命 令 (intrinsic)です 下 記 ドキュメントに 説 明 があります MSP430 Optimizing C/C++ Compiler v 4.3 User's Guide SLAU132I 5.11.26 The vector Pragma ISRに 来 た 時 の 割 込 みフラッグの 状 態 は デバッガーを 使 いISR 内 部 でbreakさせて 各 IFGビットを 見 ることで 確 認 でき ます 3.4 ISR とランタイムルーチン(RTS)の 関 係 割 込 みが 起 きると RTS がレジスタをスタックに 保 存 してから ISR に 制 御 を 渡 します ISR が 終 了 するとき RTS がレジスタを 復 元 して 割 り 込 み 可 にして 最 後 に PC を 戻 してアプリケーションに 戻 ります _bic_sr_register_on_exit(lpm4_bits)が 呼 ばれているときは レジスタ 復 元 の 時 に SR レジスタが 書 き 換 えら れ active モードに 戻 すことができます 3.5 LPM モード 各 デバイスのユーザガイドで LPM モードが 規 定 されています この LPM モードとクロックの 関 係 は デバイスシリーズごとに 相 違 がありますので 必 ずユーザガイドで 確 認 します 2xxx シリーズでは 下 記 に 記 載 があります 2.3 Operating Modes 5
Figure 2-9. Operating Modes For Basic Clock System Table 2-2. Operating Modes For Basic Clock System SR レジスタの SCG0 SCG1 OSCOFF CPUOFF ビットの 状 態 で LPM モードが 決 まります 各 デバイスのヘッダ(msp430g2553.h)で 下 記 のように 定 義 されていますので C コードでは LPMx_bits と 表 現 できます #define LPM0_bits #define LPM1_bits #define LPM2_bits #define LPM3_bits #define LPM4_bits (CPUOFF) (SCG0+CPUOFF) (SCG1+CPUOFF) (SCG1+SCG0+CPUOFF) (SCG1+SCG0+OSCOFF+CPUOFF) この SCG0 SCG1 OSCOFF CPUOFF は クロックの on/off を 制 御 します クロックシステムのブロック 図 に 書 か れていますので LPM モードとクロックの 関 係 が 理 解 できます Figure 5-1. Basic Clock Module+ Block Diagram MSP430F2xx クロックを 使 用 するペリフェラルでは 適 切 な LPM モードを 選 択 する 必 要 があります 例 えば ACLK 使 用 Timer を 動 かしているときに LPM4 で wait すると ACLK が 停 止 ->Timer も 停 止 します DCO->SMCLK->UART で 動 作 させているときに LPM2~LPM4 で wait すると DCO と SMCLK が 停 止 して UART 送 受 信 ができません 3.6 wake-up 時 間 の 確 認 デバイスシリーズごとに wake-up 時 間 がかなり 異 なりますので 必 ず data-sheet で 確 認 お 願 いします 例 えば DCO の wake-up 時 間 が5us ということは (DCO->MCLK のとき)ISR は MCLK つまり DCO が 動 い ている 必 要 がありますから LPM2~LPM4 では ISR が 動 くまでに5us 遅 延 することになります これが 不 都 合 なとき は LPM0 か LPM1 を 選 ぶことになりますが 消 費 電 流 は 増 加 します 3.7 LPMx.5 モード F5/F6 FR シリーズには LPM3.5/LPM4.5 のモードがあり 電 流 消 費 を 最 低 限 に 抑 えることができます RTC と PIO の 割 り 込 み Reset で wake-up ができます 詳 細 はユーザガイドで 確 認 してください Figure 1-6. Operation Modes Table 1-2. Operation Modes で 確 認 してください LPM3.5 は XT1 ブロックが 動 作 して RTC を 継 続 動 作 できます LPM4.5 では XT1 ブロックも 停 止 します 6
4 ペリフェラル ライブラリ 4.1 ドライバーとISR アプリケーションでペリフェラルのレジスタを 設 定 する 方 法 では 別 のアプリケーションへ 移 植 するのが 大 変 になります ペリフェラルのドライバーを 作 り このなかでレジスタ 設 定 と port ピン 設 定 IO バッファアドレスの ISR への 引 き 渡 しなど をさせて 独 立 したライブラリにすると 移 植 が 容 易 になります ドライバーと ISR を 対 にしてペリフェラル ライブラリを 作 る 例 で 相 互 の 関 係 を 下 記 に 示 します アプリケーション ドライバー [ ペリフェラル HW ] ISR ドライバー 呼 び 出 し ---- > IO バッファ 引 き 渡 し ------------------------------- > port 設 定 --------- > レジスタ 設 定 --------- > ペリフェラル Enable ----- > < --- return; _bis_sr_register(lpm4_bits+gie); -- GIE----- > IO 割 込 --------- > IO バファへ 格 納 --------- > --------- > --------- > IO 終 了 (Active+GIE) < ---------------------------------------- bis_sr_register(lpm4_bits) 留 意 事 項 アプリケーションが LPMx で wait する 前 に ISR が LPMx 解 除 をすると アプリケーションは LPMx wait のままです 4.2 複 数 ペリフェラルを 並 行 動 作 させる 場 合 アプリケーションは 複 数 ペリフェラルの 完 了 を 適 切 な LPM モードで 待 つ 必 要 があります 例 えば ACLK と SMCLK を 使 用 している 二 つのペリフェラルがあるとき LPM3 で 待 つと SMCLK 使 用 のペリフェラル は 停 止 してしまいます LPM1,LPM0 で 待 つ 必 要 があります LPMxを 解 除 する ISR が 一 つの 場 合 は 問 題 ありませんが 複 数 の 場 合 は 誰 が 解 除 したのか つまりどのペリフェラルが 終 了 したのか 判 定 が 必 要 になります 複 数 ペリフェラルを 待 ち 合 わせて 制 御 するライブラリ example を E2E Japan フォーラムに 掲 載 しております google で msp430info multi-io で 検 索 して 下 記 の 記 事 をご 覧 ください MSP430 複 数 ペリフェラルを 並 行 動 作 させる 方 式 以 上 - 7