Windows11 24H2にUPDATEできなくなった件1

弊方の中古購入した富士通ESPRIMO Q556/R にて突然以下のような表示がでるようになりました。

Windows11 22H2 の期限迫っていることは理解しましたが、更新プログラムのチェック を押しても自動アップデートに進みません。別の Windows11のPCは、このようなことは無く、23H2 に勝手に更新されていました。 ナゼでしょう?

一先ずWindows11 22H2 のインストーラをダウンロードして実行してびっくりです。

現状を再確認します。23H2より Core i7-7700T がNGになったのでしょうか?

Windows11のCPU要件を再確認すると、Windows11 当初よりCore i7-7700 は非対応です。はてな?

あっ CPU換装したのを思い起こしました。元々はCorei 3-7100T でした。しかしコレが Windows11 の対象になっているかというと、、、

ネットを調べると、インストーラの CPU型番チェックの.dll を無効にして、インストールする方法があるようですね。業販だったので安心していたのですが、この方法で構築されたPCだったのかもしれません。これは想定外、開発環境も作り込んでいるので困った事態です。同じように困っている方もたくさんいらっしゃるんでしょうね、、、、

とはいうものの弊方も一度試してみます。appraiserrs.dll の中を空にした場合、普通に考えるとダイナミックリンク先のAPIが無いと何もカードしていないとアプリは異常終了します。Windows11のインストーラはdllを明示的ロードしてNGの場合 (LoadLibrary() APIで可能)をして、意図的にCPUチェックをスルーするロジックになっているといえます。 しかし、、、

考察するに、

  • 既にWindows11がインストールされているPCでは「appraiserrs.dll の中を空方式」 は、OS側がCPUチェックするため通用しない

とすると大型アップデート時は、毎回クリーンインストールが必要になりますね。これは大変だ。

RS232C付きの小型PCは貴重です。Win11の対象となっている core i7 8700Core i7-7700T と同じFCLGA1151ソケットと公式サイトにも記載がありますが、よく調べると前者はFCLGA1151-V2と呼ばれソケットは共通ですがピン配置は異なり、動作互換は理論上も物理的にも無いとのことです。ソケットの違いはここにまとめてあるみたいです。助かります。

よく調べると Q556/R の後継Q558/Bcore i 9世代対応、Q558/V core i 8世代対応になっていますね。まさかこれを見逃していたとは考えにくいです。Q558 を検索するとQ556もヒットしやすいですので、Win11だからQ558と勘違いしたのかもしれません。次記事に続きます。

Nordic UART転送速度調査1: nRF52840 と Android端末間編

前回nRF52840 と Android端末間で、Nordic UARTの基本的な送受信を行いました。次にどのくらい実際に通信量を流せるか試します。Bluetooth5での公称通信速度は 2Mbps です。実際にそんなに出るわけありません。昔々、有線TCP/IPでも実効転送速度は一割でシステム設計するよう叩き込まれたものです。

BTマスターハードウェアnRF52840-DK
BTマスターVersion5.4
BTマスターIDESEGGER5.6 (デバッガ有効)
BTスレーブモトローラG32, 2.4Gz x 4 coe
BTスレーブVersion5.2
BTスレーブIDEAndroidSdtio 4.0 (デバッガ有効)
IDE用PC Windows10, Core i7 3.8GHz x 8 coe

通信方向マスタ → スレーブ
通信周期3 sec
1セットの通信量2,000 byte
通信1セットのパケット分割数8回
パケットサイズ244
パケット間隔スレーブ内で BLE_NUS_EVT_TX_RDY:次送信許可 イベント発生後、即時。

シーケンス全体:

パケット間シーケンス:

スレーブ側で以下の計算を行い秒辺りの送信バイト数を画面表示する。

( 通信1セットの終了開始時刻(sec) - 通信1セットの受信開始時刻(sec) ) ÷ 通信1セットの受信Byte数

2MBpsで、1byte=10bit仮定し、200kbyte/秒すると、性能の1%しか達成していない。

少し予想はしていましたが、なぜこのような結果となるのでしょう? 引続き調査をしていきます。

横河オシロスコープDLM2024の導入memo

弊方では簡単な波形確認は、PCオシロ POS-4 を使用していました。しかし高速のシリアル通信やクロックの確認は難しいです。 顧客先でも高性能なオシロをお持ちでない場合もあります。

そこで横河DLM2024を導入にした覚書です。10年前くらいのモデルです。もっと古いDL1740でもフルカラーだし十分ですがフロッピーはつらいです。オプションでロジアナ、オプション無でシリアル通信のByte変換解析(少し怪しい)があります。CAN解析もできるらしいですがオプションが必要かは不明です。

購入はメーカリース会社さんのリースアップ品です。丁寧に使用されていて、近々で校正ずみ、付属品もそろっていて半年保障ありです。中古計測器屋さんやヤフオクでも同じくらいの値段だったのでこの方が効率的かと思います。

ロギングも可能なDL750 + 波形モジュール4ch でも+数万円 でしたので悩みどころでしたが、持ち運びする場合を考慮してコンパクトな方にしました。

まずプローブ未接続で起動してみます。このモデルは初期状態が波形太く光るモードです。(用途は分かりません。後で波形フォーマットを変更します。)

機器スペックを表示してみます。

イーサがあるのでネットワークを設定します。本体でUtility -> NetWork -> TCP/IP から設定します。デフォルトはDHCPなので、OFFして固定IPを設定します。

ping確認します。設定を反映するには本体を再起動が必要です。

続いて波形画像を取り出すため FTP 設定を本体で行います。FTP は FFFTP を使用します。デフォルトで有効になっています。

本体への接続手順は以下のとおりです。本体側デフォルトユーザ設定は anoymous (パスワードは不要) です。

ブラウザからの波形表示もサポートされていましたが、Flash Player で作られており、現在のブラウザでは使用禁止のため以下のようになります。リモート表示のトライはこちらを見てください。

お試しでCAN生波形をみてみます。初期状態だとなぜか波形トレースがかかっており、一旦トレースクリアをします。波形がなまっているので、本体ACQUIREボタン -> メニューRecord Lengthを4ch時の最大1.25Mにします。波形フォーマットも何故か破線設定になっているので、本体DISPLAYボタン -> メニューAccumulateをり OFF します。

以上で、DLM2024 の導入が完了しました。電子コントローラの開発現場でも、トリガーくらいでオシロの機能を使いこなせていない場面もよく見受けられます。そのた機能の使い方もレポートしていきたいと思います。

オシロで計測したいが手持ちオシロが無い、古すぎる、買うほど使用頻度が低い、リースも短期間だと高いなどお困りの方は計測サービスをいたします。詳しくはこちらまでご相談ください

Xperia Z4 TabletでFullバックアップを試す

セットアップ済み端末から、.ftf を再生成できればもしかすると… 気になって試してみたメモです。わかっていたことですが、root化できないとダメみたいです。

以下メニューがそれを示すのでしょうか? “Root access denid(拒否)“となりダメでした。

検索すると “Backup-TA” なるツールが見つかります。2010年代前半と古いものです。SUコマンド がないとダメでした。(しかしよくよくみると当ツールは Flash Tool に含まれているようです)

root化で検索すると “EASY Rooting Toolkit” が見つかります。これはソースコードだけでした。Android StduioNDK を追加し、make をかけます。コードが古く、#include漏れ、変数型不足、prototype宣言不足だらけでかなり修正しましたが Build できました。adb /data/local/tmp に転送し、実行しても無反応でした。(しかしよくよくみると当ツールは Flash Tool に含まれているようです)

これも実行ファイル、スクリプト、Superuser.apk 等を、adb /data/local/tmp に転送し実行するものでした。BusyBox(バイナリ結合コマンド)も転送しているので、bootバイナリにroot権限を埋込しそうです。しかし動作しますが成果は無しです。

あと実行するとウイルス検知されます。ヤバいやつです。


バックアップから .ftf 生成するには、root化が肝のようです。XDAで最新の手法を見ると、

  • boot loader をunlock
  • .ftf から .sin を展開し、boot.img を取出し。
  • Andeoid 上で、magisk のapkをインストール後、boot.img にroot権限を付与。
  • fastboot flash boot で、boot.img を書き込み。

実施するには実験用の SGP771 か SGP712 が必要ですね。

Javaと組込み機器Cで通信するときの留意事項

AndroidアプリなどJava言語と、組込み機器C言語で通信させるとき、せちがらい制約があります。その制約と対応方法の覚書です。

古くはVB6(VBA)C#Switf には構造体はありますが Java だけなんで?て感じです。Java側でByte配列へ編集もしくは分解するしかないようです。以下事例です。

組込み側

///  BTスレーブ要求フレーム ///
typedef struct _ST_SLAVE_REQ {
  uint8_t		head[ 4 ];	// HERAER兼パケット識別
 	uint16_t	len;		    // パケット長
 	uint16_t	req;		    // 要求コード
  uint8_t		foot[ 4 ];	// FOOTER
 	uint16_t	csum;		    // CHECKUSUM
} ST_SLAVE_REQ;
// Memo: 実際にはCPUアーキテクチャによってパウンダリ調整なし、2byte調整、4byte調整があるのでよく確認します。

Java側 :

///  BTスレーブ要求フレーム ///
short   frmLen = 14;
byte[]  buff = new byte[frmLen];

copyBytes(buff, 0, appCom.ID_SLAVE, 4 );          // 4: HERAER兼パケット識別
copyBin16(buff, 4, frmLen );            	        // 2: パケット長
copyBin16(buff, 6, appCom.REQ_START_MONITER );  	// 2: 要求コード
copyBytes(buff, 8, appCom.ID_TAIL, 4 );           // 4: HERAER兼パケット識別
short   csum = checksum(buff, frmLen - 2);        // Checksum
copyBin16(buff, 12, csum );            	           // 2: Checksum

Bundle arg = new Bundle();
arg.putByteArray( "BINARY",  buff );     // BIN DATA

WriteValueBLE( mServiceCANonNUS, mMessengerCANonNUS, arg );

byteコピー などはメソッドを追加します。web検索すると Unsafe.copyMemory なるものがでてきますが作った方が早い!

    ///////////////////////////////////////////////////
    // Byteコピー
    ///////////////////////////////////////////////////
    public boolean copyBytes(
        byte[]  to,
        int     offset,
        byte[]  from,
        int     len
    ) {
        if ( from.length < len ) {  // ちゃんと実体sizeをちぇっくしましょう。
            return false;
        }

        if ( to.length - offset < len ) {
            return false;
        }

        for( int i = 0; i < len; i ++ ) {
            to[ i + offset ] =  from[ i ];
        }
        return true;
    }

unit16変換関数を作ります。バイトオーダーは組込み機器側のCPUアーキテクチャに合せます。

///////////////////////////////////////////////////
// int16コピー
///////////////////////////////////////////////////
public boolean copyBin16(
    byte[]  to,
    int     offset,
    short   from
) {
    if ( to.length - offset < 2) {
        return false;
    }

    // ARMはリトルエンディアン
    to[ 0 + offset ] =  (byte)( from % 256 );
    to[ 1 + offset ] =  (byte)( from / 256 );
    return true;
 }


似たような言語では、C#はあり、Switf は無いようです。 (アプリだけ作ってる方々は、組込み機器ではsignedを基本使わないこと自体あまり知られていないのかもしれませんが…)

以下の場合、Java側で正しい値になりません。以下例では、frm.len は 4002( 0x9C42) となり、Java側で 0x9C がUnder Flow し -100 となります。そのまま extractBin16 で加算されると66 (0x42) + -100 * 256 = -25,534 と全く異なる値になってしまいます。

組込み側:

///  BTスレーブ応答フレーム ///
typedef struct _ST_SLAVE_RESP {
		uint16_t	len;		         // パケット長 6
    uint8_t    data[40000];    // CAN DATA部
} ST_SLAVE_RESP;

		:
	前略
		:
ST_SLAVE_RESP frm;

frm.len = sizeof(ST_SLAVE_RESP) - sizeof( uint16_t );	// パケット長 ,checksum分引く = 40,002(0x9C42)
		:
	中略
		:
 err_code = ble_nus_data_send( /*in*/    &m_nus,
			 						  /*in*/     &frm,
			  					  /*in-out*/ &sendLen,
									  /*in*/     m_conn_handle );

Java側:

/// BLEデータの取出し
byte alldata[] = characteristic.getValue();

// パケット長 6
short len = extractBin16(alldata, 4);
		:
	中略
		:

///////////////////////////////////////////////////
// int16取り出し
///////////////////////////////////////////////////
public short extractBin16(
    byte[]  from,
    int     offset
) {
    short   val  = 0;
    short    tmp;

    // QualcommはARM系なのでリトルエンディアン、Nordic もARM系なのでリトルエンディアン
    val  +=  from[ 0 + offset ];            // 0x42 → 10進 66
    val  +=  ( from[ 1 + offset ] * 256 );  // 0x9C → 10進 -100

    return val;
}

修正例は以下のとおりです。これは VB6(VBA) も同様で昔はよく引っ掛かっていたものです。

///////////////////////////////////////////////////
// int16取り出し
///////////////////////////////////////////////////
public short extractBin16(
    byte[]  from,
    int     offset
) {
    short   val  = 0;
    short    tmp;

    // ARMはリトルエンディアン
    tmp  =  from[ 0 + offset ];
    if ( tmp < 0 ) {    // Javaはunsignedがないため、1の補数で補完する
        tmp = (short)(255 + tmp + 1);
    }
    val  +=  tmp;

    tmp  =  from[ 1 + offset ];
    if ( tmp < 0 ) {    // Javaはunsignedがないため、1の補数で補完する
        tmp = (short)(255 + tmp + 1);
    }
    val  +=  ( tmp * 256 );

    return val;
}

チエックサム計算も同様にくるってしまいます。尚、shortがオーバーフローしたとき、プログラム異常になってしまうのかわかりませんが対策しておきます。

組込み側:

uint16_t CalcCheckSum(
 	 uint8_t *buf, 	// i : 対象Buffer
	 int16_t len	  // i : 対象Buffer長。
) {
	uint16_t i;
	uint16_t sum;

	sum = 0;
	for( i = 0; i < len; i ++ ) {
		sum += buf[ i ];
	}
	return	sum;
}

Java側:

 ///////////////////////////////////////////////////
 // checksum
 ///////////////////////////////////////////////////
 public short checksum(
     byte[]  to,
     int     len
 ) {
     long    sum = 0;
     short    tmp;

     for( int i = 0; i < len; i ++ ) {
         tmp = (short)to[ i ] ;
         if ( tmp < 0 ) {    // Javaはunsignedがないため補完する
             tmp = (short)(255 + tmp + 1);
         }
         sum += tmp ;
     }

     return((short)sum);
 }


組込みC側と送受信する文字列は、Stringでは渡せないです。copyValueOf(char[] data)、valueOf(char[] data) があるようですがコードもかさむんで、Byte[] でよいでしょう。

    final byte[]  ID_MASTER = {0x42,0x54,0x30,0x32};   // "BT02" MASTERから
    final byte[]  ID_TAIL   = {0x42,0x45,0x4E,0x44};   // "BEND"	 終了