Windows VS2022 からTestflight をUPLOADする手順【’25.1月編】

前記事からひきつづきWindows Visual Studio 2022 で、TestFlightする手順です。MAC Visual Studio 2019での手順と画面も違うため別途記録しました。

TestFlightのビルド構成にし、Build後、アーカイブを実行。

アーカイブが始まります。UI動作はやや不安定です。画像中に注記しています。

署名をするため配布を開始します。

配布先を選びます。

生成先を選びます。

直ぐに保存先の選択ダイアログがでます。

この後、MAC側でUPLOADしますが、同じFileなのに20回くらいで成功しました。サーバの要因か不調な場合があります。Apple Developer のパスワードを何回も聞かれたり、htmlタグエラーみたいなのが多発します。Transporter も起動しなおすと表示が変わったりメチャクチャです。

なおストアーアップロードはWindows版でも相変わらず失敗します。

TortoiseGit で大きいfileをGit-Hubにpushする

Windows上でGit-Hubに大きいファイルをpushする手順の記事があまり見られなかったので覚書です。

300MBのzipをGit-Hubにpushする数分も待たされ、容量うんぬんではなく、error: faild to push some refs to とエラーがでます。

他WEB記事をみると Git LFS というモードがあるようです。なるほど。どうしたら有効になるのでしょう? git lfs というオプションがあるようで、コマンドプロンプトからたたいてみます。gitのコマンドは、TortoiseGit と一緒に入っているみたいです。

コマンドは適当な場所でたたくと、リポジトリ外的にエラーがでるので、リポジトリ直下でたたいてみます。

このあとTortoiseGit のメニューに変化がみられました。

対象のzipが変更あり扱いになりました。よくわかりませんがコミットします。

再pushすると、大きいファイルの認識はされるものの( これはTortoiseGit というよりGit本体の反応 ) エラーは変わりませんでした。

他のコマンドためします。以下手順でpushできました。push自体は TortoiseGit からも同じなので出来るはずです。

リポジトリ直下に .gitattributes という設定ファイルができているので、これがポイントなのでしょうか?

*.zip filter=lfs diff=lfs merge=lfs -text
*.txt filter=lfs diff=lfs merge=lfs -text

結果は TortoiseGit からは全て直接できないが、コマンドプロンプトから行えばいいようです。

オリジナルCAN Logger を構想する1

構想時のメモです。

ラズパイ や FA用PC と 汎用CANボート の組合せがスピーディですが、

  • 起動に時間がかかる。
  • サイズが大きくなりがち。(二輪にも載せたい)
  • 細かな制御ができない。
  • 予期しない不確定要素がおおい。
  • ノイズや振動は大丈夫か? (二輪にも載せたい)
  • CAN-FDに対応させたい。(開発用途ではCAN-BUS使用率が直ぐいっぱいになってしまう)

よって車載用のCAN付マイコンを使います。

ロガーでもリアルタイム値をリモートで見たいと要素もあります。モバイル端末で中継させ、用途に応じてデータを飛ばします。以下のような構成とします。

モバイル端末に使うには、BTで中継します。

以下ポイントです。

  • BT4は遅いのでBT5.1を使います。Long rangeモードがあり耐ノイズ性を期待します。
  • 車載CANとBTを搭載したマイコンはほぼないので、タスク分割も兼ねて別マイコンとします。
  • ログモードは後でかんがえます。

極力ハードウェア機能で受信させ、フルログモードに備え、処理能力の消費を控えます。CANは2チャンネルを使用。制御用が必要になる可能性もあるため、それら用に受信バッファとルールをRESERVEしておく。

基本はこんな感じで構想中です。

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を入れてみます。うまくいったようです。


ユーザさんから追加情報がありました。 Book Walker というアプリがうまく動作しないとのことです。SC-03G LinageOS10では動作するとのことで、LInageOS20固有の課題なのかもしれません。何分、リアルタイム課金されるアプリは決済関係で要注意かと。。。


以上、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 用と明記しておきます。

修正した MindTheGapps-13.0.0-arm64*.zip は機種依存であるとまずいので、本流にマージせず個別にGit-Hubに公開しました。 ここから MindTheGapps-13.0.0-arm64*.zip を選んで以下のようにDownloadしてください。

これで Googleサービス のインストールできました。次のサービスのセットアップに続きます

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 アプリでの手続き名は以下のとおりです。

以下入力例です。

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

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

申請は受理されるものの以下のような指摘がありました。

この 事業者整理記号 は最もよくわからないところです。2桁の都道府県コード、2桁の市町村コード、カタカナの3桁の事業所記号、5桁の事業所番号の組合せが、帳票によってコロコロかわるような印象です。4桁の数値というと社会保険の支払い通知書の事業所コードというものもあります。それかな??? 何分、記入欄にどの項目がどれか記載されていない、入力桁数の厳格なチェックがされていないので、要注意です。

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の定義名なので、マニュアル記載名が検索キーにならないところ、アドレスでも検索できる。