AN889の日記

組込みエンジニアのブログ

【iPhone】USBメモリーのファイルシステム

iPhoneで写真や動画をたくさん撮って、ストレージの空き容量が少なくなって困ってる方は多数いらっしゃると思います。
そんなときUSBメモリーへ移す方法があります。

www.buffalo.jp

 

iPhoneUSBメモリーの接続にはアダプター(コネクター変換ケーブル)が必要です。
どららも私の環境で動作確認済です。

 

USBメモリーへ移すまたはコピーする際、サイズの大きい動画は注意が必要です。
USBメモリーの購入時のファイルシステムはほとんどFATです。FATはその仕組み上、1ファイルの最大サイズは約4GBです。
なので、このサイズを超える動画をコピーしようとすると、「操作を完了できませんでした」というエラーが表示されコピーできません。

この対処として、USBメモリーのファイルシステムを変更する必要があります。
それにはPCが必要です。Windows機ならexFATでフォーマットします。

 

iPhoneが対応しているファイルシステムはAPFS、APFS(暗号化)、macOS拡張(HFS+)、exFAT(FAT64)、FAT32、またはFATです。

support.apple.com

 

動画サイズの確認方法ですが、写真アプリで対象の動画を選択して画面下の情報ボタン(iマーク)をタップすれば表示されます。

support.apple.com

 

【Linux】NXP QorIQプロセッサ向けLinuxでのSGMIIリンク設定

NXPのQorIQシリーズT1014/T1024プロセッサーにてMACイーサネットPHYをSGMII接続する際、プロセッサーレジスター SGMII IF Mode (MDIO_SGMII_IF_MODE) でのリンク(MAC-PHY間のリンクです。PHYと対向機(例えばイーサネットスイッチやPC)とのリンクではありません)設定が必要な場合があります。
MACのリンク設定とPHYのリンク(PCS(Physical Coding Sublayer)リンク)設定が同じ(例えばどちらもオートネゴシエーション有効)ならいいのですが、違う場合リンクされません。

PHYのリンク設定ですが、例えばMICROCHIP社製VSC8562
https://www.microchip.com/en-us/product/vsc8562/
の場合、MAC SerDes PCS Controlレジスター(アドレス 16E3)のビット7 MAC SerDes autonegotiation enable でします(このビットはスティッキー(sticky bit)なので、ソフトリセットしても値が保持されます)。

プロセッサーのMDIO_SGMII_IF_MODEレジスター設定はLinux
GitHub - nxp-qoriq/linux at LSDK-19.09-update-311219-V4.14
だとドライバーdrivers/net/ethernet/freescale/fman/fman_memac.csetup_sgmii_internal_phy()でします。
バイスツリーで実PHYを定義している場合、522行目でオートネゴシエーション有効に設定されます。
PHYのPCSリンクをオートネゴシエーション無効にしても、MDIO_SGMII_IF_MODEでオートネゴ有効になるのでリンク確立しません。 そこで、MDIO_SGMII_IF_MODEのリンク設定を選択できるよう、デバイスツリーにプロパティーを新たに設け、ドライバーを改造しました。

  • バイスツリーのプロパティ
    • プロパティ名:fsl,pcs-link-speed
    • 値:100=100Mbps全二重、1000=1000Mbps全二重
    • プロパティ未定義時はオートネゴシエーション有効
    • 定義例
&enet0 {
    fsl,pcs-link-speed = <100>; /* 100M Full */
};

または

ethernet@e0000 {
    cell-index = <0>;
    compatible = "fsl,fman-memac";
    reg = <0xe0000 0x1000>;
    fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>;
    ptp-timer = <&ptp_timer0>;
    pcsphy-handle = <&pcsphy0>;
    fsl,pcs-link-speed = <100>; /* 100M Full */
};
  • ドライバー改造
diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
index a847b9c..2eb9942 100644
--- a/drivers/net/ethernet/freescale/fman/mac.c
+++ b/drivers/net/ethernet/freescale/fman/mac.c
@@ -836,6 +836,19 @@ static int mac_probe(struct platform_device *_of_dev)
        priv->fixed_link->asym_pause = phy->asym_pause;
 
        put_device(&phy->mdio.dev);
+   } else if (mac_dev->phy_node && !of_property_read_u32(mac_node, "fsl,pcs-link-speed", &val)) {
+       priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
+                      GFP_KERNEL);
+       if (!priv->fixed_link) {
+           err = -ENOMEM;
+           goto _return_of_get_parent;
+       }
+
+       priv->fixed_link->link = 1;
+       priv->fixed_link->speed = (int)val;
+       priv->fixed_link->duplex = DUPLEX_FULL;
+       priv->fixed_link->pause = 0;
+       priv->fixed_link->asym_pause = 0;
    }
 
    err = mac_dev->init(mac_dev);

【Yocto】Intel 64ビットプロセッサー向けLinuxビルド(meta-intel)

はじめに

Intel 64ビットプロセッサー(x64)向けLinuxをYoctoでビルドする方法です。 meta-intel を使います。

環境構築

$ mkdir path/to/prj
$ mkdir sources
$ cd sources
$ git clone git://git.yoctoproject.org/poky -b kirkstone
$ git clone git://git.openembedded.org/meta-openembedded -b kirkstone
$ git clone git://git.yoctoproject.org/meta-intel -b kirkstone
$ cd ..
$ . ./sources/poky/oe-init-build-env build

設定

build/conf/local.conf
  • MACHINEの設定
MACHINE = "intel-corei7-64"
WKS_FILE = "image-installer.wks.in"
IMAGE_FSTYPES:append = " ext4"
IMAGE_TYPEDEP_wic = "ext4"
INITRD_IMAGE_LIVE = "core-image-minimal-initramfs"
do_image_wic[depends] += "${INITRD_IMAGE_LIVE}:do_image_complete"
do_image_wic[recrdeptask] += "do_image_ext4"
do_rootfs[depends] += "virtual/kernel:do_deploy"
IMAGE_BOOT_FILES:append = " \
${KERNEL_IMAGETYPE} \
    microcode.cpio \
    ${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}.ext4;rootfs.img \
    ${@bb.utils.contains('EFI_PROVIDER', 'grub-efi', 'grub-efi-bootx64.efi;EFI/BOOT/bootx64.efi', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'grub-efi', '${IMAGE_ROOTFS}/boot/EFI/BOOT/grub.cfg;EFI/BOOT/grub.cfg', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', 'systemd-bootx64.efi;EFI/BOOT/bootx64.efi', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', '${IMAGE_ROOTFS}/boot/loader/loader.conf;loader/loader.conf ', '', d)} \
    ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', '${IMAGE_ROOTFS}/boot/loader/entries/boot.conf;loader/entries/boot.conf', '', d)} \
    "
build/conf/bblayers.conf
  • レシピパスの設定
BBLAYERS ?= " \
      ${TOPDIR}/../sources/poky/meta \
      ${TOPDIR}/../sources/poky/meta-poky \
      ${TOPDIR}/../sources/poky/meta-yocto-bsp \
      ${TOPDIR}/../sources/meta-openembedded/meta-oe \
      ${TOPDIR}/../sources/meta-openembedded/meta-networking \
      ${TOPDIR}/../sources/meta-openembedded/meta-python \
      ${TOPDIR}/../sources/meta-openembedded/meta-filesystems \
      ${TOPDIR}/../sources/meta-openembedded/meta-multimedia \
      ${TOPDIR}/../sources/meta-intel \
      "

ビルド

  • X11 の最小イメージ
$ bitbake core-image-x11
  • SATO デスクトップイメージ
$ bitbake core-image-sato

インストールUSBメモリーの作成

  • X11 の最小イメージ
$ sudo dd if=tmp/deploy/images/intel-corei7-64/core-image-x11-intel-corei7-64.wic of=/dev/sdx status=progress
  • SATO デスクトップイメージ
$ sudo dd if=tmp/deploy/images/intel-corei7-64/core-image-sato-intel-corei7-64.wic of=/dev/sdx status=progress

sdx は環境に合わせて変更ください。
[例]sdc

Windows機ならrufusで作成できます。
rufus.ie

ターゲット機のBIOSUEFI)でブートデバイス順序の第1をUSBにして、このUSBメモリーをターゲット機に挿して起動すればインストール開始します。

カスタマイズ

インストール開始までの待ち(タイムアウト)時間変更

デフォルトだと、インストール開始まで5秒待たされます。この待ち時間はsources/meta-intel/wic/image-installer.wks.inで変更できます。
[例]1秒

bootloader --ptable gpt --timeout=1 --append=" rootwait "
インストール処理の変更

インストール処理はsources/poky/meta/recipes-core/initrdscripts/files/init-install-efi.shに記述されています。 インストール処理を変更したい場合はこのファイルを編集ください。

  • [例]インストール先指定に待ち時間を設定
--- sources/poky/meta/recipes-core/initrdscripts/files/init-install-efi.sh.orig      2023-12-26 13:21:42.493604948 +0900
+++ sources/poky/meta/recipes-core/initrdscripts/files/init-install-efi.sh     2023-12-07 09:14:09.962019853 +0900
@@ -101,12 +101,16 @@

 # Get user choice
 while true; do
-    echo "Please select an install target or press n to exit ($hdnamelist ): "
-    read answer
+    echo "Please select an install target or press n to exit ($hdnamelist ), waiting for 5 secs ...: "
+    read -t 5 answer || true
     if [ "$answer" = "n" ]; then
         echo "Installation manually aborted."
         exit 1
     fi
+    if [ -z "$answer" ]; then
+        echo "Default target (sda) selected."
+        answer=sda
+    fi
     for hdname in $hdnamelist; do
         if [ "$answer" = "$hdname" ]; then
             TARGET_DEVICE_NAME=$answer
  • [例]インストール先の強制フォーマット
 @@ -208,7 +212,7 @@
 mkfs.vfat $bootfs

 echo "Formatting $rootfs to ext4..."
-mkfs.ext4 $rootfs
+mkfs.ext4 -F $rootfs

 echo "Formatting swap partition...($swap)"
 mkswap $swap
  • [例]ブートオプションの変更
@@ -274,7 +278,7 @@
     # delete any root= strings
     sed -i "s/ root=[^ ]*/ /" $SYSTEMDBOOT_CFGS
     # add the root= and other standard boot options
-    sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait quiet @" $SYSTEMDBOOT_CFGS
+    sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait @" $SYSTEMDBOOT_CFGS
 fi

 umount /tgt_root
Linuxブートまでの待ち(タイムアウト)時間変更

デフォルトだと、Linuxブートまで10秒待たされます。この待ち時間はbuild/conf/local.confに下記追加で変更できます。
[例]1秒

SYSTEMD_BOOT_TIMEOUT = "1"

【BD-HW51】STBとの予約録画連携の設定

CATV(ケーブルテレビ)のSTB(セットトップボックス)の予約録画設定で録画先をLAN接続したHDDレコーダーにしてますが、ときどき録画失敗してました。録画時間前になるとHDDレコーダーが起動しますが、このときSTBとのLAN接続失敗が原因でした。
私のHDDレコーダーはシャープ製BD-HW51ですが、クイック起動設定がデフォルトの「する(設定2)」のままでした。この設定だと録画時間前に起動しても録画時間までにSTBとLAN接続できませんでした。そこで、設定を「する(設定1)」に変更したところ、録画失敗することなくなりました。

クイック起動設定については取説 操作編のp210に載ってます。

取扱説明書 ブルーレイディスクレコーダー BD-HW51

【TRACE32】Infineon製SPIフラッシュS25FLxのレジスター設定

Infineon製SPIフラッシュS25FLxをQSPIで使うにはレジスターでクアッドモードに設定する必要があります。
an889.hatenablog.com

このレジスター設定をローターバッファ社製デバッガーソフトウェアTRACE32でするお話です。

TRACE32でSPIフラッシュを扱う場合、付属のフラッシュプログラムを使います。
プロセッサーがZynqMP(XILINXプロセッサーZynq™ UltraScale+™ MPSoC)の場合です。

FLASHFILE.TARGET 0xFFFC1000++0x2FFF  E:0xFFFC4000++0x27FF ./spiw4b64_zynqultra.bin /KEEP /STACKSIZE 0x400 /DUALPORT
FLASHFILE.TARGET 0xFFFC1000++0x2FFF  E:0xFFFC4000++0x27FF ./spi4b64_zynqultra.bin  /KEEP /STACKSIZE 0x400 /DUALPORT


レジスター設定方法です。

  • デュアルパラレル接続
FLASHFILE.SPI.CMD 0x06 0x06 ; Write Enable
FLASHFILE.SPI.CMD 0x01 0x01 0x00 0x00 0x02 0x02 ; Write <SR1> <SR1> <CR1> <CR1>
FLASHFILE.SPI.CMD 0x04 0x04 ; Write Disable
  • デュアルスタックまたはシングル接続
FLASHFILE.SPI.CMD 0x06 ; Write Enable
FLASHFILE.SPI.CMD 0x01 0x00 0x02 ; Write <SR1> <CR1>
FLASHFILE.SPI.CMD 0x04 ; Write Disable


設定できたかどうかレジスター読出しで確認できます。

  • デュアルパラレル接続
FLASHFILE.SPI.CMD 0x35 0x35 /READ 0x2
  • デュアルスタックまたはシングル接続
FLASHFILE.SPI.CMD 0x35 /READ 0x1


FLASHFILE.SPI.CMDの書式です。

  • デュアルパラレル接続
FLASHFILE.SPI.CMD <cmd for flash_bottom> <cmd for flash_top> <data[0] for flash_bottom> <data[0] for flash_top> <data[1] for flash_bottom> <data[1] for flash_top> ...
  • デュアルスタックまたはシングル接続
    デュアルスタックで上位デバイスの設定はできません。
FLASHFILE.SPI.CMD <cmd> <data[0]> <data[1]> ...


その他注意事項です。

  • FLASHFILE.unlockはCR1(Configuration register 1)を初期化するので、使わないでください。

【U-Boot】ZynqMPでInfineon製SPIフラッシュS25FLxを使うときの注意事項

XILINXプロセッサーZynq™ UltraScale+™ MPSoC(以下、ZynqMP)でInfineon製SPIフラッシュS25FLシリーズ*1を使ったときのことです。
ZynqMPとこのフラッシュとはQSPIデュアルパラレル接続しました*2

QSPIなのでフラッシュをクアッドモードに設定する必要があります。
このフラッシュのU-Bootでのクアッド設定はdrivers/mtd/spi/spi-nor-core.cspansion_read_cr_quad_enable()です。これはspi_nor_init()内で呼ばれます。ところが、クアッド設定に失敗します。

このフラッシュのクアッド設定はCR1[1](Configuration register 1のビット1 QUAD)で行います。工場出荷値は0でクアッド無効です。CR1を設定するにはWRR(Write Register)コマンド0x01を使うのですが、その際のデータ部は2バイトで、データ部の0バイト目をSR1(Status Register 1)のデータ、1バイト目をCR1のデータにします。
このデータ長が2というのが落とし穴でした。デュアルパラレル接続ではストライプでデータをフラッシュへ送信します。偶数バイトを下位フラッシュへ、奇数バイトを上位フラッシュへと *3。なので、0バイト目のSR1のデータが下位フラッシュへ、1バイト目のCR1のデータが上位デバイスへ送信され、下位・上位フラッシュそれぞれにはWRRコマンドがデータ長1になってました(バス波形でも確認)。これではSR1の設定になるので、CR1を設定できません。
なので、WRRコマンド送信時はストライプを無効にする必要があります。ストライプ有効/無効はZynqMPのGQSPI_GEN_FIFOレジスタ*4のビット18で設定します。

そこで、spansion_read_cr_quad_enable()内で呼ばれるwrite_sr_cr()でストライプ設定を無効にすることで、CR1を設定できるようになり、クアッドモードにすることができました。このパッチです。これはv2023.01_2023.1*5用です。v2023.01_2023.2*6ではストライプ設定実装が変わってるので、このパッチは適用できません。

4バイトアドレスモードにするためのset_4byte()も同様の対処必要です。このフラッシュを4バイトアドレスモードにするにはBAR[7](Bank address registerのビット7 EXTADD)を1にする必要ありますが、その設定のBRWR(Bank Register Write)コマンド0x17もストライプ有効だとデータ部が1バイトのため下位デバイスのみに送信されます。この対処もパッチに入れています。

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index cff390b4..b58a4c43 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -2108,7 +2108,12 @@ static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
 
    write_enable(nor);
 
+   if (nor->isparallel) /* eratta */
+       nor->spi->flags &= ~SPI_XFER_STRIPE;
    ret = nor->write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
+   if (nor->isparallel) /* eratta */
+       nor->spi->flags |= SPI_XFER_STRIPE;
+
    if (ret < 0) {
        dev_dbg(nor->dev,
            "error while writing configuration register\n");
@@ -3656,6 +3661,38 @@ static void s25fl256l_default_init(struct spi_nor *nor)
 static struct spi_nor_fixups s25fl256l_fixups = {
    .default_init = s25fl256l_default_init,
 };
+
+static int s25fl512s_post_bfpt_fixup(struct spi_nor *nor,
+                  const struct sfdp_parameter_header *header,
+                  const struct sfdp_bfpt *bfpt,
+                  struct spi_nor_flash_parameter *params)
+{
+   int ret;
+
+   if (nor->isparallel) {
+       /* eratta */
+       nor->spi->flags &= ~SPI_XFER_STRIPE;
+       ret = set_4byte(nor, nor->info, 1);
+       nor->spi->flags |= SPI_XFER_STRIPE;
+   } else if (nor->isstacked) {
+       ret = set_4byte(nor, nor->info, 1);
+       nor->spi->flags |= SPI_XFER_U_PAGE;
+       ret |= set_4byte(nor, nor->info, 1);
+       nor->spi->flags &= ~SPI_XFER_U_PAGE;
+   } else {
+       ret = set_4byte(nor, nor->info, 1);
+   }
+   if (ret)
+       return ret;
+
+   nor->addr_width = 4;
+
+   return 0;
+}
+
+static struct spi_nor_fixups s25fl512s_fixups = {
+   .post_bfpt = s25fl512s_post_bfpt_fixup,
+};
 #endif
 
 #ifdef CONFIG_SPI_FLASH_S28HX_T
@@ -4432,6 +4469,10 @@ void spi_nor_set_fixups(struct spi_nor *nor)
    if (CONFIG_IS_ENABLED(SPI_FLASH_BAR) &&
        !strcmp(nor->info->name, "s25fl256l"))
        nor->fixups = &s25fl256l_fixups;
+
+   if (!CONFIG_IS_ENABLED(SPI_FLASH_BAR) &&
+       !strncmp(nor->info->name, "s25fl512s", 9))
+       nor->fixups = &s25fl512s_fixups;
 #endif
 
 #ifdef CONFIG_SPI_FLASH_MT35XU

【ZynqMP】xqspipsu_generic_flash_interrupt_example.c の修正

XILINX社のSDKであるVitisにはいろいろなサンプルプログラムが同梱されています。 japan.xilinx.com

このうちのQSPIフラッシュテストプログラムにいけてないところが少しあるので修正しました。 github.com

  • FlashEnableQuadMode()
    case SPANSION_ID_BYTE0で、WRITE_ENABLE_CMD 発行前にチップセレクトも兼ねる GetRealAddr() が実行されないので、フラッシュがデュアルパラレルだと上位デバイスへ WRITE_ENABLE_CMD コマンドが発行されません。
    なので、WRITE_ENABLE_CMD 発行前に GetRealAddr() を実行するようにしました。

  • QspiPsuInterruptFlashExample()
    コマンドのデバッグ文が元の位置だと、その後に選択された4バイトモードコマンドが表示されないので、4バイトモードコマンド選択後に移動しました。

--- xqspipsu_generic_flash_interrupt_example.c.orig  2023-10-10 10:28:10.692908400 +0900
+++ xqspipsu_generic_flash_interrupt_example.c    2023-10-17 15:25:32.296358072 +0900
@@ -371,10 +371,6 @@
        FSRFlag = 0;
    }
 
-  xil_printf("ReadCmd: 0x%x, WriteCmd: 0x%x,"
-         "StatusCmd: 0x%x, FSRFlag: %d\n\r",
-         ReadCmd, WriteCmd, StatusCmd, FSRFlag);
-
    if (Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB) {
        Status = FlashEnterExit4BAddMode(QspiPsuInstancePtr, ENTER_4B);
        if (Status != XST_SUCCESS) {
@@ -393,6 +389,10 @@
        }
    }
 
+   xil_printf("ReadCmd: 0x%x, WriteCmd: 0x%x,"
+          "StatusCmd: 0x%x, FSRFlag: %d\n\r",
+          ReadCmd, WriteCmd, StatusCmd, FSRFlag);
+
    for (UniqueValue = UNIQUE_VALUE, Count = 0;
            Count < PageSize;
            Count++, UniqueValue++) {
@@ -1986,6 +1986,7 @@
        while (TransferInProgress);
 
        WriteEnableCmd = WRITE_ENABLE_CMD;
+       GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
        /*
         * Send the write enable command to the Flash
         * so that it can be written to, this needs
@@ -2006,8 +2007,6 @@
        }
        while (TransferInProgress);
 
-      GetRealAddr(QspiPsuPtr, TEST_ADDRESS);
-
        WriteBuffer[0] = WRITE_CONFIG_CMD;
        WriteBuffer[1] |= 0x02;
        WriteBuffer[2] |= 0x01 << 1;
@@ -2071,6 +2070,7 @@
        FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI;
        FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX;
 
+       memset(ReadBfrPtr, 0xff, sizeof(ReadBfrPtr));
        FlashMsg[1].TxBfrPtr = NULL;
        FlashMsg[1].RxBfrPtr = ReadBfrPtr;
        FlashMsg[1].ByteCount = 1;