Galaxy Tab s 10.5 Wifi版をAndroid13相当にUpdateする3

前記事ではスタムOS用のGoogleサービスエンジンの一つである MindTheGapps のインストールまで完了しました。次にGoogleのセットアップを行います。実施してみたところ、Xperia Z4 Tablet とは少し違っていました。


以下のとおりでした。この状態で Google Play ストア をインストールし、実行しても落ちてしまいました。


Xperia Z4 Tablet では現れていた Goolge の更新ボタンが今回では見られません。

Google Play ストア が未だないので、アプリの .apk を用意し、オフラインでインストールします。弊方では公式Android13が入っている端末の’25.1月時点のバージョンに習い以下のものを入れました。

GoogleVer. 15.40.41 【特に入れなくていいかも】
Google 開発者サービスapkによるUpdate不可
Google Play ストアVer. 44.1.17-23Install後、アプリ権限、システム更新権限を手動で付与すること。

この後、WiFiを接続し、端末を再起動します。以下手順です。ちなみに Google Play ストア は初回起動ではコケます。


Google Playの起動は、

試しにMAPを入れてみます。うまくいったようです。


以上、SM-T800を Android13相当にupdateし、Google Play の動作させるまでの手順です。しかしながら自分でやるのはメンドクサイ、忙しい、自身が無い方は、弊方でセットアップをお受けいたします。Google Paly初期セットアップに手間をようするため難易度中、約1.25時間の個人様向け工数+事務費で税込4,000円~ ご相談、依頼はこちらから。

Galaxy Tab s 10.5 Wifi版をAndroid13相当にUpdateする2

前回では、SM-T800 を Android13 相当にUpdateまでしました。次にカスタムOS用のGoogleサービスエンジンの一つである MindTheGapps のインストールエラーの調査と対策を行います。


XDAのSM-T800 LinageOS 20 のページをみると、MindTheGapps13 がインストールできないとの投稿があり、その対策版情報がありました。MindTheGapps_Legacy-13.0.0-arm64-20231025_200931.zip です。試したところ、前回の「Could not mount ...」は発生しないもののGoogleサービスはインストールされません。何も作用がありません。インストール自体1秒もかからず早すぎです。


MindTheGapps でなく、別種Gapp: NikGapp というのがあります。こちらを試しましたがダメでした。

NikGapps-core-arm64-13-20241231-signed.zipTWRPで Error 1 発生。
NikGapps-core-arm64-12-20241231-signed.zipTWRPで Error 1 発生。
NikGapps-Juan-Basic-arm64-13-20250110-unofficial.zipTWRPで Error 1 発生。


MindTheGapps のパッケージはただのzipなので構造と仕組みを調べてみます。

おおざっぱdirectory構造は以下のとおりです。黒字がDirectory、緑字がfile です。

  • META-INF
    • com
      • android
      • google
        • android
          • update-binary [ココがインストールscript]
  • system [②ココがインストール配布物、OSのDirectory構造と同じ]
    • addon.d
    • product
      • app
        • 各アプリFolder
          • 各アプリ.apk
      • lib
        • 各.so (unix共有dynamic Library)
      • lib64
        • 各.so (unix共有dynamic Library)
      • priv-app
        • 各アプリFolder
          • 各アプリ.apk
    • system_ext
      • priv-app
        • 各アプリFolder
          • 各アプリ.apk

上記①は、UNIXシェルスクリプト です。幸い割と得意なので解析&デバックできそうです。


update-binaryスクリプトの内容を読むと以下のような感じでした。(以下説明を理解するにはUNIX 基本知識が必要です)

  1. OS Directory ( /system, /product, /system_ext ) を一旦unmoutする。
  2. 端末ストレージの/devリスト:/etc/recovery.fstab ( dfコマンドの写し )から、/system, /product, /system_ext の /devファイル を取得する。
  3. /devファイル から、/system, /product, /system_ext を 再mount する。
  4. ストレージ残容量をチェックする。
  5. インストール対象の 各アプリ.apk の一覧を 30-gapps.sh を生成する。これが /system/android.d にコピーされ、OS初回起動時に 各アプリ.apk が自動インストールされる仕組みのようです。
  6. MindTheGapps/system 下の全fileを、パーミッションを保ったまま、OSの/systemにコピーする。
  7. OSの/product が /system と別ストレージの場合、MindTheGapps/system/produc を パーミッションを保ったまま、OSの/product にコピーする。
  8. OSの/system_ext が /system と別ストレージの場合、MindTheGapps/system/system_ext を パーミッションを保ったまま、OSの/system_ext にコピーする。


update-binaryスクリプトにトレースを追加して動作させてみます。TWRP上では標準出力( echoコマンド )は使えないようです。update-binary内の用意されている ui_print() を使います。MindTheGapps のzipを解凍し、update-binary変更後、MindTheGappsを再zipします。再zip時は、META-INF と system が直下になるようにします。7zipなら以下のようにします。

folder全体zipしていまうと Directory 階層が出来てしまうので、TWRPがzipを認識しなくなります

実行してみると以下のような結果でした。

前述のスクリプト手順2. が 端末 もしくは TWRP に合っていないようです。SM-T800の/etc/recovery.fstab の内容は以下のとおりです。

/boot		emmc	/dev/block/bootdevice/by-name/BOOT
/recovery	emmc	/dev/block/bootdevice/by-name/RECOVERY	flags=backup=1
/misc		emmc	/dev/block/platform/dw_mmc.0/by-name/OTA
/system		ext4	/dev/block/bootdevice/by-name/SYSTEM
/system_image	emmc	/dev/block/bootdevice/by-name/SYSTEM
/data		ext4	/dev/block/bootdevice/by-name/USERDATA	flags=encryptable=footer;length=-16384
/cache		ext4	/dev/block/bootdevice/by-name/CACHE
/modem		emmc	/dev/block/bootdevice/by-name/RADIO	flags=backup=1;display="Modem";flashimg
/hidden		ext4	/dev/block/bootdevice/by-name/HIDDEN	flags=backup=1;display="Hidden"
/hidden_image	emmc	/dev/block/bootdevice/by-name/HIDDEN	flags=display="Hidden Image";flashimg
/efs		ext4	/dev/block/bootdevice/by-name/EFS	flags=backup=1;display="EFS"
/efs1		emmc	/dev/block/bootdevice/by-name/m9kefs1	flags=backup=1;subpartitionof=/efs
/efs2		emmc	/dev/block/bootdevice/by-name/m9kefs2	flags=backup=1;subpartitionof=/efs
/efs3		emmc	/dev/block/bootdevice/by-name/m9kefs3	flags=backup=1;subpartitionof=/efs
/external_sd	vfat	/dev/block/mmcblk1p1 /dev/block/mmcblk1	flags=display="Micro SDCard";storage;wipeingui;removable
/usb-otg	vfat	/dev/block/sda1 /dev/block/sda		flags=display="USB OTG";storage;wipeingui;removable

上記「 /system ext4 /dev/block/bootdevice/by-name/SYSTEM」行の「/dev/block/bootdevice/by-name/SYSTEM」が抽出できればよいようです。このオリジナルの抽出コード行は以下のようになっています。

grep -v "^#" /etc/recovery.fstab | grep "[[:blank:]]$1[[:blank:]]" | tail -n1 | tr -s [:blank:] ' ' | cut -d' ' -f1

コメントでなく、$1(system)が見つかった 最初の一行をスペースでカットした… みたいな感じですね。SM-T800のフォーマットと合っていないのでしょう。MindTheGapps_Legacy-13.0.0-arm64-20231025_200931.zip の抽出コード行は以下のように少しシンプルですが、grep の -o オプションはUNIX処理系によって無いようです。オリジナルgrepには無し。TWRP3.7上では使えませんでした。

cat /etc/recovery.fstab | cut -d '#' -f 1 | grep /system | grep -o '/dev/[^ ]*' | head -1

いずれにしても修正が必要です。 弊方ではawkを使ってもっとシンプルにします。本物UNIX育ち弊方ではこれが自然です。近年Linux育ちの方は不自然なのでしょうか? ちなみにプロセスID取得時は、ps -ef|grep プロセス名|awk `{print $1}` と千回は叩いたでしょうか。 TWRP上でも使えました。 頭コメント^#判定も特に不要。 以下コード例です。これで一つ解決です。

cat /etc/recovery.fstab | grep ^$1 | awk '{print $3}' | head -1


前述修正1では、/devファイルは取得できるようになりましたが、インストール後の反応は未だ見られません。以下のように調べます。

  • update-binaryのクリーンアップ部をコメントアウトして、MindTheGapps.zip の展開結果をストレージ上に残すようにする。
  • MindTheGapps.zip をinstall。
  • MindTheGapps の作業フォルダ /tmp/system に移動。
  • 試したいスクリプトと同じコマンドを叩く。

これにより問題のあった行は以下でした。

ui_print "Copying files"
cp --preserve=a -r ./* "${SYSTEM_OUT}/"

cp コマンドの –preserve オプションはUNIX処理系によって無いようです。TWRP3.7ではオプションエラーになりました。TWRPの標準出力は無効になっており、cpコマンドの exit値: $? の未チェックなので使用者は異常に気付かず. . . といった不具合メカニズムのようです。パーミッションを保ちたいらな -r オプションでいいハズです。以下のように修正します。

ui_print "Copying files"
cp -pr ./* "${SYSTEM_OUT}/"

これでインストール内容は反映されるようになりました。しかしこれでだけではインストールコピー失敗の気付きになりません。以下のようにコピーされたfile数を表示できるようにします。

ls -1R ${SYSTEM_OUT}	> $TMP//MindGappCpBefore.txt
cp -pr ./* "${SYSTEM_OUT}/"
ls -1R ${SYSTEM_OUT}	> $TMP/MindGappCpAfter.txt

# show number of copy files.
diff -w /tmp/MindGappCpBefore.txt /tmp/MindGappCpAfter.txt | grep ^+[a-zA-Z]> $TMP/MindGappCpList.txt
rm -f $TMP//MindGappCpBefore.txt $TMP/MindGappCpAfter.txt
COPY_COUNT=`cat $TMP/MindGappCpList.txt | wc -l`
ui_print "$COPY_COUNT files has copied."


修正後のトータル実行結果は以下のとおり。他の端末ではテストできていないので SM-T800 用と明記しておきます。

これで Googleサービス のインストールできました。次のサービスのセットアップに続きます。なお本修正の公開はGithubに置きますので少しおまちください。

Galaxy Tab s 10.5 Wifi版をAndroid13相当にUpdateする1

リピートユーザさんからご相談があり実施した記録です。Galaxy Tab s 10.5 Wifi版は、2014製、Android6止まりですが、Samsungの高級タブレットシリーズ “S”初代、有機EL、解像度 2560×1600、1.9 GHz4コア、ブロンズメタリックで高級感あり、中古価格も安い。中々Goodな端末です。


SM-T800のカスタム調査を進めると、LinageOS17 (Android10相当) が見つかりますが、この手の掲示板XDAをみるとなんと LinageOS20 (Android13相当) が見つかりました。 10年前の端末が Android13 にできるなんてブルジョアです。

OSインストール手順は、boot loader と リカバリ が別々になっているくらいで、SC-03G と概ね同じです。以下インストール必要物です。

書換用WindowsアプリOdin3ver. 3.14.4
root化イメージCF_AutoRoot_Port_T800_BeansTown106.tar.md5
boot loaderT800XXU1CPK2.tar.md5
カスタムリカバリtwrp-3.7.0_9-0-chagallwifi.img.tar3.4.0-0,-3.6.2_9でもOK。
OSイメージlineage-20.0-20230426-UNOFFICIAL-chagallwifi.zip
制限事項指紋認証は使えない。

以下簡易説明です。細かい部分はSC-03G をみてください。

Volum Down + Home を押しながら電源ボタンONし、odinモード で起動。ボタン配置は以下のように逆になっているので、Volum Down と Volum Up を間違えないよう。

PCで、odinを起動、指定ファイルを読込み、書込みます。

一度起動して root化 を確認。

Volum Down + Home を押しながら電源ボタンONし、odinモード で起動。odinで指定ファイルを読込み、書込みます。これを実施しないとOSが起動しません。

Volum Down + Home を押しながら電源ボタンONし、odinモード で起動。odinで指定ファイルを読込み、書込みます。

Volum Up + Home を押しながら電源ボタンONし、リカバリモード で起動。

Android File Host に置いてあった LinageOS17 の最新2024/08/17版を書いてみると失敗です。

LinageOS17 の最新2023/02/18版はOK。

ちょっと釈然としないのでもう少し探索すると LinageOS 20 版(Android13相当) がありました。GithubはこちらXDAのスレッドはこちら。びっくりです。書込みは問題なし。


LinageOS 20 版で、起動は問題ないです。動作速度も遜色なし。IMEIがデフォルト非表示になっているなど、より新しいOSの利点ですね。

Samsungで気になる指紋認証と、GPSの確認は以下のとおり。


LinageOS では Goolgeサービス( 設定アプリのGoogleアカウント)、Google Play は入っていません。カスタムOS用のそれが MindTheGapps です。Android 13用を、カスタムリカバリ:TWRP からインストールしてみると失敗しました。


以上、OS自体はセットアップできましたが、Google Play は使えない状態です。まあ無償アプリで、apk が公開されているものなら使えるので、これで支障はないです。しかしあからさまにインストールできないのは妙です。次の記事で調査と対策をしていきます。

Xperia E1 Dual D2105 をAndroid 6または7.1.2相当にUpdateしてみる2

前記事では各種OSのインストールとウイークポイント調べ、Walkmanアプリの各バージョンの動作を確認しました。今回は本端末の最大の特徴である Walkman Button について調べました。


AndroidのOS構造は全く理解していませんが、 Walkman Button を誰がどのように検出しているかを知る必要があります。考えられるケースとしては、

  1. OSにWalkman Button ドライバ部があり、それが提供するAPIアプリが使用している。正攻法ですが端末メーカ独自のボタンを組込める基本構造なのかギモンです。Samisung Tab Active3 はボタンが7つくらいあるものもあり、どうなってるんでしょう?
  2. Walkman Button にデバイス( /dev/なんとか )が割当てられていて、APIアプリがそれにアクセスし検出している。同じLinux系のラズパイのI/Oポートはこの方式です。
  3. Walkman Button の操作をラッパーする常駐アプリがある。先刻の確認ではLinageOSではカメラボタンに割当てられていました。Android OSは独自のボタンを許容していない可能性もあります。そうすると、この方式しかないということになります。


一枚SIM版のD2005のOSコードは公開されていたので見てみました。(今回端末D2105用はなぜか無い) Eclipceにインポートして、BUTTONGPIO(入出力ポート) というキーワードで検索すると、ボタン割当てぽいところがあり。しかしWalkmanというものは無し、

つづいてWalkmanというキーワードで検索すると、

以上のことから、考察1No.3 の方式の可能性が高そうです。アプリを一生懸命確認しても無意味そうです。


プレインストールアプリの中のどれかがラッパーアプリか動かして調べるにしても、50コ近くあり、And6 や And7.1.2 で起動しないかもしれません。自分で作る? 既にこの世にあるのでは? Button Mapper というアプリがありました。OSの音楽再生イベントがあり、それとリンクさせるんですね。当アプリで、Walkman Buttonを認識させるとOS上はカメラボタンになっていました。なるほど。

これで問題点は解消、素晴らしいアプリです。少し寂しいですが、音楽再生アプリは、Walkmanアプリ でなくてなんてせもいいってことになります。


残るのは、wma再生、ラジオ、カメラ ですね。

社会保険の賞与不支給申請を行う

売上タイミングでなかなか12月に賞与が出せません。賞与が遅れる場合も賞与支給申請を出せと社会保険事務局から追及されます。その賞与不支給申請手続きの覚え書きです。

e-gov アプリでの手続き名は以下のとおりです。

以下入力例です。

もうひとつの支払い届も提出します。

記入例は以下のとおりです。

RH850F1KHで自動生成コードをベースでCANドライバーを作る3

前記事では北斗電子さんHSBRH850F1KH176向けにRH850自動コード生成し、RH850/U2A 用のCANドライバサンプルコードをRH850F1KH用に移植し、CAN送信をテストまでできました。今回は受信をテストします。その覚書きです。テスト環境は前記事と同じです。一先ず送信までできていれば、ハード的には送受信OKのはずです。


受信ルール は旧来のCAN Message Box の CAN ID Mask を包括したものといえます。受信ルール 数は以下のようになっています。

適用受信ルール数
CAN UNIT 一つあたり256
CAN Cahnel任意、0~256

受信ルール のCh毎割当ては r_rh850_can_cfg.c にて以下のように設定します。Channel の group が 2つに分かれ 、リトルエンディアンなので定義の一番下が Ch. 0 になります。分かっていてもついつい上から Ch .0 と思い書いてしまいがち、なかなか気付ずトラップです。Ch毎割当数==0では受信無反応となってしまいます。

can_rx_rule_num_t	g_can_rx_rule_num[ USED_UNIT_NUM ]  = {
// ========================== U n i t 0 設 定 ==========================
	{
		{		// group0 (ココ注意Trap:一番下がch0)
		 	0,	// Ch3
		 	0,	// Ch2
		 	16,	// Ch1
		 	16,	// Ch0
		},
		{		// group1 (ココ注意Trap:一番下がch4)
		 	0,	// Ch7
		 	0,	// Ch6
		 	0,	// Ch5
		 	0,	// Ch4
		},
	},
};


CAN ID 一つづつに受信ルール を割当てれば、 F1KH の176pinなら 256の CAN ID+データ を受信できそうですが、後述する 受信Buffer の制約を受けます。 むろんCAN ID MASK値を絞って一つの受信ルール で複数のCAN IDでを受信してもOKですが、CANデータは素早くRAMに退避する必要があります。

取り急ぎテストでは以下のように、受信ルール が 1つにつき、CAN ID 一つで行うとします。

CAN Ch.CAN ID受信ルール
00x1000
00x1011
10x20016

受信ルール の定義コードは以下の通りです。受信ルール の4つのSFR: ID、MASK、ポインタ0、ポインタ1 詳細はF1KHマニュアルを見ます。MASK値の ID種、Frame種、Node種は 基本1を立てます。32bit 16進数表記では間違い易いため、 弊方では設定マクロを追加しています。

const uint32_t g_rxrule_table[ USED_UNIT_NUM ][ CAN_RX_RULE_NUM ][ 4 ] = {
// ========================== U n i t 0 設 定 ==========================
	{
		// ------------------------ C h 0 設 定 ---------------------------
		{ // [0]
			CAN_RX_RULE_ID(0/*標準ID*/, 0/*DataFrame*/, 0/*他Node*/, 0x100/*ID*/),
			CAN_RX_RULE_MASK(1/*ID種*/, 1/*Frame種*/, 1/*Node種*/, 0x7FF/*ID*/),
			CAN_RX_RULE_PTR0(0x0000/*label*/, 1/*buf使用*/, 0/*buf番号*/, 8/*dlc*/),
			CAN_RX_RULE_PTR1(0x000000/*送受信FIFO*/, 0x00/*受信FIFO*/),
		},
		{ // [0]
			CAN_RX_RULE_ID(0/*標準ID*/, 0/*DataFrame*/, 0/*他Node*/, 0x102/*ID*/),
			CAN_RX_RULE_MASK(1/*ID種*/, 1/*Frame種*/, 1/*Node種*/, 0x7FF/*ID*/),
			CAN_RX_RULE_PTR0(0x0000/*label*/, 1/*buf使用*/, 1/*buf番号*/, 8/*dlc*/),
			CAN_RX_RULE_PTR1(0x000000/*送受信FIFO*/, 0x00/*受信FIFO*/),
		},
・・・ 中略 (定義の欠番はNG) ・・・ 
		// ------------------------ C h 1 設 定 ---------------------------
		{ // [16]
			CAN_RX_RULE_ID(0/*標準ID*/, 0/*DataFrame*/, 0/*他Node*/, 0x200/*ID*/),
			CAN_RX_RULE_MASK(1/*ID種*/, 1/*Frame種*/, 1/*Node種*/, 0x7FF/*ID*/),
			CAN_RX_RULE_PTR0(0x0000/*label*/, 1/*buf使用*/, 16/*buf番号*/, 8/*dlc*/),
			CAN_RX_RULE_PTR1(0x000000/*送受信FIFO*/, 0x00/*受信FIFO*/),
		},
・・・ 中略 (定義の欠番はNG)・・・ 
		
		


RH850では受信内容の取得方法が2つあるようです。今回はその中でシンプルな 受信Buffer による受信でテストします。 受信Buffer 数は以下のとおりです。

適用受信Buffer数
CAN UNIT 一つあたり128
CAN Cahnel任意、0~128

CAN ID に一つづつ受信Buffer を割当てれば、 F1KH の176pinなら 128コCAN ID+データ を同時期に受信でき、最新のそれぞれのCANデータ内容をSFRに保持でき、最も効率的といえます。むろん受信Buffer を複数のCAN IDで使いまわしてもOKですが、CANデータは素早くRAMに退避する必要があります。

受信Buffer は 送信と異なり CAN Channel の割当てはなく、一つの CAN UNIT 内で自由です。 受信ルール が 1つにつき、受信Buffer を一つ割当てます。上記のコード例では以下のように割当てています。

CAN ID受信ルール受信Buffer
0x10000
0x10111
0x2001616


設定は、API: R_CAN_Init() の中で行われます。CAN通信中には行うべきものではないようです。注意点は各数は以下のようななっています。

適用
受信ルール255
受信ルールSFRセット16

これは受信ルール のページ番号を 0~15 に切替えながらSFR を使い回す仕組みになっています。弊方では「U2Aとの違い?」と勘違いしてしまいました。 受信ルール の現在設定値もSFR値をウオッチしても分からないんです。 受信ルール は一つづつテストしていくしかなさそうです。


受信Buffer による受信では受信完了割込みは発生しません。 API: R_CAN_ReadRxBuffer() でポーリングチェックします。ただCANドライバのOriginal仕様では 、ポーリング周期内に複数CAN Frame受信するケースには対応していません。弊方ではここは改造しました。その呼出し部は以下のような感じです。

	  uint32_t		last_tm = 0;
	  uint32_t		now_tm = 0;
	  uint8_t 		CAN_RxBufIdx[ CAN_RX_MAX_1MSEC ];	// 受信Buffer Index
    can_frame_t 	CAN_RxBuffer[ CAN_RX_MAX_1MSEC ];	// 受信Frame内容
	
    while ( 1U ) {
    	/// 初期化待ち ///
    	if ( complateInit == FALSE ) {
 ・・・ 中略 ・・・    	
    		}
    	}
    	/// 初期化済み ///
    	else {
    		now_tm = R_Config_TAUB_Get1msTimer();

    		if ( now_tm - last_tm > 0 ) {	// 1ms経過した
    			// 全CHからの受信CHECK
    			retCan = R_CAN_ReadRxBuffer(
   					0                 /*unit*/,
						CAN_RX_MAX_1MSEC,	/* 同時受信Frame max数 */
						CAN_RxBufIdx,		  /* 受信あったBuffer番号*/
						CAN_RxBuffer 		  /* Frame内容*/ );
    		}
 

テストは BUSMATER から疑似CAN Frame を送信し、e2Studio + E1 でStudioで内部をウオッチして確認します。Ch.0 、Ch.1ともに。


これで RH850F1KH で、自動コード生成とサンプコードを用いて最短(?)で動作検証およびプラットフォーム作成ができました。延べ3week程度でしょうか?

手順とそのポイントは以上ですが、RH850F1KH を直ぐに動かしたい、工数がない、自身がない会社さん等はご相談を受付けています。ある程度の有償でもよろしければこちらまでご一報ください

RH850F1KHで自動生成コードをベースでCANドライバーを作る2

前記事では北斗電子さんHSBRH850F1KH176をターゲットにRH850自動コード生成をベースとし、RH850/U2A 用のCANドライバサンプルコードを、RH850F1KH用に基本部分を移植しました。次にCAN送信をテストしていきます。今回は企画元がFD未対応なので、CAN2.0のみの使用です。


CAN受信側のハードは、PEAK CAN-USB FDバージョン を用います。代理店さんから購入予定でしたが、ebayで新品放出品があり入手しました。正規ルート以外はコピー品も多いようなので要注意です。ドイツから直接購入は出来ないようです。過去職場でCAN2.0版を導入しましたが、筐体が黒になり安っぽさが消えたように見えます。Kavaer PCeボートも保有していますが、今回、新しく試しています。

配線はpin1とpin4を逆にしないよう注意です。HSBRH850F1KH176 のCANコネクタはpin番号がシルクに書いないようです。JST製なのでpin番がハウジングに書いてあったと思いましたが見当たらず。付属のケーブルは線が細くはんだ付して直ぐ切れそうリスキーです。太い線で作り直した方がよさげです。CANも絶縁になっていないので回路検討としてはCANトランシーバから先は別で組んだ方が良いかも。

CAN受信側のソフトはオープンソースのBUSMATER を用います。CAN DBを定義でき、CANシグナルに分けてサンプリングとログができます。CANLayzer の CAN DB のコンバートも可。しかし数年間、UPDATEがありません。のでCAN-FDには未対応です。過去職場でも紹介し導入し、割と評判が良かったですが、世間的には知名度が低いのでしょうか? (リリース当時ETASさんもアピールしていましたが) にしてもKavaer CAN King ( 全然Kingじゃない )は使い物にならないと思うのですが…


マニュアル 「表 24.125 通信速度の設定例」の表内の「(数値)」が、CANクロックの分周ですが、そのまま設定するとBUSエラーになります。通信速度の計算式をみると、そこから -1 が必要です。CANクロック:fCAN40MHz1Mbpsの場合、r_rh850_can_cfg.c の設定は以下のようになります。Tq数( 1bitの分解能、通信相手によっては調整要す )は取急ぎ粗目に 8 としています。

const can_ch_cfg_t  g_can_ch_cfg[ USED_UNIT_NUM ][ MAX_CH_NUM_U0 ] = {
// ========================== U n i t 0 設 定 ==========================
{
	// ------------------------ C h 0 設 定 ---------------------------
    {
    ・・・中略・・・
     /* ---- Normal Baudrate ----
       パラメータ( 分周比, SEG1 Bit-Timing, SEG2 Bit-Timing, Jump幅)
  	 */
    	CAN_CFG_N_BAUDRATE(
			// 1Mbps 分周比 = 40Mhz ÷ ( 1MHz × Tq数:8 ) = 5 より-1
   			4U, CAN_NTSEG1_5TQ, CAN_NTSEG2_2TQ, CAN_NSJW_1TQ
		),
    	/* ---- Data Baudrate ---- */
    	CAN_CFG_D_BAUDRATE(
			// 1Mbps 分周比 = 40Mhz ÷ ( 1MHz × Tq数:8 ) = 5 より-1
			// 取急ぎCAN2.0では Normal Baudrate と同じでよい模様。
   			4U, CAN_NTSEG1_5TQ, CAN_NTSEG2_2TQ, CAN_NSJW_1TQ
		),

設定値まとめを以下に示します。なお一般的に乗用車両は500kbps、働く車やレクレーションVehicleは250kbpsですが、レースや車両評価で使う場合は1Mbpsが多いようです。

項目
通信速度1Mbps
fCAN クロック40Mz
クロック分周5
Tq数8
SEG1 Bit Timing5
SEG2 Bit Timing2
Bitズ レジャンプ幅1

CANクロック::fCANは、設定にもよりますが下図の部分でよいようです。


RH850では送信は3つの方法があります。その中で送信Buffer が一番シンプルな手段です。使用する APIは R_CAN_TransmitByTxBuf (orgは略しすぎなので改名してます) です。送信Buffer 数は以下のようになっています。

項目
1 Channelあたり送信Buffer数36
1 Unitあたり送信Buffer SFR数255

CAN Channel と 送信Buffer の割当てがイマイチ分かりにくいです。単純に 「 Channel番号 × 36 + CH毎に使うBuffer番号」 でいいようです。OrignalのAPIは 送信Buffer 番号は絶対値なので、ch毎の相対にした方が使いやすいでしよう。以下コードを追加しました。

#define CAN_CH_TO_TX_BUF( ch, num )			( ch * MAX_TX_BUF_OF_CH	+ num )
・・・中略・・・
	// 送信Buffer番号を算出
	txbuf_idx = CAN_CH_TO_TX_BUF( ch_idx, txbuf_idx )

以下呼出しコード例です。基板確認のため、Ch 0、Ch 1両方試します。

	Can_RtnType ret;
	can_frame_t	frame;

	frame.ID	= 0x700;
	frame.DLC	= 8;
	frame.IDE	= 0;	  // 標準frame
	frame.TMFDF = 0;	// CAN2.0
	frame.RTR	= 0;
	frame.DB[ 0 ]	= 0x30;
	frame.DB[ 1 ]	= 0x31;
	frame.DB[ 2 ]	= 0x32;
	frame.DB[ 3 ]	= 0x33;
	frame.DB[ 4 ]	= 0x34;
	frame.DB[ 5 ]	= 0x35;
	frame.DB[ 6 ]	= 0x36;
	frame.DB[ 7 ]	= 0x37;

	ret =  R_CAN_TransmitByTxBuf(	0,	// i : CAN Unit
								  0, 	    // i : CAN Ch番号
									0, 	    // i : 送信Bfffer番号
									&frame	// i : CAN Frame
	);
	
  frame.ID	= 0x701;
	frame.DLC	= 8;
	frame.IDE	= 0;	// 標準frame
	frame.TMFDF = 0;	// CAN2.0
	frame.RTR	= 0;
	frame.DB[ 0 ]	= 0x40;
	frame.DB[ 1 ]	= 0x41;
	frame.DB[ 2 ]	= 0x42;
	frame.DB[ 3 ]	= 0x43;
	frame.DB[ 4 ]	= 0x44;
	frame.DB[ 5 ]	= 0x45;
	frame.DB[ 6 ]	= 0x46;
	frame.DB[ 7 ]	= 0x47;

	ret =  R_CAN_TransmitByTxBuf(	0,	// i : CAN Unit
								 	1, 	    // i : CAN Ch番号
									0, 	    // i : 送信Bfffer番号
									&frame	// i : CAN Frame
	);

BUSMASTERでの受信結果は以下のとおりです。送信できない場合、あまり不確定要素はないため、配線ミスかBaudrate間違いの可能性が高いです。

なお送信前に、送信中かエラー中かの判定もないので追加したほうがいいでしょう。API: R_CAN_CheckTxBufResult でも代用できるかもしれません。

	{
		volatile uint32_t sts;

		sts = RCFDCnCFDCmSTS( ch_idx );
		if ( ( sts & CAN_COM_STS_BIT_ON ) == 0) {   // Ch通信可=不可
			return CAN_RTN_TX_ERROR ;
		}

		if ( ( sts & CAN_BUSOFF_STS_BIT_ON ) != 0) {  // Ch BUS-OFF
			return CAN_RTN_TX_ERROR ;
		}

		if ( ( sts & CAN_TRM_STS_BIT_ON ) != 0) {  	// Ch送信STATUS=送信中
			return CAN_RTN_TX_ERROR ;
		}
	}


送信完了割込みは、エラー割込みや送信前のSFRチェックを行えば特に不要です。割込が多発すると、組込みでは貴重な処理能力を食います。今のところは余裕があるため検出しておきました。弊方での実装例は以下のとおりです。実装先は自動コード生成された r_smc_intprg. c です。

/* CAN0 TRANSMIT INTERRUPT */
#if defined (__CCRH__)
#pragma interrupt IntCAN0Tx(enable=false, channel=26, fpu=true, callt=false)
#elif defined (__ghs__)
#pragma ghs interrupt
#elif defined (__ICCRH850__)
#pragma type_attribute=__interrupt
#else
#error Unknown Compiler
#endif
void IntCAN0Tx(void)
{
/* Start user code for IntCAN0Tx. Do not edit comment generated here */
	R_CAN_DispatchEevent( 0 /*unit*/, 0 /* ch.*/, CAN_EVENT_SEND_COMPLATE );
/* End user code. Do not edit comment generated here */
}

弊方では上記の R_CAN_DispatchEevent の中で、登録ずみcallbackを呼んでいます。例がなくとも想像がつくでしょう。r_rh850_can_cfg.c の設定も少し変更します。以下の 0xFFFFU の部分、送信Buffer の32個に対して1bitづつ有効無効を指定します。取急ぎ全部有効にしておきます。

const can_ch_cfg_t  g_can_ch_cfg[ USED_UNIT_NUM ][ MAX_CH_NUM_U0 ] = {
// ========================== U n i t 0 設 定 ==========================
{
	// ------------------------ C h 0 設 定 ---------------------------
    {
 ・・・中略・・・   
        /* ---- Tx/Rx FIFO buffer ---- */
        0x00000000UL,
     	  0x00000000UL,
        0x00000000UL,
        /* ---- Tx queue ---- */
        0x00000000UL,
        /* ---- 送信Buffer割込許可 RCFDCnCFDTMIECm ---- */
        0xFFFFU		// LSBより 1bit 1Buffer で割当て
    }

割込みが発生しない、割込みが発生後、RESETする場合は、割込み設定が正しくできていない可能性が高いです。前記事をよく確認します。

以上で送信まで試せました。受信編へ続きます。


SFRは多すぎてウオッチするのに時間がかかります。CS+ にもあるかもしりませんが、e2Studioでとても役に立った機能を記録しておきます。

① 選択されたレジスターを使うと、確認したいSFR値だけをまとめておける。

② 上記①の抽出のため、SFR一覧の目視検索に時間がかがる。SFRiodefine.hの定義名なので、マニュアル記載名が検索キーにならないところ、アドレスでも検索できる。

RH850F1KHで自動生成コードをベースでCANドライバーを作る1

前記事では、北斗電子さんHSBRH850F1KH176をターゲットにRH850自動コード生成を行いました。しかしCANドライバは自動コード生成の対象になっていません。そこで自動コード生成とHSBRH850F1KH176 に合わせたCANドライバプログラムを用意することにしました。その覚え書きです。


CANドライバ部は、RH850は設定項目も多く、RH850のCAN機能のアプリケーションノートも無いようです。一からは大変そうなのでサンプルコードを探します。現在、ルネサスから提供されているのは、RH850/U2A 用だけでした。同サンプルコードは、製品コンパイラやマイコン購入者でなくても、ルネサスアカウントを持っていればダウンロードできました。

取り急ぎ RH850F1KHの設定でbuildしてみると、ほぼほぼ通ってしまいます。それはRH850/U2A 専用にSFRを定義が作成しれていて、RH850F1KHiodefine.h は参照していないからです。SFRアドレスもCAN構成も大分違います。RH850F1KH用に移植が必要です。


RH850 CAN機能はこりまでと異なる用語等があります。実用ベースでの見たところ以下のように理解しました。

用語・機能解釈
グローバルCAN「グローバル=世界」 ではないです。RH850のみでのCAN2.0、CAN-FD、複数のCAN UNITを管理するための機構です。
クラシカルCANCAN2.0B のこと。
CAN UNIT所謂CAN コントローラ、この配下に複数のCANチャンネルが連なります。
SFR添え字UINT番号、CH番号等の略記号。マニュアルの表 24.9 添字 に説明あり。
受信ルール従来のCAN Message Box のCAN IDマスクと同意。
送信Buffer従来のCAN Message Box の送信専用版。
受信Buffer従来のCAN Message Box の受信専用版。
データBit Rate少なくとも CAN2.0B では通常Bit Rateと同じ。
FIFO Buffer従来のCAN Message Boxとは別の先入れ先出し方式のMessage Boxの模様。未だ動作未確認です。
割り込みベクタ方式一般的な「テーブル参照方式」と、「優先度に基づいた直接分岐方式」があります。

U2A用サンプルコードのSFR定義: r_rh850_can_sfr.h を変更していきます。ルネサスのマニュアルには、UNIT番号、Channel番号、Buffer番号などぱ可変要素としてSFR名が記載されています。例えば、RCFDCnCFDCmDCFGnはUNIT、mはChannelを示します。実名は RCFDC0CFDC0~7DCFG、iodefine.h はでは RCFDC0.CFDC0~7DCFG となります。よってマニュアルに合わせたSFR名でコードを書いた方が検索性に優れます。 U2A用サンプルコードはそのようになっていますがF1KHと命名が違うため合わせていきます。

  • RSCFDnXXX は、 RCFDCnXXX に一括置換。

これでマニュアルとSFRの対比がつかめるようになります。

U2A用サンプルコードのSFR定義: r_rh850_can_sfr.h では、SFRアドレスは CAN UNIT 毎のベースアドレスからの計算式になっています。そこでまず r_rh850_can_cfg.h にて CAN UNIT のベースアドレスを変更します。U2A用は CAN UNIT は一つと決め打ちです。F1KHの最多pin種では2つのため、ベースアドレスはグローバル変数とし逐次切替式としました。

uint32_t	CAN_START_ADDR;
#define R_CAN_SelectUnit( ch ) 	( CAN_START_ADDR = CAN_START_ADDR [ ch ] )
const uint32_t  CAN_UINT_ADDR[2] = { 0xFFD00000UL /* UNIT 0 */, 0xFFD20000UL /* UNIT 1 */};

あとは SFR名 で マニュアルを検索し、アドレスを変更していきます。アドレスはGlobal系の数個以外は全部違います。50個近くあるので大変です。ついでに日本語名もコメント付与します。計算式のオフセットやCH毎増分など違う場合もあるので修正します。以下 r_rh850_can_cfg.hの一例です。

#define RCFDCnCFDTMCp(p) CAN_REG8 (0x0250 + (p)) // 送信バッファ制御(p)
・・・中略・・・
#define RCFDCnCFDCFCCk(k) CAN_REG32(0x0118 + (0x04 * (k))) // 送受信FIFOバッファ構成/制御(k)
#define RCFDCnCFDCFSTSk(k) CAN_REG32(0x0178 + (0x04 * (k)))	// 送受信FIFOバッファステース(x)

U2AにしかないSFRの削除、F1KHしかないSFRの追加をします。こちらはマニュアルと照らし合わせていくしかありません。手間がかかります。以下 r_rh850_can_sfr.h の一例です。

#define RCFDCnCFDGTINTSTS0  CAN_REG32(0x0610)	// Global TX割り込みステータス0 
#define RCFDCnCFDGTINTSTS1  CAN_REG32(0x0614)	// Global TX割り込みステータス1 ☆
#define RCFDCnCFDGFDCFG     CAN_REG32(0x0624)		// Global FDコンフィグレーション ☆

U2AF1KHで、同じSFRでBit構成が異なるのものがあります。こちらはマニュアルと照らしあわせていくしかありません。弊方ではコメントを付与ついでに調べていきます。幸い数はすくないです。決定的に変更しないとまずいのはBaudrate( RCFDCnCFDCmNCFG, RCFDCnCFDCmDCFG )ですまさかと思い弊方では直ぐに気付けませんでした。トラップです。以下 r_rh850_can_sfr.h の一例です。

#define CAN_DTSEG2_BIT_POS              20U	// Data BitRate Timeセグメント2 (3bit)
#define CAN_DTSEG1_BIT_POS              16U	// Data BitRate Timeセグメント1 (4bit)

U2A用では、CAN構成は r_rh850_can_cfg.[ch] に記述されています。F1KHに構成が異なるため変更が必要です。弊方では CAN UNIT 毎に定義できるようにしています。

#define MAX_CH_NUM_U0					8
#define MAX_CH_NUM_U1					4	// 324pinの場合のみ
#define MAX_CH_NUM(unit)      ( unit == 0 ? MAX_CH_NUM_U0 : MAX_CH_NUM_U1 )
#define USED_UNIT_NUM         1	// 324pinは2
#define MAX_TX_BUF_OF_CH			32	// CH毎の送信Buffer数

送信バッファ数はF1KHが多いので追加します。こちらは r_rh850_can_drv.h。

#define CAN_TXBUF16         16U
#define CAN_TXBUF17         17U
・・・中略・・・
#define CAN_TXBUF31         31U
#define CAN_MAX_TXBUF_NUM   32U

ドライバプログラムで取り扱う構造体もF1KHでは少し違います。CAN Frame と CAN Channel 定義 を修正します。以下CAN Frameの例です。

typedef struct {
・・・中略・・・
	uint32_t TS :16;   /* 受信時刻                           */
	uint32_t RESERVE:12;  /* 空き                            */
	uint32_t DLC :4;	/* DLC(データ部長)                   */
	uint32_t TMESI:1;	/* CAN-FD 0:ERRアクティブNode 1:ERRパッシブNode */
	uint32_t TMBRS:1;	/* CAN-FD DATA領域Bitrate 0:変わらない 1:変わる */
	uint32_t TMFDF:1;	/* CAN-FD 0:CAN2.0 1:CAN-FD */
	uint32_t RESERVE2:13;	/* FD Status(TMESI,TMESI           */
	uint32_t LBL:16;	/* 受信バッファラベル                  */
・・・中略・・・
} can_frame_t;


自動コード生成部を使う部分、セルフテスト部は特に不要です。以下.c は、Build対象外にします。

  • r_rh850_can_int.c
  • r_rh850_can_io.c
  • r_rh850_can_drv2.c

r_rh850_can_drv.c が CANドライバAPI 部です。コメントは少な目で英語なので、内容を確認しながらコメントを追記していきます。全APIで行うとタイヘンなので取り急ぎ使いそうなもののみです。併せてCAN UNIT番号を指定可能にしておきます。以下一部例です。

/******************************************************************************
 * Function Name: R_Can_Init
 * Description  : CAN UNIT毎に初期化を行う。
 *                - CAN用RAMクリア
 *                - Gobal STOPモード解除を待つ。
 *                - CAN2.0 と FD切替え
 *                - ch毎のBaudrate設定
 *                - 受信Ruleの設定
 *                - 受信Bufferの設定
 *                各設定は、r_rh850_can_cfg.c で行う。
・・・中略・・・
 *	              CAN_RTN_ARG_ERROR -
 *	                  パラメータエラー
 ******************************************************************************/
Can_RtnType R_CAN_Init(
	const uint8_t unitNum,	// i : CAN Unit
	const uint8_t chNum,		// i : 使用CAN ch数
	const BOOL useCanFd		  // i : CAN FD使用
) {

修正内容の整合性があっているか、仮Buildします。自己あやまり以外で引っかかる部分が少しあります。RCFDCnCFDTMIECm のポインタ型はU2A用では16bitでしたがF1KHでは32bitにする必要があります。

・・・中略・・・
volatile uint32_t *p_TMIEC;
・・・中略・・・

オリジナルのままでは使いにくそうなので多少機能追加しています。 Callback 機構とそのための割込みに仕込む EVEVT Dispacher です。

/******************************************************************************
 * Function Name: R_CAN_DispatchEevent
 * Description  : CAN ENEVTを処理する
 *                割込ハンドラから呼ばれます
 *                割込ペリフェラルとのI/F部です。
 * Remark:
 * - 現在は、送信Bufferによる送信のみサポート。
 * - RH850では、受信Bufferの割込みはない。
 ******************************************************************************/
void R_CAN_DispatchEevent(
	const uint8_t		unitNum, // i : CAN Unit
	can_ch_t			  ch_idx,	 // i : CAN Ch番号
	const uint8_t		event		 // i : ENEVT No.
) {
・・・中略・・・
/******************************************************************************
 * Function Name: R_CAN_SetRecvCallback
 * Description  : CAN受信Callbckを設定する。
 ******************************************************************************/
void R_CAN_SetRecvCallback(
	const uint8_t		  unitNum,	// i : CAN Unit
	can_ch_t			    ch_idx,		// i : CAN Ch番号
	CAN_RECV_CALLBAK	func		  // i : 受信Callbak
) {
・・・中略・・・
/******************************************************************************
 * Function Name: R_CAN_SetSendCallback
 * Description  : CAN送信Callbckを設定する。
 ******************************************************************************/
void R_CAN_SetSendCallback(
	const uint8_t		 unitNum,	// i : CAN Unit
	can_ch_t			    ch_idx,	// i : CAN Ch番号
	CAN_SEND_CALLBAK	func		// i : 受信Callbak
) {
・・・中略・・・
/******************************************************************************
 * Function Name: R_CAN_SetErrCallback
 * Description  : CANエラーCallbckを設定する。
 ******************************************************************************/
void R_CAN_SetErrCallback(
	const uint8_t		unitNum,	// i : CAN Unit
	can_ch_t			  ch_idx,		// i : CAN Ch番号
	CAN_ERR_CALLBAK	func		  // i : 受信Callbak
) {


自動コード生成でのmainモジュール: r_cg_main.c の実装は以下のような感じです。

・・・中略・・・
/* Start user code for include. Do not edit comment generated here */
#include "r_rh850_can_sfr.h"
#include "r_rh850_can_drv.h"
/* End user code. Do not edit comment generated here */
・・・中略・・・

void main(void)
{
・・・中略・・・
    r_main_userinit();
    r_main_startCan();

    while ( 1U ) {
・・・中略・・・
}

void r_main_startCan(void)
{
	// CAN Controller 初期化
	if ( R_CAN_Init( 0/*UNIT*/, 2/*CH数*/, FALSE/*CANFD*/ ) != CAN_RTN_OK ) {
		return;
	}

	// Ch0 Callbak設定 
	R_CAN_SetErrCallback ( 0/*UNIT*/, 0/*ch.*/, r_main_errCan0  );
	R_CAN_SetRecvCallback( 0/*UNIT*/, 0/*ch.*/, r_main_recvCan0 );
	R_CAN_SetSendCallback( 0/*UNIT*/, 0/*ch.*/, r_main_sendCan0 );

	// Ch1 Callbak設定
	R_CAN_SetErrCallback ( 0/*UNIT*/, 1/*ch.*/, r_main_errCan1  );
	R_CAN_SetRecvCallback( 0/*UNIT*/, 1/*ch.*/, r_main_recvCan1 );
	R_CAN_SetSendCallback( 0/*UNIT*/, 1/*ch.*/, r_main_sendCan1 );

	// Global CAN開始
	if ( R_CAN_GlobalStart( 0/*UNIT*/ ) != CAN_RTN_OK ) {
		return;
	}

	// CAN 0ch 開始
	if ( R_CAN_ChStart( 0/*UNIT*/, 0 /* Ch. */ ) != CAN_RTN_OK ) {
		return;
	}

	// CAN 1ch 開始
	if ( R_CAN_ChStart( 0/*UNIT*/, 1 /* Ch. */ ) != CAN_RTN_OK ) {
		return;
	}

CAN機能と割込は場合、HSBRH850F1KH176 の回路実装から各種割当ては以下のようになります。なお受信Buffer による受信割込みはRH850は無いです。送受信FIFOはFIFO Buffer専用の割込みのようです。

Chanel機能ポート名ポート番号送信完割込番号送受信FIFO割込番号エラー割込番号
0受信CAN0RXP10_02524
0送信CAN0TXP10_1262524
1受信CAN1RXP0_2114113
1送信CAN1TXP0_3115114113

CANペリフェラルの定義は、e2stdioの自動生成で以下のように行います。

上記の設定で、対応するポートの入出力の設定はされるので、以下2つの個別の設定はしないです。

CANペリフェラルの定義は、Pin.cR_Pins_Create に生成されます。しかし生成されるだけで、 Config_PORT.c などからcallされていません。呼出しコードは自分で書く必要がありました。弊方では直ぐ気付けずトラップでした。弊方では、Config_PORT_user.c から以下のように呼出追加しました。

void R_Config_PORT_Create_UserInit(void)
{
    /* Start user code for user init. Do not edit comment generated here */
	  R_Pins_Create();
    /* End user code. Do not edit comment generated here */
}

割込みの設定は一旦以下ようにします。これでハンドラのベクタテーブルへの定義とスケルトン、割込み有効無効のAPIが生成されます。

しかしCAN割込みの場合、割込み優先度割り込みベクタ方式 の設定コードは自動生成されませんでした。タイマ等では自動生成されるので、ここはトラップです。デフォルトは割込み優先度です。そのまま動かすと優先度15割込み未定義で無限loopしました。boot.asmを見ると自動生成デフォルト状態では _Dummy_EI で無限loopになってます。この方式は使わない方が無難なようです。

割込み設定に関するコード例は以下のとおりです。r_main_startCan() の各Ch.初期化後に追記しましたた。

	/* CH0 割込み方式とLEVEL設定 */
    INTC1.ICRCAN0ERR.BIT.TBRCAN0ERR = _INT_TABLE_VECTOR;
    INTC1.ICRCAN0REC.BIT.TBRCAN0REC = _INT_TABLE_VECTOR;
    INTC1.ICRCAN0TRX.BIT.TBRCAN0TRX = _INT_TABLE_VECTOR;
    INTC1.ICRCAN0ERR.UINT16 &= _INT_PRIORITY_LEVEL4;
    INTC1.ICRCAN0REC.UINT16 &= _INT_PRIORITY_LEVEL4;
    INTC1.ICRCAN0TRX.UINT16 &= _INT_PRIORITY_LEVEL4;

	/* CH1 割込み方式とLEVEL設定 */
    INTC2.ICRCAN1ERR.BIT.TBRCAN1ERR = _INT_TABLE_VECTOR;
    INTC2.ICRCAN1REC.BIT.TBRCAN1REC = _INT_TABLE_VECTOR;
    INTC2.ICRCAN1TRX.BIT.TBRCAN1TRX = _INT_TABLE_VECTOR;
    INTC2.ICRCAN1ERR.UINT16 &= _INT_PRIORITY_LEVEL4;
    INTC2.ICRCAN1REC.UINT16 &= _INT_PRIORITY_LEVEL4;
    INTC2.ICRCAN1TRX.UINT16 &= _INT_PRIORITY_LEVEL4;

    // CH0 割込み有効化
	IntCAN0Error_enable_interrupt( );
	IntCAN0TxRxFIFORxCmp_enable_interrupt( );
 	IntCAN0Tx_enable_interrupt( );

    // CH1 割込み有効化
	IntCAN1Error_enable_interrupt( );
	IntCAN1TxRxFIFORxCmp_enable_interrupt( );
 	IntCAN1Tx_enable_interrupt( );


以上おおざっぱなところ、初期化は通過し、送受信スタンパイまで行き着きました。しかし試行錯誤や細かい部分でハードルもあり、ここまで延べて2weekくらいは要したかと思います。

送信編につづきます。

Xperia E1 Dual D2105 をAndroid 6または7.1.2相当にUpdateしてみる1

音楽再生専用にほどよい4inchディスプレイのXperia E1。Walkmanボタンで画面さわらずとも再生とポーズができます。FMラジオ、大型スピーカ、SIMスロット2。自動車整備中でイヤフォンが使えないとき、ツナギのぽっけに入れて音楽再生にちょうど良いです。

標準OSはAndroid4.1.2。色々なOSが出ています。Walkmanボタンが使えるカスタムOSを模索中です。試したOSと結果のメモです。


①Bootloader unlock 解除コードの入手 → ②Bootloader unlock → ③customリカバリ書込み → ④OS 書込みと他の基本手順はXperiaと同様です。 ③の内容が少し違いました。recovery領域にcustomリカバリ書込みはエラーとなり、boot領域に書込むと上手く起動します。

そうすると常時TWRPが起動するようになってしまいますが、OSを書くと上手くなくなってしまうので問題になかったです。なお端末のコードネームは、最初 falconss だったが途中から Shuangになったので、その両方でキーワードで情報を探す必要があるようです。


  • Andrid6相当
  • lineage14.1にくらべると動作はかなり軽い。(Open Gapp無し時)
  • Open Gappを入れても遅いが動く。Googleログインまでかなり時間要す。
  • wmaファイルは音楽再生可能。(弊方wma派につき)
  • walkmanボタンは効かない。カメラボタン扱いとなっている。
  • カメラ起動で「問題が発生しました」となる。open-camera-1-53-1.apkでも同様。
  • 吊るしラジオアプリは起動するが100Hzから変更できない。
  • ブラウザは起動するが、OS古くてgoogleサーバ側で拒否され閲覧不能。
  • インストール後、カスタムリカバリは残る。

  • Andrid7.1.2相当
  • lineage13.0にくらべると動作は重いが使えなくはない。(Open Gapp無し時)
  • Open Gappを入れるととてつもなく遅く、リセットを繰り返し起動が困難。しつこく繰返ば起動する。
  • wmaファイルは音楽再生不可。
  • walkmanボタンを押すとカメラが起動される。設定->ボタン->カメラボタンは無効にしていても起動してしまう。
  • カメラは起動動作可能。
  • 吊るしラジオアプリは起動するが、周波数表示されず何もできない。
  • ブラウザは起動し、閲覧可能。
  • インストール後、カスタムリカバリは残らない。

  • Andrid7.1.2相当
  • 初回Bootに時間かかる。
  • 大蛇の起動画面が目を引く。
  • lineage14.1にくらべると動作はやや軽い。(Open Gapp無し時)
  • Open Gappを入れると遅く、何とか起動する。Googleログインは失敗した。
  • wmaファイルは音楽再生不可。(何かの拍子に再生されてことが一度あった)
  • walkmanボタンは効かない。カメラボタン扱いとなっている。
  • カメラは起動しない
  • 吊るしラジオアプリは起動するが、周波数表示されず何もできない。E1オリジナルのラジオアプリは起動失敗する。
  • ブラウザは起動し、閲覧可能。
  • インストール後、カスタムリカバリは残らない。

  • 試さず。どのみちAndroid5なので。

  • TWRPで解凍エラーが発生し試せず。

各OSも一長一短があるようです。結果を下表にまとめます。

OS重さGapp相性walkman
ボタン
ラジオカメラWEB
閲覧
lineage-13.0××××××
lineage-14.1××××
Viper〇△×××××

本端末では、Walkmanボタン が重要です。各種バージョンを試してみました。以下その結果です。なお、wmaファイルの再生可否はOSの実験結果から、アプリ依存ではなくOS依存の模様です。

バージョンインストールWalkmanボタン
8.4.1.5 (E1オリジナル収録Ver.)××
8.4.1.4×
7.15.A.0×
8.1.A.0.5×
8.4.A.3.5××
8.5.A.3.3××

E1オリジナル 8.4.1.5はオリジナルROM: Sony_Xperia_E1_Dual_D2105_20.1.B.0.64_RU から取出しものですが解せない結果です。何か深い秘密があるのでしょうか?


冷静さをとり戻すため一旦オリジナルに戻します。VolumeDown押しながらUSBケーブルを差し、Flashモードに遷移させた後、Flashtool で Sony_Xperia_E1_Dual_D2105_20.1.B.0.64_RU を書きます。以下手順です。


以上、悔しい状況です。引き続き調査を継続します。