(toppers-users 4481) Re: GR-SAKURA「TOPPERS/ECNL」 S12AD→DMAC でUnre

長島 宏明 nagasima @ core-s.co.jp
2016年 1月 6日 (水) 08:14:10 JST


柴田様

長島です。

報告ありがとうございます。
解決したようで良かったです。

対策方法ですが、CPUの動作になりますので、
私の方では問題ないとは言い切れません。すいません。
現象から対策を考えるなら、私も同じことをすると思います。

確実なのはRenesasさんに聞くのがいいかと思います。

今後とも、
よろしくお願いします。

On 2016/01/05 21:04, 柴田正 wrote:
> コアーズ 長島様
>
> お世話になっています。柴田です。
>
> 早速ですが、結果を先に報告させていただきます。
> お陰さまで、不具合が発生しない方法は、見つかりました。
> ありがとうございます。
>
> ただ、メモリー破壊という、直接的な原因は同じですが、
> 修正箇所は予想していた箇所と違っていました。
>
> 割込みハンドラから、Excep_DMACA_DMAC0関数を呼出しても、
> 同じバグが発生しました。
> 割込みハンドラで、DMCRBの値がゼロになっていたため、
> 下記のように再び0x0100を設定する処理を実装し改善しました。
> サンプルコードをGrepしても、同じ処理が見つからなかったため、
> 他の対策を行っていない場合は、サンプルも正常に動作していません。
> この対策方法で問題ありませんか。
>
> void dmaca_dmac1_handler2(void)
> {
>      static uint32_t dmac_input_cnt = 0;
>      dmac_input_cnt++;
>      if ((dmac_input_cnt % 2) == 1) {
>           DMAC1.DMDAR = (void *)g_adc_buf2[1];
>      }
>      else {
>          DMAC1.DMDAR = (void *)g_adc_buf1[1];
>      }
>      DMAC1.DMCRB = 0x0100;
>      DMAC1.DMCNT.BIT.DTE = 1;
> }
>
> 何度も申し訳ありませんが、
> よろしくお願いします。
>
> 以上。
>
> 2016年1月5日 14:58 長島 宏明 <nagasima @ core-s.co.jp>:
>> 柴田様
>> 長島です。
>>
>>> もし、アドレスが元に戻っていない場合は、
>>> DMAC1.DMDARを再設定すれば、よろしいですか。
>>>
>> 再設定でもいいと思いますが、DMTMD.DTSを「00b」に設定すれば、
>> 「転送先側がリピート領域またはブロック領域」となるので、
>> CPUが再設定を行ってくれると思います。
>> それならば、現状の割り込みハンドラでいいと思います。
>>
>>> また、調査したら、その結果をご連絡させていただきます。
>>> ただ、ご返事が遅れる可能性もあります。
>>> その場合は、ご了承ください。
>>>
>> 承知いたしました。
>>
>> 以上です。
>> よろしくお願いします。
>>
>> On 2016/01/05 14:47, 柴田正 wrote:
>>>
>>> コアーズ 長島様
>>>
>>> ご回答をいただき、ありがとうございます。
>>> 柴田です。
>>>
>>>> BRKコマンドのコードは「00」のようなので、
>>>> 「p_tmevtb->callback」が指しているアドレスにプログラムコードが
>>>> ないようです。
>>>> 「DEFAULT_ISTACK_TOP」はスタック領域なので、
>>>> ここが呼ばれることは設計上はないと思います。
>>>>
>>> 了解しました。
>>>
>>>
>>>> 「__kernel_tmevt_heap」のメモリ領域が壊されているように思います。
>>>>
>>> そうですか。そうであれば、早い段階で見つかって、とてもラッキーです。
>>>
>>>> 割り込みハンドラの内容は、下記がすべてでしょうか?
>>>>>
>>>>> void dmaca_dmac1_handler2(void) {
>>>>>         DMAC1.DMCNT.BIT.DTE = 1;
>>>>> }
>>>>
>>>>
>>> 現在は、このコードだけです。
>>> 割込み処理に時間がかかり、エラーが発生しているかと考え、
>>> 最小限にしました。
>>> このコードに直す前は、ルネサスのサンプルコードの
>>> Excep_DMACA_DMAC0関数を呼出していました。
>>> 最初は、DMAC0とDMCA1、2CHを考えており、
>>> そのコードが残っています。
>>> 念のため、その部分のコードを下記します。
>>> このコードを実行しても、エラーが発生していたつもりです。
>>> ただ、領域破壊であれば、もしかしたら、試していないのかも知れません。
>>> もう一度、試してみます。
>>>
>>> void Excep_DMACA_DMAC1(void)
>>> {
>>>        g_dmac_flag[0] = 1;   //DMAC0用転送完了通知フラグ
>>>        g_dmac_flag[1] = 1;   //DMAC1用転送完了通知フラグ
>>>
>>>        dmac_input_cnt[0]++;    //DMAC0用バッファ切り替えカウンタ
>>>        dmac_input_cnt[1]++;    //DMAC1用バッファ切り替えカウンタ
>>>
>>>        if ((dmac_input_cnt[1] % 2) == 1)
>>>        {
>>>             g_buf_flag[0] = 1;
>>>             g_buf_flag[1] = 1;
>>>             DMAC0.DMDAR = (void *)g_adc_buf2[0];   //DMC0用バッファ2
>>>             DMAC1.DMDAR = (void *)g_adc_buf2[1];   //DMC1用バッファ2
>>>        }
>>>        else {
>>>             g_buf_flag[0] = 0;
>>>             g_buf_flag[1] = 0;
>>>             DMAC0.DMDAR = (void *)g_adc_buf1[0];   //DMC0用バッファ1
>>>             DMAC1.DMDAR = (void *)g_adc_buf1[1];   //DMC1用バッファ1
>>>        }
>>>        DMAC1.DMCNT.BIT.DTE = 1;
>>> }/* End of function Excep_DMAC_DMAC1 */
>>>
>>>
>>>> DMAC1.DMAMD.WORD = 0x0080;
>>>> の設定で、転送先アドレスがインクリメントされるようです。
>>>> DMAC1.DMTMD.WORD = 0x5101;
>>>> でリピート転送をしているようですが、
>>>> DMTMD.DTS値は「01b」になりそうです。
>>>> その場合、「転送元側がリピート領域またはブロック領域」となるので、
>>>> 転送先アドレスはリピートしてくれないように読めます。
>>>>
>>>> 「dmaca_dmac1_handler2」が呼ばれたときに、
>>>> 「DMAC1.DMDAR」の値の確認をしてみてください。
>>>>
>>> 了解しました。
>>> もし、アドレスが元に戻っていない場合は、
>>> DMAC1.DMDARを再設定すれば、よろしいですか。
>>>
>>>
>>>>> ※MTU0は、142番だと考えていましたが、私の間違いですか。
>>>>
>>>> 142番のようですね、こちらの間違えでした。
>>>>
>>> 了解しました。
>>> 私も自信がなかったので、間違っていないことが確認できて、
>>> よかったです。
>>>
>>>
>>>>> 私も、割込み番号が知りたいと調査を行いましたが、分かりませんでした。
>>>>
>>>> RXでは、割り込み番号はわからないようですね。
>>>> 別のCPUと勘違いしていました。申し訳ありません。
>>>>
>>> 了解しました。
>>> たくさんのCPUを扱うと、よくあることですよね。
>>>
>>>
>>> また、調査したら、その結果をご連絡させていただきます。
>>> ただ、ご返事が遅れる可能性もあります。
>>> その場合は、ご了承ください。
>>>
>>> 以上です。
>>>
>>>
>>> 2016年1月5日 14:03 長島 宏明 <nagasima @ core-s.co.jp>:
>>>>
>>>> 柴田様
>>>>
>>>> 長島です。
>>>>
>>>> 割り込みの設定等は、直接は関係なさそうですね。
>>>> BRKコマンドの部分を見逃していました。
>>>>
>>>>> signal_time関数で、以下のコメントが書かれているコードがあります。
>>>>> その条件が満たされて、タイムイベントヒープが削除され、
>>>>> 「(*(p_tmevtb->callback))(p_tmevtb->arg);」が実行されます。
>>>>> それで、「DEFAULT_ISTACK_TOP」が呼出され、
>>>>> BRKコマンドが実行され、おそらく、無条件トラップの割込みベクタが呼ばれ ます。
>>>>>
>>>> BRKコマンドのコードは「00」のようなので、
>>>> 「p_tmevtb->callback」が指しているアドレスにプログラムコードが
>>>> ないようです。
>>>> 「DEFAULT_ISTACK_TOP」はスタック領域なので、
>>>> ここが呼ばれることは設計上はないと思います。
>>>>
>>>> 「__kernel_tmevt_heap」のメモリ領域が壊されているように思います。
>>>>
>>>> 割り込みハンドラの内容は、下記がすべてでしょうか?
>>>>>
>>>>> void dmaca_dmac1_handler2(void) {
>>>>>         DMAC1.DMCNT.BIT.DTE = 1;
>>>>> }
>>>>
>>>>
>>>> Renesasのサンプルでは、「void Excep_DMACA_DMAC0(void)」で
>>>> DMAC0.DMDAR = (void *)&g_adc_buf1[0];
>>>> として、転送先アドレスを再設定しているようです。
>>>>
>>>> DMAC1.DMAMD.WORD = 0x0080;
>>>> の設定で、転送先アドレスがインクリメントされるようです。
>>>> DMAC1.DMTMD.WORD = 0x5101;
>>>> でリピート転送をしているようですが、
>>>> DMTMD.DTS値は「01b」になりそうです。
>>>> その場合、「転送元側がリピート領域またはブロック領域」となるので、
>>>> 転送先アドレスはリピートしてくれないように読めます。
>>>>
>>>> 「dmaca_dmac1_handler2」が呼ばれたときに、
>>>> 「DMAC1.DMDAR」の値の確認をしてみてください。
>>>>
>>>>> ※MTU0は、142番だと考えていましたが、私の間違いですか。
>>>>
>>>> 142番のようですね、こちらの間違えでした。
>>>>
>>>>> 私も、割込み番号が知りたいと調査を行いましたが、分かりませんでした。
>>>>
>>>> RXでは、割り込み番号はわからないようですね。
>>>> 別のCPUと勘違いしていました。申し訳ありません。
>>>>
>>>> 以上です。
>>>> よろしくお願いします。
>>>>
>>>> On 2016/01/05 11:49, 柴田正 wrote:
>>>>>
>>>>>
>>>>> コアーズ 長島様
>>>>>
>>>>> ありがとうございます。
>>>>> 早速ですが、疑問点を回答させていただきます。
>>>>>
>>>>>> カーネルはECNLのリリースで使用している「TOPPERS/ASP」でよいでしょうか?
>>>>>>
>>>>> ECNLを変更していないため、「TOPPERS/ASP」になります。
>>>>>
>>>>>
>>>>>
>>>>>> Renesasのサンプルコードで、「src\peripheral_init.c」の
>>>>>> 「dmac_init」関数を見ると、「DMAC0」の方を使っているようですが、
>>>>>> 「DMAC1」になるように変更しているということでよいでしょうか?
>>>>>>
>>>>> 「DMAC1」に変更しています。
>>>>> 全て、DMAC0をDMAC1に変更しています。
>>>>> 1回はDMA転送終了時の割込みが発生するため、
>>>>> おそらく、DMAC1への変更は問題ないと判断しています。
>>>>> #256回のAD変換/DMA転送後、割込みが発生する。
>>>>>
>>>>> 念のため、その部分のコードを以下に示します。
>>>>> void mtu_init(void){
>>>>>        SYSTEM.PRCR.WORD = 0xa503;
>>>>>        MSTP(MTU0) = 0;
>>>>>        MTU0.TIER.BYTE = 0x00;
>>>>>        MTU0.TCR.BYTE = 0x21;
>>>>>        MTU0.TMDR.BYTE = 0x00;
>>>>>        MTU0.TIORH.BYTE = 0x03;
>>>>>        MTU0.TIER.BIT.TGIEA = 1;
>>>>>        MTU0.TGRA = 0xffff;  //AD変換速度の問題と考え、カウンタを最大にしています。
>>>>>        IR(MTU0,TGIA0) = 0;
>>>>>        IEN(MTU0,TGIA0) = 1;
>>>>>        IPR(MTU0,TGIA0) = 0;
>>>>>        SYSTEM.PRCR.WORD = 0xa500;
>>>>> }/* End of function mtu_init */
>>>>>
>>>>> void s12ad_init(void){
>>>>> //サンプルから、チャンネルを1から2に変更しています。
>>>>>        SYSTEM.PRCR.WORD = 0xa503;
>>>>>        PORT4.PMR.BIT.B2 = 0;
>>>>>        MPC.PWPR.BYTE = 0x40;
>>>>> MPC.P42PFS.BYTE = 0x80;
>>>>>        MPC.PWPR.BYTE = 0x80;
>>>>>        MSTP(S12AD) = 0;
>>>>>        S12AD.ADCSR.BYTE= 0x02;
>>>>>        S12AD.ADANS0.WORD = 0x0004;
>>>>>        S12AD.ADSTRGR.BIT.ADSTRS = 1;
>>>>>        S12AD.ADCSR.BIT.ADIE = 1;
>>>>>        IR(S12AD,S12ADI0) = 0;
>>>>>        IEN(S12AD,S12ADI0)= 1;
>>>>>        IPR(S12AD,S12ADI0)= 0;
>>>>>        SYSTEM.PRCR.WORD = 0xa500;
>>>>> }/* End of function s12ad_init */
>>>>>
>>>>> void dmac_init(void){
>>>>> //サンプルからDMAC0からDMAC1に変更しています。
>>>>> //ADポートと、ポート1から2に変更しています。
>>>>>         SYSTEM.PRCR.WORD = 0xa503;
>>>>>         MSTP(DMAC) = 0;
>>>>>         ICU.DMRSR1 = VECT_S12AD_S12ADI0;
>>>>>         DMAC0.DMCNT.BIT.DTE =0; //念のため、DMAC0は動作を停止しています。
>>>>>         DMAC1.DMCNT.BIT.DTE =0;
>>>>>         DMAC1.DMAMD.WORD = 0x0080;
>>>>>         DMAC1.DMTMD.WORD = 0x5101;
>>>>>         DMAC1.DMSAR = (void *)&S12AD.ADDR2;
>>>>>         DMAC1.DMDAR = (void *)g_adc_buf1[1];
>>>>>         DMAC1.DMCRA = 0x00010001;
>>>>>         DMAC1.DMCRB = 0x0100;
>>>>>         DMAC1.DMCSL.BIT.DISEL = 0;
>>>>>         DMAC1.DMINT.BIT.DTIE = 1;
>>>>>         IR(DMAC,DMAC1I) = 0;
>>>>>         IEN(DMAC,DMAC1I)= 1;
>>>>>         IPR(DMAC,DMAC1I)= 1;
>>>>>         DMAC1.DMCNT.BIT.DTE = 1;
>>>>>         SYSTEM.PRCR.WORD = 0xa500;
>>>>> }/* End of function dmac_init */
>>>>>
>>>>>
>>>>>
>>>>>> となっていますので、126,102番の割り込みも有効になっているようです。
>>>>>> この割り込みハンドラの定義もされていますでしょうか?
>>>>>>
>>>>> 試験的に、割込みベクタが定義できるものは全て定義(※)しました。
>>>>> ただ、それでも発生しました。
>>>>> ※無条件トラップ、予約、206~210(DEU、PDC)を除く、全ての割込み。
>>>>>
>>>>> 現在は、余計は割込みフラグがクリアされるため、DMAC1しか定義していません。
>>>>> 126,102番(※)は定義するべきですか。
>>>>> ※MTU0は、142番だと考えていましたが、私の間違いですか。
>>>>>
>>>>>
>>>>>
>>>>>> __kernel_default_int_handler_entryが呼ばれるのは、
>>>>>> DEF_INHで割り当てをしていない割り込みに、
>>>>>> 割り込みが入ったときだと思います。
>>>>>> そのときの割り込み番号が何かをデバッガなどで調べて教えていただけると
>>>>>> 現象が詳しくわかると思います。
>>>>>>
>>>>>> signal_time関数については、関連が見えませんでしたので、
>>>>>> もう少し詳しく教えてください。
>>>>>> どの辺りを実行したときに__kernel_default_int_handler_entryが
>>>>>> 呼ばれているか、呼び出し元はどこかなど、教えてください。
>>>>>>
>>>>> signal_time関数で、以下のコメントが書かれているコードがあります。
>>>>> その条件が満たされて、タイムイベントヒープが削除され、
>>>>> 「(*(p_tmevtb->callback))(p_tmevtb->arg);」が実行されます。
>>>>> それで、「DEFAULT_ISTACK_TOP」が呼出され、
>>>>> BRKコマンドが実行され、おそらく、無条件トラップの割込みベクタが呼ばれます。
>>>>>
>>>>> ○ current_timeよりイベント発生時刻の早い(または同じ)タイムイベ
>>>>>       ントを,タイムイベントヒープから削除し,コールバック関数を呼び
>>>>>       出す.
>>>>>
>>>>> 私も、割込み番号が知りたいと調査を行いましたが、分かりませんでした。
>>>>> __kernel_default_int_handler_entryのアセンブラでは、
>>>>> 「mov.l #0FFFFFFFFH, r1」となっており、
>>>>> R1レジスタには、同じ割込み番号が設定されます。
>>>>> もし確認方法があれば、教えてください。
>>>>> よろしくお願いします。
>>>>>
>>>>> お手数でしょうが、よろしくお願いします。
>>>>>
>>>>> 以上です。
>>>>>
>>>>>
>>>>>
>>>>> 2016年1月5日 10:24 長島 宏明 <nagasima @ core-s.co.jp>:
>>>>>>
>>>>>>
>>>>>> コアーズの長島です。
>>>>>>
>>>>>> タイトルに「TOPPERS/ECNL」とあるので回答します。
>>>>>> ただ、質問の内容はカーネルの内容のように思いますので、
>>>>>> わかる範囲で回答します。
>>>>>> カーネルはECNLのリリースで使用している「TOPPERS/ASP」でよいでしょうか?
>>>>>>
>>>>>> Renesasのサンプルコードで、「src\peripheral_init.c」の
>>>>>> 「dmac_init」関数を見ると、「DMAC0」の方を使っているようですが、
>>>>>> 「DMAC1」になるように変更しているということでよいでしょうか?
>>>>>> DMAC0の場合、割り込み番号は198になります。
>>>>>>
>>>>>> また、「mtu_init」関数では、
>>>>>> /* Interrupt request enable */
>>>>>> IEN(MTU0,TGIA0) = 1;
>>>>>>
>>>>>> 「s12ad_init」関数では、
>>>>>> /* Interrupt request enable */
>>>>>> IEN(S12AD,S12ADI0)= 1;
>>>>>>
>>>>>> となっていますので、126,102番の割り込みも有効になっているようです。
>>>>>> この割り込みハンドラの定義もされていますでしょうか?
>>>>>>
>>>>>> __kernel_default_int_handler_entryが呼ばれるのは、
>>>>>> DEF_INHで割り当てをしていない割り込みに、
>>>>>> 割り込みが入ったときだと思います。
>>>>>> そのときの割り込み番号が何かをデバッガなどで調べて教えていただけると
>>>>>> 現象が詳しくわかると思います。
>>>>>>
>>>>>> signal_time関数については、関連が見えませんでしたので、
>>>>>> もう少し詳しく教えてください。
>>>>>> どの辺りを実行したときに__kernel_default_int_handler_entryが
>>>>>> 呼ばれているか、呼び出し元はどこかなど、教えてください。
>>>>>>
>>>>>> 以上です。
>>>>>> よろしくお願いします。
>>>>>>
>>>>>> On 2016/01/04 22:54, 柴田正 wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>      はじめまして。柴田と申します。
>>>>>>>
>>>>>>> 以下の環境で、S12ADの結果をDMACで取得するプログラムを実装しています。
>>>>>>> 1) マイコン: GR-SAKURA(RX63N:http://sakuraboard.net/gr-sakura.html)
>>>>>>> 2) IDE: CubeSuite+ 1.02.01
>>>>>>> 3) JTAG: E1
>>>>>>> 4) ビルドツール: CC-RX v1.02.01
>>>>>>>
>>>>>>> 割込みハンドラで再度割込みを要求(※)すると、以下のメッセージが
>>>>>>> syslogに出力され、DMACの割込みが発生しないようになります。
>>>>>>> ”Unregistered Interrupt occurs.”
>>>>>>>
>>>>>>> ※このエラーが発生する直接の原因は、time_event.cのsignal_time関数の
>>>>>>>         下記コードで呼出され先でBRKコマンドが実行され、
>>>>>>>         おそらく、無条件トラップ割込みで
>>>>>>>         __kernel_default_int_handler_entryが呼ばれ、
>>>>>>>         syslogに出力しています。
>>>>>>>
>>>>>>>
>>>>>>> S12AD→DMACのコードは、Renesasのサンプルコード(※)を、
>>>>>>> Toppersに移植したもので、私が影響あると考える部分だけを
>>>>>>> 下記に抜粋しました。
>>>>>>> お手数とは思いますが、どなたか、対策/不具合調査方法を教えてください。
>>>>>>> よろしくお願いします。
>>>>>>>
>>>>>>> #現在は、1CHですが、将来的には、AD、DMAC共に、2チャンネルにする予定です。
>>>>>>> #当たり前かも知れませんが、dmaca_dmac1_handler2関数内のコードを
>>>>>>>        コメントアウトすると、それ以降、割込みが発生しないため、
>>>>>>>        エラーが発生しません。
>>>>>>>
>>>>>>> ---- cfgファイル ----
>>>>>>> ATT_INI({ TA_HLNG, 0, init_task });
>>>>>>> CFG_INT(199, {0, -1});
>>>>>>> DEF_INH(199, {TA_HLNG, dmaca_dmac1_handler2});
>>>>>>>
>>>>>>> ---- ソース ----
>>>>>>> void init_task(VP_INT exinf) {
>>>>>>>         dis_int(199);
>>>>>>>         Init_Adc();
>>>>>>>         ena_int(199);
>>>>>>> }
>>>>>>>
>>>>>>> void Init_Adc(void) {
>>>>>>>          mtu_init();
>>>>>>>          s12ad_init();
>>>>>>>          dmac_init();
>>>>>>> }
>>>>>>>
>>>>>>> void dmaca_dmac1_handler2(void) {
>>>>>>>         DMAC1.DMCNT.BIT.DTE = 1;
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ※http://japan.renesas.com/support/downloads/download_results/C1000000-C9999999/mpumcu/rx/an_r01an1265jj_rx63n_numerical_lib.jsp
>>>>>>>
>>>>>>> 以上です。よろしくお願いします。
>>>>>>>
-- 
--------------------------------------
コアーズ株式会社
開発部 長島 宏明
〒140-0001
東京都品川区北品川1-13-7長栄ビル3階
TEL:03-3450-8051 FAX:03-3450-8052
--------------------------------------