■経緯について CS+4環境で開発済みであり安定動作できているRX71M用FWプログラムがあります。 このFWを最新のCS+6環境に置き換えるための作業過程で、USBホストドライバで 不具合事象が発生しました。
■不具合事象 CS+6(V6.01.00)/ビルドツールCC-RX V2.08.00環境でビルドしたFWでは、 USBメモリの認識ができなくなってしまったことが判明。再現率100%
■調査状況について ・再現率100%のため、切り分け調査を開始 ・切り分け調査した結果、USBホストドライバの一部ソースコードの最適化 コンパイルが影響していることが判明。
■確認済み環境 CS+4(V4.00.00)/ビルドツールCC-RX V2.05.00:問題なし CS+6(V6.00.00)/ビルドツールCC-RX V2.07.00:不具合事象あり CS+6(V6.01.00)/ビルドツールCC-RX V2.08.00:不具合事象あり
■USBHドライバの対象ソースコード \rx_fit\FITModules\r_usb_basic\src\hw - r_usb_creg_access.c - r_usb_hreg_access.c
■最適化レベル毎の再現性 最適化レベル2(-optimize=2) コード・サイズ重視の最適化(-size) : NG(不具合再現) 最適化レベル2(-optimize=2) 実行性能重視の最適化(-speed) : NG(不具合再現) 最適化レベル1(-optimize=1) コード・サイズ重視の最適化(-size) : OK 最適化レベル1(-optimize=1) 実行性能重視の最適化(-speed) : OK 最適化レベル1(-optimize=1) コード・サイズ重視の最適化(-size) : OK 最適化レベル0(-optimize=0) : OK
■不具合の出るコードの例と暫定対策の例 \rx_fit\FITModules\r_usb_basic\src\hw - r_usb_hreg_access.c void hw_usb_hset_rwupe (usb_utr_t *ptr, uint16_t port) { if (USB_PORT0 == port) { #if 0 // ★NG 元のコード ptr->ipp->DVSTCTR0.WORD |= USB_RWUPE; #else // ★OK こちらの書き方なら問題なし ptr->ipp->DVSTCTR0.WORD = ptr->ipp->DVSTCTR0.WORD | USB_RWUPE; #enfif } }
■今後の調査について 引き続き、根本原因を究明し、対策の検討を進めたいと考えています。 ・コンパイラのエラッタ確認(既知なのかどうか) ・ルネサスが公開している最新ドライバ(FITモジュール)の確認 ・最適化によるアセンブラコードの違いを確認 ・場合によってはソースコードを修正して対応する ・その他全てのドライバの確認(共通問題の可能性が高い)
何か情報お持ちの方がいましたら教えていただきたく、よろしくお願いいたします。
以上
こんにちは
CC-RXにおけるビット操作命令の生成についてV2.06.00で仕様変更がされていたようです。
【リビジョンアップ】RXファミリ用C/C++コンパイラパッケージ V2.06.00
⇒ 2.7 その他改善
(1) ビット操作命令の出力
もしかしてマニュアルのビット操作命令出力の条件に合致したりしてないでしょうか。
CC-RX コンパイラ ユーザーズマニュアル
⇒ 11.5.4 V2.06 以降【V2.05 以前からの変更点】
(1) ビット操作命令の出力を制御する方法の導入
シェルティさん、こんにちは。NoMaYです。(私のPCのCPUが古過ぎてCC-RX V2.04以降が使えず回りくどいレスですが)>私の環境(CC-RX V207、最適化2)では不再現でした。>特定コンパイルオプションの条件下において不正なコードが出力されるといったところで、>USBドライバ自体には問題がないように感じました。この部分は、私だけでなくて、ふじさんも気になる文面かと思いますが、生成されたコードは、ふじさんのNGコードの方では無くてOKコードの方だった、ということでしょうか?ふじさんのNGコード ≠ シェルティさんがCC-RX V2.07 最適化2で試された結果
(参) 4.2.5 キーワードの使用方法 - CS+ V6.01.00 > コンパイラ編 > コンパイラ言語仕様 > 拡張言語仕様 > キーワードの使用方法(1)指定サイズのアクセス記述tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0205y.html「__evenaccess <型指定子> <変数名><型指定子> __evenaccess <変数名>宣言または定義したサイズで変数をアクセスします。変数の型のサイズでアクセスすることを保証します。」ふじさんのOKコード(以下の3つは同じ) = シェルティさんがCC-RX V2.07 最適化2で試された結果
もしくは
あと、細かいところですが、ふじさんとじまさんの以下の文面はアセンブラに不慣れゆえの書き間違いかな、と思われます。以下の(a)と(b)に合致していませんので。11.5.4 V2.06以降【V2.05以前からの変更点】 - CS+ V6.01.00 > コンパイラ編 > 注意事項 > 旧バージョン・旧リビジョンとの互換性(1)ビット操作命令の出力を制御する方法の導入tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx11c0504y.html「組み込み関数を使用せずに、コンパイラにビット操作命令を必ず出力させる場合は、次の条件をすべて満たすソース・プログラムを記述してください。(a) 定数値を代入する(b) 代入先を1バイト型で1ビット幅のビットフィールドにする(c) 代入先をvolatile 修飾する」ふじさん>ビット操作命令出力の条件に合致しており、最適化しているためコンパイラ判断によるものとなっていました。↓(むしろ以下の文面かと思われます)ビット操作命令出力の条件に合致しておりおらず、最適化しているためコンパイラ判断によるものとなっていました。じまさん>もしかしてマニュアルのビット操作命令出力の条件に合致したりしてないでしょうか。↓(むしろ以下の文面かと思われます)もしかしてマニュアルのビット操作命令出力の条件に合致したり合致していなかったりしてないでしょうか。
こんにちは。NoMaYです。>OR 08H[R1].UB, R2 ← 皆さんが仰る通り unsigned short かつ __evenaccess のI/Oレジスタ対するコードとしては変ですね>MOV.B R2, 08H[R1] ← 皆さんが仰る通り unsigned short かつ __evenaccess のI/Oレジスタ対するコードとしては変ですねちょっと待った! >> 自分変なのかな?r_ usb_basic_if.h
typedef volatile struct st_usb0 * usb_regadr_t; ← ここに _evenaccess が無いですよね?typedef struct usb_utr usb_utr_t;typedef void (*usb_cb_t)(struct usb_utr *, uint16_t, uint16_t);typedef struct usb_utr{ usb_mh_t msghead; /* Message header (for SH-solution) */ uint16_t msginfo; /* Message Info for F/W */ uint16_t keyword; /* Rootport / Device address / Pipe number */ union { usb_regadr_t ipp; /* USB module startAddress(USB0/USB1)*/ #if USB_NUM_USBIP == 2 usb_regadr1_t ipp1; /* USB module start address(USBA) */ #endif /* USB_NUM_USBIP == 2 */ }; uint16_t ip; /* USB module number(0 or 1) */ uint16_t result; /* Result */ usb_cb_t complete; /* Call Back Function Info */ void *p_tranadr; /* Transfer data Start address */ uint32_t tranlen; /* Transfer data length */ uint16_t *p_setup; /* Setup packet(for control only) */ uint16_t status; /* Status */ uint16_t pipectr; /* Pipe control register */ uint8_t errcnt; /* Error count */ uint8_t segment; /* Last flag */ void *p_usr_data;} usb_message_t;
iodefine.h
struct st_usb0 { ← ここにはコンパイラの仕様上 _evenaccess を記述出来ません... union { unsigned short WORD;// struct {// unsigned short :4;// unsigned short HNPBTOA:1;// unsigned short EXICEN:1;// unsigned short VBUSEN:1;// unsigned short WKUP:1;// unsigned short RWUPE:1;// unsigned short USBRST:1;// unsigned short RESUME:1;// unsigned short UACT:1;// unsigned short :1;// unsigned short RHST:3;// } BIT; } DVSTCTR0;...};#define USB0 (*(volatile struct st_usb0 __evenaccess *)0xA0000) ← ここに _evenaccess が付いてますよね?
こんにちは。NoMaYです。分かった、、、(少なくとも)最新のUSBドライバのソースでは変更されてますね、、、r_usb_typedef.h
typedef volatile struct st_usb0 __evenaccess * usb_regadr_t; ← ここに _evenaccess が付いてますね!typedef struct usb_utr usb_utr_t;typedef void (*usb_cb_t)(struct usb_utr *, uint16_t, uint16_t);typedef struct usb_utr{ usb_mh_t msghead; /* Message header (for SH-solution) */ uint16_t msginfo; /* Message Info for F/W */ uint16_t keyword; /* Root port / Device address / Pipe number */ union { usb_regadr_t ipp; /* USB module startAddress(USB0/USB1)*/ #if USB_NUM_USBIP == 2 usb_regadr1_t ipp1; /* USB module start address(USBA) */ #endif /* USB_NUM_USBIP == 2 */ }; uint16_t ip; /* USB module number(0 or 1) */ uint16_t result; /* Result */ usb_cb_t complete; /* Call Back Function Info */ void *p_tranadr; /* Transfer data Start address */ uint32_t tranlen; /* Transfer data length */ uint16_t *p_setup; /* Setup packet(for control only) */ uint16_t status; /* Status */ uint16_t pipectr; /* Pipe control register */ uint8_t errcnt; /* Error count */ uint8_t segment; /* Last flag */ void *p_usr_data;} usb_message_t;