[RX631]PDG2を用いたSCI送信をDMACAにより行うサンプルをC++環境で実行する方法について

100rpmくらいでPOVをアルゴリズム考えてみよう


はじめまして、白と申します。

現在RX631でPDG2を用いながらSCIのDMAC転送による送信のサンプルを
動かそうとしております。

C++での開発を行いため,プロジェクトの新規作成時にC++のプロジェクトとして
作成したところ,所望の動作をしませんでした。

/*-------------------------------------
目的:
C++アプリケーションで、DMACを用いたSCIの送信を行うこと.
そのために,下記マニュアル178Pのサンプルプログラムを動作させること.

参照マニュアル
RX63N/RX631グループ
Peripheral Driver Generator
リファレンスマニュアル
(20UT2186JJ0102 Rev.1.02)

ページ Page 178 of 427

使用MCU R5F5631FDDFP (100pin LQFP)
(100MHz動作)

使用デバッガ E1 JTAG接続

開発環境
CS+ V5.00
PDG2 Version 2.09.000

ビルドツール設定
”double型、およびlong double型の精度”を
"倍精度として扱う"に変更.その他初期設定


-------------------------------------*/

----現状----
 上記マニュアルの178Pのサンプルプログラムをプロジェクトを
Cのプロジェクトとして作成し、実行した場合には
正常に動作することを確認しました。
 また、SCI機能単体でのデータ送信が正常に行えていることも
確認できました。そのため、回路面での問題ではないと考えております。

使用したコードはCの場合もC++の場合も同じものであり,
サンプルに追加した部分は,main関数に無限ループ処理を入れ
また、mainの先頭で,PDG2の生成関数(R_PG_Clock_Set();)を用いて、
クロック設定を行っています。

 全く同一のコードを、プロジェクトをC++のプロジェクトとして製作した場合

(上記マニュアルP64のチュートリアル部における
アプリケーション(CC-RX)を
C++アプリケーション(CC-RX)に変更し、
プロジェクトを製作)

した場合には,正常に動作しませんでした。
具体的には、DMAC転送完了割り込み通知関数の
末尾の
>>sci_dma_transfer_complete = true;
/*逆アセンブル
sci_dma_transfer_complete = true;

fbe204000000 MOV.L #00000004H,R14
f8e401 MOV.B #01H,[R14]
6702 RTSD #08H
*/
までは実行でき,その次のステップで
ff000000に飛びます.
ff000000 ? ?
となっております.

PDG2自体がC用のコード生成であるようですが,
DMACの部分以外の各機能に関しては、
C++アプリケーションでも使用可能でしたので、
どうにか,C++アプリケーションとして開発ができないだろうかと
願っております。そのため、C++アプリケーションとして、
上記サンプルを動作させるためにはどのようにすればよいか、
教えていただけましたらと思います。
長文となってしまいましたが、よろしくお願いします。


/*---------------------------------------
以下プログラムのソースコード
(サンプルプログラムと同一*/

//この関数を使用するには"R_PG_<プロジェクト名>.h"をインクルードしてください
#include "R_PG_default.h"
volatile bool sci_dma_transfer_complete; //DMA転送終了フラグ
uint8_t tr[]=”ABCDEFG”; //送信データ
void func(void)
{
//DMA転送終了フラグの初期化
sci_dma_transfer_complete = false;
R_PG_Clock_Set(); //クロックの設定
//SCI0を設定する
R_PG_SCI_Set_C0();
//DMAC0を設定する
R_PG_DMAC_Set_C0();
//DMA転送元、転送先アドレス、転送カウンタを設定する
R_PG_DMAC_SetSrcAddress_C0( tr );
R_PG_DMAC_SetDestAddress_C0((void*)&(SCI0.TDR));
R_PG_DMAC_SetTransferCount_C0( 8 );
//DMAC0を転送開始トリガ入力待ち状態にする
R_PG_DMAC_Activate_C0();
//SCI0の送信を有効にする (TXI割り込みが発生し、DMA転送が開始)
R_PG_SCI_SendAllData_C0(
PDL_NO_PTR,
PDL_NO_DATA
);
//DMA転送終了を待つ
while (sci_dma_transfer_complete == false);
}


void main(void)
{
R_PG_Clock_Set();

func();

func();
for(;1;){
;
}
}

//DMA割り込み通知関数
void Dmac0IntFunc (void)
{
//シリアル送信終了フラグ
bool sci_transfer_complete;
sci_transfer_complete = false;
//シリアル送信の終了を待つ
do{
R_PG_SCI_GetTransmitStatus_C0( &sci_transfer_complete );
} while( ! sci_transfer_complete );
//シリアル通信を停止
R_PG_SCI_StopCommunication_C0();
//DMACを停止
R_PG_DMAC_StopModule_C0();
sci_dma_transfer_complete = true;
}


/*---------------------------------------*/

  • すみません、投稿の先頭1行は無視してください。
    テキストエディタで下書きしていたのですが、直前のメモが残っておりました・・・
  • 白さん、こんにちは。NoMaYと申します。

    一読した印象では、CとC++の違いと言うより、それぞれのプロジェクトでの何らかの設定の違い(例えばセクション割り当てとか)の違いにより、何らかの不具合が発生(もしくは潜在していた不具合が表面化)して、サブルーチンからの戻りアドレスを格納していたスタックの内容が壊れてしまった、という現象のような気がしました。

    私は、いっそプロジェクトのファイル一式(PDG2の設定ファイルやPDG2が生成したコードなども)をZIPファイルに固めて添付して頂けるとアドバイスがしやすい、と普段から考えている人間なのですが、CとC++の両方のプロジェクトで、そうして頂くことは可能でしょうか?

  • 早速のご返信ありがとうございます。

    私も同様のことを考えて,問題が生じたプロジェクトとは別に,

    まずサンプルだけを動作させるためのプロジェクトを作り、テストを行っておりました.

    そのため、サンプルのmainの処理を追加しただけのプロジェクトとなってしまいますが,

    それについて添付します。PDG2のプロジェクトについても両方添付いたしましたが,

    PDG2のプロジェクトについては完全なコピーですので,一切の違いはないはずです。

     

    /*フォルダ構成*/

    |-Ver_C

     |-test2 :CS+のプロジェクト

      |-serial_class PDG2のプロジェクト

     

    /*--------*/

    Ver_C.zip

    としてzip圧縮で添付しました。

     

    また、逆アセンブラコードを少し見ていたところ,やはりCとC++では

    生成されるものが違うようです・・・

    //C++アプリケーション
    sci_dma_transfer_complete = true;

    fbe204000000 MOV.L #00000004H,R14
    f8e401 MOV.B #01H,[R14]
    6701 RTSD #04H


    //Cアプリケーション
    sci_dma_transfer_complete = true;

    fbe248040000 MOV.L #00000448H,R14
    f8e601 MOV.L #01H,[R14]
    6702 RTSD #08H

     

    他にも何か必要なことがありましたら、ご返信いただければ幸いです。

     

  • |-Ver_C++

    |-test :CS+のプロジェクト

    |-serial_class PDG2のプロジェクト

    Ver_C++.zip

     

    以上、2つのプロジェクトが実際に使用し、問題が生じているC++プロジェクトと

    Cプロジェクトです。

  • 白さん、こんにちは。NoMaYです。

    確かに、逆アセンブラコードが違いますね、何だろう、、、 これからプロジェクトを見てみます。

  • わわいです
    まず思いつくのは、スタックのエリアの容量が足りているのか?というとこらへんです
    そのFF000000に飛んで行くときのSPの値はどうなってますか
  • 白さん、こんにちは。NoMaYです。

    コンパイラにリストファイルを出力させてみて気付いたのですが、RTSD命令のオペランドが違うのは、最適化オプションが違う為のようです。また、プログラムが暴走するのは、bool型のサイズが違う為では無いでしょうか?(どうも、C++では1バイト、Cではintのtypedefで4バイト、[訂正] C89仕様でunsigned longのtypedefで4バイト、C99仕様で1バイト、の扱いのようです。そして、PDG2のソース及びライブラリでは4バイトとして扱われている為、引き渡されたアドレスの2,3,4バイト目を壊してしまった、のだと考えられます。)

    test.lst

                                     ;*** COMMAND PARAMETER ***
                                     
                                     ;-output=src=test.src
                                     ;-isa=rxv1
                                     ;-fpu
                                     ;-dbl_size=8
                                     ;-lang=cpp
                                     ;-include=serial_class
                                     ;-include=serial_class\i_src
                                     ;-include=serial_class\SCI
                                     ;-include=serial_class\IO
                                     ;-include=serial_class\DMAC
                                     ;-include=serial_class\SYSTEM
                                     ;-obj_path=DefaultBuild
                                     ;-debug
                                     ;-listfile=DefaultBuild
                                     ;-show=source
                                     ;-nologo
                                     ;test.cpp

    test2.lst

                                     ;*** COMMAND PARAMETER ***
                                     
                                     ;-output=src=test2.src
                                     ;-isa=rxv1
                                     ;-fpu
                                     ;-dbl_size=8
                                     ;-lang=c
                                     ;-include=serial_class
                                     ;-include=serial_class\i_src
                                     ;-include=serial_class\SCI
                                     ;-include=serial_class\IO
                                     ;-include=serial_class\DMAC
                                     ;-include=serial_class\SYSTEM
                                     ;-obj_path=DefaultBuild
                                     ;-debug
                                     ;-listfile=DefaultBuild
                                     ;-show=source
                                     ;-optimize=0
                                     ;-nologo
                                     ;test2.c

    test.lst

                                     ;      69 void Dmac0IntFunc(void){
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",69
    00000050 6080                           SUB #08H, R0
                                     ;      70  bool sci_transfer_complete=false;
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",70
    00000052 3E0100                         MOV.L #00000000H, 04H[R0]
    00000055                         L24:   ; bb
    00000055 710104                         ADD #04H, R0, R1
                                     ;      71  
                                     ;      72  do{
                                     ;      73      R_PG_SCI_GetTransmitStatus_C2(&sci_transfer_complete);
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",73
    00000058 05rrrrrr             A         BSR _R_PG_SCI_GetTransmitStatus_C2
    0000005C                         L25:   ; bb.split
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",72
    0000005C A809                           MOV.L 04H[R0], R1
    0000005E 6101                           CMP #00H, R1
    00000060 10                   S         BEQ L27
    00000061                         L26:   ; bb5
    00000061 F80600                         MOV.L #00000000H, [R0]
    00000064 08                   S         BRA L28
    00000065                         L27:   ; bb6
    00000065 F80601                         MOV.L #00000001H, [R0]
    00000068                         L28:   ; bb7
    00000068 EC01                           MOV.L [R0], R1
    0000006A 6101                           CMP #00H, R1
    0000006C 21rr                           BNE L24
    0000006E                         L29:   ; bb10
                                     ;      74  }while(! sci_transfer_complete);
                                     ;      75  
                                     ;      76  R_PG_SCI_StopCommunication_C2();
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",76
    0000006E 05rrrrrr             A         BSR _R_PG_SCI_StopCommunication_C2
    00000072                         L30:   ; bb10.split
                                     ;      77  R_PG_DMAC_StopModule_C0();
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",77
    00000072 05rrrrrr             A         BSR _R_PG_DMAC_StopModule_C0
    00000076                         L31:   ; bb10.split1
                                     ;      78  
                                     ;      79  sci_dma_transfer_complete = true;
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test2\test2.c",79
    00000076 FBE2rrrrrrrr                   MOV.L #_sci_dma_transfer_complete, R14
    0000007C F8E601                         MOV.L #00000001H, [R14]
    0000007F 6702                           RTSD #08H
                                     ;      80 }

    test2.lst

                                     ;      69 extern "C" void Dmac0IntFunc(void){
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",69
    0000004E 6040                           SUB #04H, R0
                                     ;      70  bool sci_transfer_complete=false;
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",70
    00000050 3C0300                         MOV.B #00H, 03H[R0]
    00000053                         L16:   ; bb
    00000053 710103                         ADD #03H, R0, R1
                                     ;      71  
                                     ;      72  do{
                                     ;      73      R_PG_SCI_GetTransmitStatus_C2(&sci_transfer_complete);
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",73
    00000056 05rrrrrr             A         BSR _R_PG_SCI_GetTransmitStatus_C2
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",72
    0000005A B089                           MOVU.B 03H[R0], R1
    0000005C 6101                           CMP #00H, R1
    0000005E 20rr                           BEQ L16
    00000060                         L17:   ; bb11
                                     ;      74  }while(! sci_transfer_complete);
                                     ;      75  
                                     ;      76  R_PG_SCI_StopCommunication_C2();
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",76
    00000060 05rrrrrr             A         BSR _R_PG_SCI_StopCommunication_C2
                                     ;      77  R_PG_DMAC_StopModule_C0();
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",77
    00000064 05rrrrrr             A         BSR _R_PG_DMAC_StopModule_C0
                                     ;      78  
                                     ;      79  sci_dma_transfer_complete = true;
                                            .LINE  "C:\Renesas\RX\issue_20171125\csp_projects\test\test.cpp",79
    00000068 FBE2rrrrrrrr                   MOV.L #_sci_dma_transfer_complete, R14
    0000006E F8E401                         MOV.B #01H, [R14]
    00000071 6701                           RTSD #04H

    ちなみに、stdbool.hで以下のように記述されていました。

    /* stdbool.h standard header */
    #ifndef _STDBOOL
    #define _STDBOOL
    #include <macro.h>
    #ifndef _YVALS
    #include <sys/yvals.h>
    #endif /* _YVALS */

    _C_STD_BEGIN

     #define __bool_true_false_are_defined    1

     #ifndef __cplusplus
            /* TYPES */

     #if 199901L <= __STDC_VERSION__

     #else /* 199901L <= __STDC_VERSION__ */
    typedef unsigned long _Bool;
     #endif /* 199901L <= __STDC_VERSION__ */

            /* MACROS */
     #define bool    _Bool
     #define false    0
     #define true    1
     #endif /* __cplusplus */

    _C_STD_END
    #endif /* _STDBOOL */

    /*
     * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
    V5.03:0216 */
  • 白さん、こんにちは。NoMaYです。

    探してみたところ、bool型のサイズについては、以下に説明がありました。

    データの内部表現と領域 - CS+オンラインヘルプ > コンパイラ編 > コンパイラ言語仕様 > 基本言語仕様 > データの内部表現と領域
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/latest/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0104y.html

    (1)

    スカラ型(C言語)、基本型(C++言語)

    C言語におけるスカラ型および、C++言語における基本型の内部表現を表 4.17に示します。

    表 4.17

    スカラ型・基本型の内部表現

     

    型名

    サイズ(byte)

    アライメント数(byte)

    符号の有無

    値の範囲

    最小値

    最大値

                 

    22

    bool *5

    _Bool *8

    1 *9

    1 *9

    -*9

    -

    -

                 
     
     
     
     

    注 5.

    C++プログラム、またはstdbool.hをインクルードしたCプログラムのコンパイル時のみ有効です。

     
     
     

    注 8.

    C99コンパイル、またはstdbool.hをインクルードしたCプログラムのコンパイル時に有効です。

    注 9.

    C89でコンパイルする場合は、unsigned long型と同じサイズ、アライメント数及び符号になります。

     

     

  • 白さん、こんにちは。NoMaYです。

    もし原因がそうであれば、対処法としては以下のような記述を追加してしまう、ことでしょうか、、、(ただし、きちんとドキュメントに書いておかないと、メンテする時に忘れてトラブルになる可能性がありそうですが、、、)

    // To use PDG2 library and generated code in C++ source file for CC-RX
    #ifndef bool
    typedef unsigned long _Bool;
    #define bool _Bool
    #endif

     

  • ご返信が遅くなり申し訳ありません。

    最低気がオプションを変更していたことを忘れてしまっていたようです。申し訳ありませんでした。

    bool型のサイズが異なるとは全く考えたこともありませんでした。
    参考URLの方ありがとうございます。説明していただけるとなるほどと思えるのですが、自分では全く思いつけそうにない点でした。

    対処法として記していただいたコードを追加したところ、サンプルは無事動作しました。

    業務用ではないので,幸いメンテについては考えなくてもいいのですが、他に問題が生じないか確認しながら進めてみたいと思います。

    詳細な理由まで含め、説明いただきまして、ありがとうございました。