Multi Source Translation Content

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Multi Source Translation Content

ディスカッション

ソート順:
imx93: SRKの取り消し こんにちは、 私は、閉鎖済みのimx93ボード上で鍵の失効処理を実行しようとしています。 私のCSFファイルは次のようになっています。 [ヘッダ] ターゲット=アハブ バージョン = 1.0 [SRKをインストール] ファイル = "../cst-3.4.0/crts/SRKtable.bin" ソース = "../cst-3.4.0/crts/SRK2_sha384_secp384r1_v3_usr_crt.pem" ソースインデックス = 1 ソースセット = OEM 取り消し = 0x1 [データの認証] ファイル = "spl.bin" オフセット = 0x400 0x490 このアイデアはSRK2に署名し、SRK1(0x1ビットマスク)を取り消すことです。そのイメージから起動しても問題ありませんが、SRK1で署名されたイメージからも起動できます。 SRK1の資格を取り消すために、他に何か必要な手続きはありますか? ありがとうございます マチュー Re: imx93: SRK revocation こんにちは。私もi.MX93でSRKの失効処理に取り組んでおり、ヒントをありがとうございます。ahab_commit 0x10 は確かに失効を有効にするものですが、その出力と、現場のデバイスでどのように使用するかについて質問があります。 閉じた状態の i.MX93 上で、SRK テーブルの最初のキー (SRK0) と 4 番目のキーの失効ビット (マスク 0x8、SRK3) で署名されたコンテナを含む最初のイメージを起動し、失効処理はまだ適用されていません。そして、u-boot コンソールから ahab_commit 0x10 を実行しました。 - この最初のコミットは「Ahab コミットが成功しました」と回答しました。情報タイプは「0x10」であり、4番目のキーが失効したようです。コミット前に起動した、そのキーで署名されたイメージは、その後拒否されます。 その後、まったく同じコマンド(同じ引数、同じ u-boot)を 3 回連続で実行すると、常に「Ahab コミットが成功しました」という応答が返されます。情報タイプは0x0」であり、ahab_statusにイベント情報はありません。 「情報タイプ」の値は何を意味しますか?それは実際に犯されたことの仮面で、犯すことが何も残っていない0x0なのでしょうか?私の知る限り、取り消しがまだ保留中かどうかを知る他の方法はない(ヒューズバンクとele_infoは前後で同一です)。 これは現場のデバイスで重要で、u-bootコンソールでコマンドを入力できないため、コミットはu-boot(起動コマンド)によって自動的に実行されなければなりません。一度だけ実行するようにすれば、それを追跡するためのフラグが必要になりますが、それとも毎回起動時のブートコマンドに含めておいても問題ありませんか?私は後者の方が好みです。そうすれば、新しいビルドはアップデートバージョンがスキップされていても取り消しを継続できるからです。 よろしくお願いします! Re: imx93: SRK revocation うまくいきました、ありがとうございます。ただ、メインラインのサポートahab_commit追加しなければなりませんでした: https://lists.denx.de/pipermail/u-boot/2024-March/548873.html Re: imx93: SRK revocation ahab_commit 0x10 のステップが欠落していないか確認します よろしくお願いします。 Harvey
記事全体を表示
S32G399 裸机 DDR 初始化 问候! 我们正在尝试在启动过程中重现这一核心序列: 但在 M7 内核初始化 DDR 时遇到了一些问题。 1. 我们在 Design Studio 中根据示例创建了一个新项目;(Linflexd_Uart_Ip_Example_S32G399A_M7: Debug_RAM); 2.配置并验证了DDR,生成了与ddr_*.c相关的源文件; 3. 从 GoldVIP 示例和 arm-trusted-firmware 中复制并修改了一些与 DDR 初始化相关的代码; 4. 我们在 main.c 中有这样的代码序列:   Clock_Ip_Init(&Mcu_aClockConfigPB[0]); IntCtrl_Ip_Init(&IntCtrlConfig_0); Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0); Mpu_M7_Ip_Init(&MPU_M7_ModuleConfig_0); EnableRdInterconnect(2); // RD2 EnableRdInterconnect(3); // RD3 /* 2. NoC QoS */ FlexNOC_InitNoc(4); // 4 - CORE_ID_M7_0 enable_partition(); ddr_status = ddr_init();   我们注意到,DDR初始化后处于睡眠模式,所以我们将其唤醒:   *(volatile uint32_t*)0x403C0000 = 0x83080023; *(volatile uint32_t*)0x403C0020 &= ~0x1; *(volatile uint32_t*)0x403C0030 = 0x0; *(volatile uint32_t*)0x403C0320 = 0x0; *(volatile uint32_t*)0x403C0320 = 0x1;   DDR 内存从地址 0x60000000 开始,因此在使用调试探针进行调试时,我们可以在汇编代码中看到内存已分配,没有错误,也没有硬故障,但是如果我们在 GDB 中调用:   set {uint32_t}0x60000000 = 0xDEADBEEF 或 x/1xw 0x60000000   它返回“无法访问地址 0x60000000 处的内存”。   ddr_status返回0 。   请问我们哪里做错了?该图是否真的适用于NXP推荐的S32G399板启动方式?   谢谢! Re: S32G399 Bare Metal DDR initialization 你好, @Interrogator 感谢你的帖子。 实际上,您提到的流程并不是使用 S32G 平台时的典型启动流程。 典型的启动流程如 AN13750 和 GoldVIP 中所述,启动加载程序在 M7_0 上运行(也是初始化时钟、引脚等),负责加载不同分区(如 M7_1/2、A53_0)的映像,而 Linux 电路板支持包。加载到 A53_0,DDR 将由在 A53_0 上运行的 TFA 初始化。 请问您目前正在进行设计工作吗?如果是这样,相对推荐使用上述启动流程。 BR 陈银 Re: S32G399 Bare Metal DDR initialization @chenyin_h谢谢你的回复!我非常感谢。您能否也帮我理解一件事:我们目前手头有这块板,但 M7 可能没有引导加载程序。我们将 Yocto 电路板支持包。 46 构建的 Linux 镜像烧录到 SD 卡(.sdcard 文件)上,将卡插入板子,切换板上的引脚以从 SD 卡加载,并期望与 S32G274 上的行为相同,但 UART 输出完全为空。虽然在 COM 会话 (MobaXterm) 中按下按钮会导致板上的 Rx 指示灯闪烁。要查看 Linux 输出,我们需要 M7 引导加载程序,对吗?请问针对我们目前的情况,您能提出最佳解决方案吗? 谢谢你! Re: S32G399 Bare Metal DDR initialization @chenyin_h你好! 1.我们使用定制板,该电路板只有 SW3、SW6.1-2、SW10.1-2 和 SW12.1-2 引脚。 2. 我们在我们的机器上运行 bitbake,并从源代码(内核、引导加载程序、根文件系统)构建镜像。 Re: S32G399 Bare Metal DDR initialization 你好, @Interrogator 感谢您的回复。 如果您不需要使用 M7 端,则仅使用电路板支持包。启动主板即可。(M7 在这种设置下,引导加载程序并非必需。) 关于您遇到的问题 1. 使用的是哪种类型的板?定制方案还是恩智浦的参考设计? 2. 如何生成写入 SD 卡的 BSP46 镜像?使用的是预构建镜像还是自定义镜像? BR 陈银  Re: S32G399 Bare Metal DDR initialization 你好, @Interrogator 谢谢你的确认 1. 通常情况下,使用默认的 电路板支持包。 代码/设置,构建的镜像旨在启动 S32G3 参考板,如 RDB3/EVB3。 2. 由于您使用的是定制板,因此构建的映像可能无法正确启动该板,这实际上是定制板启动问题。 不确定您是否对原始的 BSP46 电路板支持包。进行过任何修改,以及是否有任何调试日志可以帮助定位问题? BR 陈银 Re: S32G399 Bare Metal DDR initialization 您好, @chenyin_h 感谢您的积极参与! 1. 我们刚刚试用了预构建的电路板支持包。 46,但很遗憾地遇到了同样的问题。 2. 我们使用 s32g3xx_attach.py 脚本对 A 核心进行调试,并在调试器控制台中发现了以下日志: 394,149 =cmd-param-changed,param="remote hardware-breakpoint-limit",value="6" 394,149 =cmd-param-changed,param="remote hardware-watchpoint-limit",value="4" 394,150 =cmd-param-changed,param="默认无法访问的内存",value="关闭" 394,151 =cmd-param-changed,param="默认无法访问的内存",value="开启" 394,164 ~“核心无法停止。状态:CoreMode.Disabled\r\n” 394,165 ~“错误类型:[CoreError]\r\n” 394,165 ~"错误代码:[200]\r\n" 394,165 ~"\r\n" 394,165 ~"\r\n" 394,165 ~" --- 初始化脚本的堆栈跟踪 ---\r\n" 这能给你提供什么线索吗? 在 M 核心上运行 s32g3xx_attach.py 返回相同的结果。 然而,s32g3xx_generic_bareboard.py 运行良好,但我们的想法是将调试器附加到已启动的核心,并通过汇编中的寄存器检查其状态。 Re: S32G399 Bare Metal DDR initialization 你好, @Interrogator 感谢您的回复。 BSP46预编译镜像应该可以在RDB3上运行(除非是非常老的版本板)。 1. 请问您是否同时拥有RDB3和定制板?(因为您在不同的回复中提到了不同的板) 2. 最终目标是运行基于自定义板的 电路板支持包。 或 GoldVIP 风格设计(M 引导加载程序 -> A(电路板支持包。) + M(App))吗?RDB3 就足够了吗? 我们可以进一步讨论细节(如果某些内容不方便分享,我们也可以在私信/支持案例中讨论),并将目标分成几个阶段,以帮助您在设计的系统中高效地使用 S32G。 BR 陈银 Re: S32G399 Bare Metal DDR initialization 你好, @Interrogator 感谢您的回复。 抱歉,我对您的测试设置有些困惑,您能否详细说明一下? 1. 从硬件角度来看,请问您使用的是定制板(由贵公司或第三方设计的板)还是参考板(由恩智浦设计,您可以从恩智浦或任何授权分销商处购买,S32G3 的参考板可能被称为 RDB3/EVB3/GoldBox3)? 2. 电路板支持包。 是 NXP 版本的软件,主要面向 S32G3 的 A53 端运行。请问您的最终目标是在 RDB3 上运行电路板支持包。,还是在您的定制板上运行电路板支持包。? BR 陈银 Re: S32G399 Bare Metal DDR initialization 你好, @chenyin_h 很抱歉之前的帖子回答得不够清楚。让我再解释一下: 1.我手里拿着一块定制板。 2. 我的最终目标是在我们定制的电路板上运行电路板支持包。。 谢谢你! Re: S32G399 Bare Metal DDR initialization 你好, @chenyin_h 1.我只有一块定制的开发板,我尝试了用上市,不用发布它的不同方法(RDB3 和 GoldVIP)。 2. 最终目标是运行 RDB3/电路板支持包。方法。 感谢您的参与,我很乐意接受进一步的帮助。您需要哪些额外信息? Re: S32G399 Bare Metal DDR initialization 你好, @Interrogator 谢谢您的确认。 对于此类问题,我可能需要先查看您的硬件设计,以便方便地分享原理图等信息。稍后我会帮您创建一个私人案例,以便更好地进行进一步讨论。 BR 陈银
記事全体を表示
S32G399 ベアメタル DDR 初期化 こんにちは! 私たちは、起動プロセスにおいてこのコアシーケンスを再現しようとしています。 しかし、M7コアによるDDR初期化中にいくつかの問題が発生しました。 1. Design Studioの例から新しいプロジェクトを作成しました;(Linflexd_Uart_Ip_Example_S32G399A_M7: Debug_RAM); 2. DDRの設定と検証を行い、ddr_*.cに関連するソースファイルを生成しました。 3. GoldVIP例およびarm-trusted-firmwareからDDR初期化に関するコードをコピー・調整; 4. main.c には次のようなコードシーケンスがあります。   Clock_Ip_Init(&Mcu_aClockConfigPB[0]); IntCtrl_Ip_Init(&IntCtrlConfig_0); Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0); Mpu_M7_Ip_Init(&MPU_M7_ModuleConfig_0); EnableRdInterconnect(2); // RD2 EnableRdInterconnect(3); // RD3 /* 2. NoC QoS */ FlexNOC_InitNoc(4); // 4 - CORE_ID_M7_0 enable_partition(); ddr_status = ddr_init();   DDRが初期化された後はスリープモードになることに気づいたので、私たちはそれを起動します:   *(volatile uint32_t*)0x403C0000 = 0x83080023; *(volatile uint32_t*)0x403C0020 &= ~0x1; *(volatile uint32_t*)0x403C0030 = 0x0; *(volatile uint32_t*)0x403C0320 = 0x0; *(volatile uint32_t*)0x403C0320 = 0x1;   DDRメモリはアドレス0x60000000から始まるため、Debug Probeでのデバッグ中にアセンブリでメモリが割り当てられていることが確認できます。エラーもハードフォルトもありませんが、GDBで呼び出すと:   set {uint32_t}0x60000000 = 0xDEADBEEF または x/1xw 0x60000000   「アドレス0x60000000のメモリにアクセスできません」と返されます   ddr_status は0を返します。   私たちが何を間違っているのか教えていただけますか?そして、その図はNXPが推奨するS32G399ボードの起動方法として実際に適用できるものなのでしょうか?   ご回答をお待ちしています。 Re: S32G399 Bare Metal DDR initialization こんにちは、 @Interrogator 投稿ありがとうございます。 実は、あなたが言及したフローはS32Gプラットフォームを使う際の典型的なブートフローではありません。 典型的なブートフローは、AN13750やGoldVIPで説明されている通りで、ブートローダーがM7_0(イニットクロックやピンなど)上で動作し、異なるパーティション(M7_1/2、A53_0など)のイメージを読み込みます。一方、Linux BSPはA53_0に読み込まれ、DDRはA53_0上で動作するTFAによって初期化されます。 現在、デザインに取り組んでいるか教えていただけますか?もしそうなら、上記のブートフローを使うことが比較的推奨されます。 BR チェイン Re: S32G399 Bare Metal DDR initialization @chenyin_hこんにちは! 1.当社では、SW3、SW6.1-2、SW10.1-2、SW12.1-2のピンのみを備えたカスタム基板を使用しています。 2. マシン上でbitbakeを実行し、ソースコード(カーネル、ブートローダー、ルートファイルシステム)からイメージを構築します。 Re: S32G399 Bare Metal DDR initialization @chenyin_h返信ありがとうございます!本当に感謝しています。もう一つ教えてもらえますか?現在ボードは手元にあり、M7にはブートローダーがない可能性があります。Yocto BSP 46で構築されたLinuxイメージをSDカード(.sdcardファイル)に書き込み、ボードにカードを差し込み、ボードのピンをSDカードから読み込むように切り替えましたが、S32G274と同じ動作を期待していましたが、UARTの出力は完全に空でした。COMセッション(MobaXterm)中にボタンを押すと、ボード上のRxインジケーターが点滅します。Linux出力を見るにはM7ブートローダーが必要ですよね?私たちの状況で最善の方法を教えていただけませんか? ありがとう! Re: S32G399 Bare Metal DDR initialization こんにちは、 @Interrogator 確認ありがとうございます 1. 通常、デフォルトのBSPコード/設定では、構築されるイメージはRDB3/EVB3のようなS32G3リファレンスボードの起動をターゲットとしています。 2. カスタムボードを扱っている場合、正しく起動できなかったイメージが作られ、これはカスタムボードの表示問題である可能性があります。 オリジナルのBSP46 BSPに何らかの変更を加えたかどうか、また問題箇所を特定するためのデバッグログがあるかどうかは分かりません。 BR チェイン Re: S32G399 Bare Metal DDR initialization こんにちは、 @Interrogator ご返信ありがとうございます。 M7側を使用する必要がない場合は、BSPのみを使用してボードを起動すれば十分です。(M7ブートローダーはこのような設定では必須ではありません。 あなたが遭遇した問題に関して 1. どのような種類のボードが使用されていますか?カスタムのものか、NXPのリファレンスデザインか? 2. SDカードに書き込まれるBSP46イメージはどのように生成されるのですか?既製のイメージとカスタムイメージのどちらが使用されますか? BR チェイン  Re: S32G399 Bare Metal DDR initialization こんにちは、 @chenyin_h 積極的なご参加ありがとうございました! 1. 現在、S32G3 RDB3 用のプリビルド済み BSP 46 を試してみましたが、残念ながら同じ問題が発生しました。 2. s32g3xx_attach.pyスクリプトを使用してAコアのデバッグを開始したところ、デバッガーコンソールに次のログが表示されました。 394,149 =cmd-param-changed, param="remote hardware-breakpoint-limit", value="6" 394,149 =cmd-param-changed, param="remote hardware-watchpoint-limit", value="4" 394,150 =cmd-param-changed,param="mem inaccessible-by-default",value="off" 394,151 =cmd-param-changed,param="mem inaccessible-by-default",value="on" 394,164 ~「コアは止められない。状態: CoreMode.Disabled\r\n" 394,165 ~"エラーの種類: [CoreError]\r\n" 394,165 ~"エラーコード: [200]\r\n" 394,165 ~"\r\n" 394,165 ~"\r\n" 394,165 ~" --- 初期化スクリプトのスタックトレース ---\r\n" 何か手がかりになりますか? Mコア上でs32g3xx_attach.pyを実行しても同じ結果が返されます。 しかし、s32g3xx_generic_bareboard.py問題なく動作しますが、私たちのアイデアは、すでに起動しているコアにデバッガーを接続し、アセンブリのレジスタでその状態を確認することでした。 Re: S32G399 Bare Metal DDR initialization こんにちは、 @Interrogator ご返信ありがとうございます。 BSP46のプリビルドイメージは、RDB3で動作するはずです(ただし、非常に古いバージョンのボードの場合は除きます)。 1. RDB3とカスタムボードの両方をお持ちかどうか確認していただけますか?(ご回答ごとに異なるボードについて言及されているため) 2. 最終的な目標はBSPスタイルかGoldVIPスタイルのデザイン(Mブートローダー-> A(BSP)+M(App))で動かすことですか?カスタムボードベースかRDB3で十分ですか? 詳細についてはさらに話し合うこともできます(内容の一部が共有に不便な場合は、個別メッセージやサポートCASEでお話しするかもしれません)、ターゲットをいくつかのフェーズに分けて、S32Gをあなたのシステムで効率的に活用できるようにしたいと思います。 BR チェイン Re: S32G399 Bare Metal DDR initialization こんにちは、 @chenyin_h 前回の投稿で分かりにくい回答をしてしまい、申し訳ありませんでした。もう少し詳しく説明させてください。 1.私はカスタムボードを持っています 2. 私の最終目標は、カスタムボード上でBSPを実行することです。 ありがとう! Re: S32G399 Bare Metal DDR initialization こんにちは、 @Interrogator ご返信ありがとうございます。 テスト設定について少し混乱している点があり申し訳ありません。よろしければ、もう少し詳しく説明していただけますでしょうか? 1. ハードウェアの観点から、あなたが持っているのはカスタムボード(御社または第三者が設計したボード)か、NXPが設計したリファレンスボード(NXPや認定ディストリビューターから購入可能で、S32G3のリファレンスボードはRDB3/EVB3/GoldBox3と呼ばれることがある)ですか? 2. BSPはNXPがリリースしたソフトウェアで、主にS32G3のA53側で動作することをターゲットにしています。最終的な目標がBSPをRDB3上で動かすことなのか、ご確認いただけますか?それともカスタム基板上でBSPを動かすのですか? BR チェイン Re: S32G399 Bare Metal DDR initialization こんにちは、 @Interrogator ご確認いただきありがとうございます。 このような問題がある場合は、まずハードウェア設計を確認する必要があるかもしれません。回路図のような情報を便利に共有するために、後でプライベートCASEの作成をお手伝いしますので、より詳しい議論ができるようにします。 BR チェイン Re: S32G399 Bare Metal DDR initialization こんにちは、 @chenyin_h さん 1.私はカスタムボードしか持っていません。起動するために様々な方法(RDB3とGoldVIP)を試してみました。 2. 最終目標は、RDB3/BSP方式を実行することです。 ご尽力いただきありがとうございます。今後も何かお手伝いできることがあれば、ぜひお願いしたいです。他にどのような情報があれば役立ちますか?
記事全体を表示
i.MX93 FRDM: RAW10 capture through ISI writes only one line per frame with IMX219 and IMX708 Hello, We are bringing up MIPI CSI-2 RAW cameras on the FRDM-IMX93 and would appreciate NXP's help. With both an IMX219 and an IMX708, streaming starts and frames are delivered, but only one line of each captured frame contains data. All other lines are zero. On the IMX219 this happens at every resolution we tested. We do not know the cause and would be grateful for your guidance. A similar symptom was reported here on kernel 6.12.20, without a resolution: https://community.nxp.com/t5/i-MX-Graphics/i-MX93-RAW10-capture-issue-only-first-line-valid-IMX219-ISI/m-p/2321729 Environment - Board: FRDM-IMX93 (MACHINE = imx93-11x11-lpddr4x-frdm), camera on the P6 MIPI CSI connector - BSP: imx-6.18.37-2.1.0 from nxp-imx/imx-manifest (meta-imx rel_imx_6.18.37_2.1.0), Yocto 6.0.2 wrynose, DISTRO = fsl-imx-wayland - Kernel: 6.18.37-2.1.0-gddef48f9b907 - Pipeline: sensor -> csidev-4ae00000.csi (dwc-mipi-csi2) -> crossbar -> mxc_isi.0 -> mxc_isi.0.capture (/dev/video0) - Format: SRGGB10_1X10 / RG10, 2 data lanes Sensors 1. Raspberry Pi Camera Module v2 NoIR (IMX219) - In-tree imx219 driver and the unmodified BSP CSI and ISI drivers - Link frequency: 456 MHz 2. Raspberry Pi Camera Module 3 NoIR (IMX708) - Driver ported from the Raspberry Pi kernel (rpi-6.12.y) - Link frequency: 450 MHz - Without further changes, this sensor produces an IPI FIFO overflow and no frames. With sensor register 0x3095 set to 0, frames are delivered at 56 fps at 2304x1296. Results Sensor Resolution Image source Result IMX219 640x480 live image, colour bars frames delivered, only line 0 has data IMX219 1640x1232 colour bars frames delivered, only line 0 has data IMX219 1920x1080 live image, colour bars frames delivered, only line 0 has data IMX219 3280x2464 colour bars frames delivered (14.5 fps), only line 0 has data IMX708 2304x1296 colour bars frames delivered (56 fps), only line 0 has data In each case the buffer has the expected size (width x height x 2 bytes). Line 0 contains the expected data, for example the colour bars. All remaining lines are zero. The IMX219 tests reported no CSI or ISI errors in dmesg. Commands (IMX219, 640x480) media-ctl -V "'imx219 2-0010':0[fmt:SRGGB10_1X10/640x480]" media-ctl -V "'csidev-4ae00000.csi':0[fmt:SRGGB10_1X10/640x480 field:none]" media-ctl -V "'crossbar':0[fmt:SRGGB10_1X10/640x480 field:none]" media-ctl -V "'mxc_isi.0':0[fmt:SRGGB10_1X10/640x480 field:none]" media-ctl -V "'mxc_isi.0':1[fmt:SRGGB10_1X10/640x480 field:none]" v4l2-ctl -d /dev/video0 --set-fmt-video=width=640,height=480,pixelformat=RG10 \ --stream-mmap --stream-count=10 --stream-to=/tmp/cap.bin Register values read during streaming (IMX219, 640x480, debug CSI build, same symptom) ISI 0x4ae40000: CHNL_CTRL (0x00) = 0xe0000000 CHNL_IMG_CTRL (0x04) = 0x0f008001 CHNL_IMG_CFG (0x0c) = 0x01e00280 Media mix 0x4ac10000: 0x30 = 0x00010158 0x3c = 0x00000e07 0x40 = 0x00000001 0x44 = 0x00019140 (value between frames) 0x48 = 0x0002291c Questions 1. Is RAW capture from a CSI-2 sensor through the ISI validated on i.MX93? If so, which sensor, BSP version and configuration were used? 2. Are there known issues, errata or required settings that apply to this use case? 3. What should we check next? Please let us know which registers, logs or captures would be useful, and we will provide them. 4. Is a reference device tree or patch available for IMX219 or another RAW sensor on FRDM-IMX93? We can share full logs, the device tree overlay and raw captures on request. Thank you for your support. Linux Yocto Project Re: i.MX93 FRDM: RAW10 capture through ISI writes only one line per frame with IMX219 and IMX708 I sent to you the patch for imx219 already, pls refer to this 
記事全体を表示
S32 Design Studioのライセンスが切れました 親愛なるNXPへ: S32 Design Studio 3.5のライセンスがまもなく期限切れになります。      ライセンス延長を手伝ってもらえますか?      ありがとう。 アクティベーションID: 29E6-6248-FCB2-DBB6 Re: S32 Design Studio License Expired こんにちは、 お客様のS32DSライセンスが延長されました。以前のコードを使用して、S32DSを再度有効化してください。
記事全体を表示
i.MX93 FRDM: ISI を介した RAW10 キャプチャでは、IMX219 および IMX708 ではフレームごとに 1 行しか書き込まれません こんにちは、 FRDM-IMX93上でMIPI CSI-2 RAWカメラを起動させようとしており、NXPのご協力をいただければ幸いです。IMX219とIMX708の両方で、ストリーミングの開始とフレームが配信されますが、キャプチャされるのはそれぞれ1ラインのみです。 フレームにはデータが含まれています。その他の行はすべてゼロです。IMX219では、テストしたすべての解像度でこの現象が発生します。原因が不明なため、ご助言いただければ幸いです。 同様の症状がカーネル6.12.20でも報告されていますが、解決策は見つかっていません。 https://community.nxp.com/t5/i-MX-Graphics/i-MX93-RAW10-capture-issue-only-first-line-valid-IMX219-ISI/mp/2321729 環境 - ボード: FRDM-IMX93 (マシン = imx93-11x11-lpddr4x-frdm)、カメラはP6 MIPI CSIコネクタに接続 - BSP: imx-6.18.37-2.1.0nxp-imx/imx-manifest (meta-imx rel_imx_6.18.37_2.1.0) から、Yocto 6.0.2 wrynose, DISTRO = fsl-imx-wayland - カーネル:6.18.37-2.1.0-gddef48f9b907 - パイプライン:センサ -> csidev-4ae00000.csi (dwc-mipi-csi2) -> クロスバー -> mxc_isi.0-> mxc_isi.0.capture (/dev/video0) - フォーマット: SRGGB10_1X10 / RG10、2データレーン センサ 1. ラズベリーパイカメラモジュールv2 NoIR(IMX219) - インツリーのimx219ドライバおよび修正されていないBSP CSIおよびISIドライバ - リンク周波数:456 MHz 2. ラズベリーパイカメラモジュール3 NoIR(IMX708) - Raspberry Piカーネル(rpi-6.12.y)から移植されたドライバ - リンク周波数:450 MHz - 追加変更なしでは、このセンサはIPI FIFOオーバーフローを生成し、フレームは発生しません。センサーレジスタ0x3095を0に設定すると、フレームは2304x1296で56fpsで配信されます。 結果 センサ解像度画像ソースの結果 IMX219 640x480のライブ画像、カラーバーフレームが配信中、データがあるのはライン0のみです IMX219 1640x1232カラーバーフレームが届きましたが、データがあるのはライン0のみです IMX219 1920x1080 ライブ画像、カラーバーフレームを配信、データがあるのはライン0のみ IMX219 3280x2464カラーバーのフレームは14.5fpsで配信され、データがあるのはライン0のみです IMX708 2304x1296カラーバーのフレームが配信されました(56fps)、データがあるのはライン0のみです 各CASEで、バッファは期待されるサイズ(幅×高さ×2バイト)を持ちます。0行目には、例えばカラーバーなど、期待されるデータが含まれています。残りの行はすべてゼロです。IMX219のテストでは、CSIまたはISIは報告されませんでした。 dmesg にエラーが表示されます。 コマンド(IMX219、640x480) media-ctl -V "'imx219 2-0010':0[fmt:SRGGB10_1X10/640x480]" media-ctl -V "'csidev-4ae00000.csi':0[fmt:SRGGB10_1X10/640x480 field:none]" media-ctl -V "'crossbar':0[fmt:SRGGB10_1X10/640x480 field:none]" media-ctl -V "'mxc_isi.0':0[fmt:SRGGB10_1X10/640x480field:noe]" media-ctl -V "'mxc_isi.0':1[fmt:SRGGB10_1X10/640x480フィールド:なし]" v4l2-ctl -d /dev/video0 --set-fmt-video=width=640,height=480,pixelformat=RG10 \ --stream-mmap --stream-count=10 --stream-to=/tmp/cap.bin ストリーミング中のレジスタ値の読み取り(IMX219、640x480、デバッグCSIビルド、同じ症状) ISI 0x4ae40000: CHNL_CTRL (0x00) = 0xe0000000 CHNL_IMG_CTRL (0x04) = 0x0f008001 CHNL_IMG_CFG (0x0c) = 0x01e00280 メディアミックス0x4ac10000: 0x30 = 0x00010158 0x3c = 0x00000e07 0x40 = 0x00000001 0x44 = 0x00019140(フレーム間の値) 0x48 = 0x0002291c 質問 1.ISIを経由したCSI-2センサからのRAWキャプチャはi.MX93で検証されますか?もしCASEなら、どのセンサ、BSPバージョン、構成が使われましたか? 2. このユースCASEに適用される既知の問題、訂正表、または必須設定はありますか? 3. 次に何を調べるべきか?どのレジスタ、ログ、キャプチャが役立つかをお知らせいただければ、ご提供いたします。 4. FRDM-IMX93上のIMX219や他のRAWセンサの参照デバイスツリーやパッチはありますか? リクエストに応じて、完全なログ、デバイスツリーのオーバーレイ、生のキャプチャも共有可能です。 再開まで今しばらくお待ちください。 Linux Yocto Project Re: i.MX93 FRDM: RAW10 capture through ISI writes only one line per frame with IMX219 and IMX708 imx219用のパッチは既にお送りしましたので、こちらをご参照ください。
記事全体を表示
S32 Design Studio License Expired Dear NXP:      The S32 Design Studio 3.5 license is about to expire.      Could you please help extend the license?      Thank you.      ActivationId: 29E6-6248-FCB2-DBB6 Re: S32 Design Studio License Expired Hi,  your S32DS license has been extended. Please activate S32DS again with your old code. 
記事全体を表示
FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) MicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, Zephyr MicroPythonの本家リポジトリ,そのZephyrポートに,FRDM-MCXN947向けの設定がマージされました. Zephyrポートというのは,MicroPythonをZephyr RTOSの上で動かす移植版です.MicroPythonは通常,マイコンの種類ごとに専用の「ポート」(移植版)を持ちますが,MCXシリーズに専用ポートはありません.その代わり,Zephyrが対応しているボードなら動かせるこの仕組みを使います(詳しくは1.3節). ビルド自体は,これまでもできました.ただしボード固有の設定が無かったため,出来上がるのは最小限のMicroPythonで,スクリプトを保存するファイルシステムも無く,I²CもSPIも使えませんでした.今回のマージで,これらが最初から使えるようになります. これでNXPのマイコンでMicroPythonを使う選択肢が広がりました.これまでは事実上,上位のクロスオーバーMCUであるi.MX RTシリーズに限られていましたが,そこにMCX Nシリーズという,より小規模で手を出しやすい選択肢が加わったことになります. このボードに有線のEthernetが載っている点も見逃せません.MicroPythonが動く安価なボードの多くは,Wi-FiやBluetoothでネットワークにつなぎます.用途によっては,電波を使わない有線のほうが扱いやすい場面もあります.この記事の後半では,ボードをWebサーバにしてブラウザからLEDを操作するところまで動かします. 一方で,制約もあります.Zephyrポートは,チップ専用のポートに比べると機能が絞られます.たとえば同じNXPのマイコンでも,i.MX RT向けの ports/mimxrt には network.LAN() があってIPアドレスを実行時に設定できますが,Zephyrポートには network モジュール自体がありません.使えるのは socket だけで,IPアドレスはビルド時にしか決められません.この記事では,そうした制約と,実際にぶつかった問題の回避策も含めて書いています(8.2節に整理しました). 以降では,MicroPythonとは何かという話から始めて,実際にFRDM-MCXN947にMicroPythonを書き込み,LEDを光らせ,スイッチを読み,I²CやSPIのデバイスを動かし,最後にEthernetを使うところまでを一通り解説します.「MicroPythonを触るのは初めて」という方を想定して,途中の手順はできるだけ省略せずに書きました. この記事の読み方 長めの記事なので,必要なところから読んでください. Zephyrの開発環境がまだの方 → 2.1節から すでにビルドと書き込みが済んでいる方 → 3章から 何ができるのか先に見たい方 → 8.6節(ブラウザからLEDを操作する例) 章ごとに必要なものは次のとおりです. 1〜5章:FRDM-MCXN947本体とUSBケーブルだけで進められます [作業時間:60分] 6章(I²C):ジャンパ線2本 [作業時間:20分] 7章(SPI):ジャンパ線1本 [作業時間:20分] 8章(Ethernet):LANケーブル1本 [作業時間:20分] 0. 目次 目次 MicroPythonとはなんなのか? 1.1 どういうところで使われているのか 1.2 MicroPythonのいいところ,悪いところ 1.3 MCXマイコンへの対応:「Zephyrポート」という形 1.4 今回の対応でできるようになったこと 1.5 Zephyrポートの弱点:ピンの指定がタプルになる MicroPython Zephyrポートのビルド 2.1 Zephyr開発環境のインストール 2.2 MicroPythonのソースを取得する 2.3 ビルドする 2.4 ボードに書き込む MicroPythonを使ってみる — 基本編 3.1 Thonnyを用意する 3.2 どのUSBコネクタに繋ぐのか 3.3 接続してプロンプトを確認する 3.4 「REPL」とは 3.5 スクリプトを書いてみる:Lチカ 3.6 このボードで使えるピンを調べる 3.7 Lチカの色を変えてみる 応用編:ピン名を工夫する 4.1 まずはスクリプトの中にPINS辞書を書く 4.2 config.pyに切り出す 4.3 ストレージに保存して共有する 4.4 config.pyを使った3色Lチカ 応用編:スイッチを読む 5.1 スイッチの状態を読む 5.2 押されたことを割り込みで知る 応用編:I²Cを使ってみる 6.1 このボードのI²C事情 6.2 ジャンパを2本つなぐ 6.3 バスをスキャンする 6.4 温度を読む 応用編:SPIを使ってみる 7.1 ループバックで試す 7.2 CSは自動制御されない 応用編:Ethernetを使ってみる 8.1 有線LANという強み 8.2 このポートのネットワークAPI 8.3 PCと直結して試す 8.4 自分のIPアドレスを調べる 8.5 ボードをWebサーバにする 8.6 LEDをブラウザから操作する 8.7 電源を入れるだけで動くようにする 8.8 ハマりやすい点 まとめ 参考資料 付録:LED操作サーバのコード解説 11.1 ここまでの内容が1つにまとまっている 11.2 コードの3つの仕掛け 11.3 例外処理が必要な理由 11.4 Connection: close について 11.5 そのほか気をつける点 11.6 この挙動は将来変わるかもしれません 1. MicroPythonとはなんなのか? MicroPythonは,マイコンの上で直接動くPython 3のインタプリタです.2013年にDamien George氏がKickstarterで資金を集めて開発を始めたもので,現在はオープンソース(MITライセンス)のプロジェクトとして開発が続いています. 「Python 3の処理系」といっても,PCで動くCPythonをそのまま持ってきたわけではありません.数百KB程度のROMと数十KBのRAMに収まるように,言語仕様とライブラリを絞り込んで再実装したものです.そのため文法はPython 3とほぼ同じですが,標準ライブラリは必要なものだけが用意されています. その代わりに,マイコンならではのモジュールが用意されています.GPIO,I²C,SPI,UART,PWM,ADCといった周辺機能を扱う machine モジュールがその代表です.このブログでも machine モジュールを使っていきます. なお,この章は背景の説明です. すぐに手を動かしたい方は2章へ進んでください. 1.1 どういうところで使われているのか MicroPythonがよく使われるのは,次のような場面です. 教育用途:BBC micro:bitがMicroPythonを採用したことで,一気に知られるようになりました.Raspberry Pi PicoもMicroPythonを公式にサポートしています. プロトタイピング:センサをとりあえず動かしてデータを見てみたい,という段階では,ビルドとフラッシュ書き込みを繰り返すCの開発サイクルより圧倒的に速く進みます. 治具・測定器:製造ラインの検査治具や,実験用の簡易測定装置のように,「少量でいいので早く作りたい」ものに向いています. ホビー:電子工作の分野では定番の選択肢のひとつです. いずれも「動くものを早く作る」ことが重視される場面です.ここがMicroPythonの一番の得意分野といえます. 1.2 MicroPythonのいいところ,悪いところ この節の内容は,特定のマイコンやポートに限らない,MicroPython全般の性質です.使うかどうかを判断できるように,両面を挙げておきます. いいところ コードが簡単に書ける:Python 3の文法がそのまま使えます.文字列処理やリスト操作といった,Cだと面倒な処理が数行で書けます. 対話的に試せる:ボードに接続して,1行ずつコマンドを打ち込みながら動作を確かめられます.「このピンをHIGHにしたらLEDは点くのか,消えるのか」といった確認が,その場で1行打つだけで済みます.ハードウェアの挙動を手探りで確かめるとき,これは非常に強力です.(この対話環境をREPLと呼びます.3.4節で詳しく説明します) ビルドが要らない:スクリプトを書いて実行するだけです.コンパイル・リンク・書き込みのサイクルが不要なので,試行錯誤が速く回ります. 学習コストが低い:Pythonを知っていれば,マイコン側の知識だけ足せば始められます. 悪いところ 実行速度が遅い:インタプリタなので,Cで書いたコードに比べると数十倍から百倍程度遅くなります.厳密なタイミング制御が必要な処理や,高速な信号処理には向きません.ただし対策はあって,関数に @micropython.native や @micropython.viper のデコレータを付けると,その関数だけをネイティブコードにコンパイルできます.それでも足りない場合は,その部分だけCで書いてモジュールとして組み込むこともできます. メモリを食う:インタプリタ本体と標準ライブラリをマイコンに載せる必要があります.数百KBのフラッシュと数十KBのRAMが,アプリケーションを書く前の時点で消費されます.小さなマイコンでは現実的ではありません. リアルタイム性の保証がない:ガベージコレクションが動くタイミングをこちらから完全には制御できません. MCXN947は2MBのフラッシュと512KBのSRAMをチップ上に持っているので,メモリの点では余裕をもってMicroPythonを載せられます. 1.3 MCXマイコンへの対応:「Zephyrポート」という形 MicroPythonは,マイコンの種類ごとに「ポート」と呼ばれる移植版を持っています. ports/rp2 (Raspberry Pi Pico), ports/mimxrt (i.MX RT), ports/esp32 といった具合です.これらは各マイコンのレジスタやSDKを直接叩く,そのチップ専用の実装です. MCXシリーズについては,このような専用ポートは存在しません.その代わりに使えるのが ports/zephyr ,つまりZephyr RTOSの上で動かすポートです. これは「Zephyrがサポートしているボードなら,原理的にはどれでもMicroPythonが動く」という作りになっています.ペリフェラルへのアクセスはZephyrのデバイスドライバ経由で行われるため,MicroPython側にチップ固有のコードを書く必要がありません. FRDM-MCXN947はZephyrが正式にサポートしているボードなので,この仕組みに乗ることができます. NXPのマイコンでMicroPythonを使う選択肢 ここで少し整理しておきます. NXPのマイコンでMicroPythonを動かそうとしたとき,これまで実質的な選択肢はi.MX RTシリーズでした.専用ポートの ports/mimxrt がRT1010からRT1170までのEVKやTeensy 4.xに対応しており,周辺機能もひととおり使えます. Zephyrポートにも以前からいくつかNXPボードの設定が入っていましたが, mimxrt1020_evk や mimxrt685_evk_cm33 といったクロスオーバーMCU向けか, frdm_k64f / frdm_kw41z のようにかなり以前のKinetis向けで,しかも後者はファイルシステムやI²C/SPIまで整えられたものではありませんでした. i.MX RTは高い性能を持つ反面,MCUとしては上位の製品群です.「MicroPythonでちょっと試したい」という用途には,やや大きな構えになります. 今回FRDM-MCXN947の設定が入ったことで,汎用MCUであるMCX Nシリーズという,より手を出しやすい選択肢が加わりました.これも今回の対応の意味のひとつだと思います. 図1:MicroPython Zephyrポートの階層   この方式には,長所と短所の両方があります.長所は,Zephyrが対応しているボードに幅広く展開できること.短所は,Zephyrの抽象化を通すぶん,チップ専用ポートに比べて「そのボードらしい書き味」が薄くなることです.具体的には後述する「ピン指定の問題」として表れます. 1.4 今回の対応でできるようになったこと Zephyrポート自体は以前からありましたが,FRDM-MCXN947用の設定は入っていませんでした.そのままビルドすると,対話的にコマンドを打ち込むことはできても,ストレージもI²CもSPIも使えない,という状態でした. 今回,以下の2つのファイルが本家 micropython/micropython のmasterにマージされました. ports/zephyr/boards/frdm_mcxn947_mcxn947_cpu0.conf ports/zephyr/boards/frdm_mcxn947_mcxn947_cpu0.overlay これによって,次のことができるようになっています. (1) オンボードのフラッシュをファイルシステムとして使える FRDM-MCXN947に載っている8 MiBのQSPIフラッシュ(Winbond W25Q64JV)の storage_partition を,LittleFSとして /flash にマウントします.書いたスクリプトをボード上に保存しておけるようになる,という意味で,これが一番大きい変更です. 実際にマウントした状態で容量を確認すると,次のようになります. >>> import os >>> os.statvfs('/flash') (4096, 4096, 2048, 2043, 2043, 0, 0, 0, 0, 255) ブロックサイズ4096バイト × 2048ブロック = 8 MiB のうち,LittleFSの管理領域を除いた約7.98 MiBが使えます. (2) MikroBusのSPIが使えるようになった MikroBusコネクタのSPI( flexcomm6_lpspi6 )を有効にしています.このSPIは,ボード共通のdevicetreeではピン定義まで用意されているものの, status = "disabled" のままになっていました.MOSI/SCKに使うP3_20/P3_21が,SAI1と共用のピンだからです. SAIは Serial Audio Interface の略で,I²SやTDMといったデジタルオーディオのデータをやり取りするためのシリアル・インターフェースです.オーディオコーデックやマイクを繋ぐときに使うもので,同じピンをSPIとSAIの両方に同時に割り当てることはできません.そのためボード共通の定義では,どちらとも決めずに無効にしてありました. では,どちらに使うのか.今回のoverlayではSPIとして有効にするという判断がされました.根拠は単純で,MicroPythonのZephyrポートにはI²S/SAIを扱うドライバも machine.I2S のようなクラスも存在しないからです.つまりSAI1のピンとして残しておいても,MicroPythonからは使いようがありません.それならSPIとして使えるようにしたほうが有用だろう,というわけです. (3) I²CとSPIのドライバが組み込まれるようになった CONFIG_I2C=y と CONFIG_SPI=y を指定しています.これがないと machine.I2C や machine.SPI を作ろうとしても失敗します. 1.5 Zephyrポートの弱点:ピンの指定がタプルになる さて,ここでZephyrポートの「使いにくいところ」を先に紹介しておきます.あとで対策を示すので,まずは問題を知っておいてください. 一般的なMicroPythonのポートでは,ピンは名前や番号で指定します. # i.MX RTの専用ポート(ports/mimxrt)の場合 led = Pin('D9', Pin.OUT) # Raspberry Pi Pico の場合 led = Pin(25, Pin.OUT) # ESP32 の場合 led = Pin(2, Pin.OUT) 同じNXPのマイコンでも,i.MX RT用の専用ポートでは 'D9' というボード上の表記そのままの名前が使えます. ところがZephyrポートでは,GPIOポート名とビット位置のタプルで指定します. # FRDM-MCXN947(Zephyrポート)の場合 led = Pin(("gpio0", 10), Pin.OUT) ("gpio0", 10) は「GPIO0ポートの10ビット目」,つまりデータシート上のP0_10を指します.間違った形式を渡すと,次のようなエラーが出ます. >>> Pin(25, Pin.OUT) Traceback (most recent call last): File " ", line 1, in ValueError: Pin id must be tuple of ("GPIO_x", pin#) なぜこうなっているかというと,ZephyrのdevicetreeではGPIOが gpio0 , gpio1 ,… というポート単位のデバイスとして定義されていて,その中のビット位置でピンを指すからです.MicroPython側はそれをそのまま受け渡す作りになっています. 問題は,この数字が回路図やボードのシルク印刷と対応していないことです.たとえば「ArduinoヘッダーのD9に接続されている赤色LEDを光らせたい」と思っても,そのD9が ("gpio0", 10) であることは,devicetreeを読まないとわかりません.Arduinoヘッダーの D9 や,RGB LEDの 赤 といった名前は,MicroPythonからは一切見えないのです. これはかなり不便です.4章で,この対策を段階を追って紹介します. コラム:Zephyrは「SDKの下回り」としても使われている Zephyrというと「組み込みアプリケーションを書くためのRTOS」というイメージが強いと思います.実際そのとおりなのですが,最近はもうひとつの使われ方が目立ってきました.別のSDKやフレームワークの土台として,裏側で使われるという使い方です. 今回のMicroPython Zephyrポートがまさにそれです.ユーザーが書くのはPythonのコードで,Zephyrの存在を意識することはほとんどありません.しかしその下ではZephyrのカーネルとデバイスドライバが動いていて,MicroPythonのインタプリタ自身も,Zephyrのスレッドのひとつとして実行されています. 同じ構造の例としてArduinoCore-zephyrがあります.これはArduinoのAPI( pinMode() , digitalWrite() , Wire , SPI …)をZephyrの上に実装したもので,Arduino IDEから使う限りはZephyrは見えません.けれども下回りはZephyrなので,Zephyrが対応しているボードにArduino環境を持ち込めることになります. このように「Zephyrを直接使う」以外に「Zephyrの上に載ったものを使う」という選択肢が増えてきています.Zephyrのボードサポートを整備することが,そのままMicroPythonやArduinoの対応にもつながる,という関係です. ▲ 目次に戻る 2. MicroPython Zephyrポートのビルド ここからは実際に手を動かしていきます.まずはファームウェアをビルドしてボードに書き込みます. 2.1 Zephyr開発環境のインストール この記事のコマンド例は,macOSやLinuxのシェル(bashやzsh)を前提にしています.Windowsをお使いの方は,環境を作り始める前に次のコラムをお読みください. コラム:Windowsで進める場合 先に結論を書くと,Windowsのコマンドプロンプト(cmd.exe)やPowerShellでは,このビルドは通りません.コマンドを書き換えても駄目です. MicroPythonのビルド処理そのものが,UNIXのコマンドに依存しているためです.ビルド規則を定めている py/mkrules.cmake の中で, cat ・ sed ・ touch が直接呼ばれています.たとえばqstr(文字列テーブル)を生成する箇所は,次のようなシェルのパイプライン1本で書かれています. cat … | sed … | (Cプリプロセッサ) | sed … > 出力ファイル これらのコマンドはWindowsに存在しません.パイプやリダイレクトはcmd.exeでも解釈できますが,肝心の cat や sed が無いので,結局そこで止まります.シェルを変えても解決しないのはこのためです. 実際,MicroPython本家のCIでも,Zephyrポートのビルドは ubuntu-latest でのみ実行されています.Windowsでのビルドは想定されていません. 紛らわしいのですが,Zephyr自体はネイティブのWindowsでビルドできます.この節で紹介するZephyrのGetting Started Guideにも,wingetでツールを入れるWindows向けの手順があります.そちらの手順どおりに環境を作れてしまうため,MicroPythonをビルドする段階になって初めて行き詰まる,ということが起こります. Windowsで進めるなら,次のいずれかのUNIX環境を使ってください.どちらでも,この記事のコマンドはそのまま使えます. WSL2(Windows Subsystem for Linux).ZephyrのGetting Started Guideでも,Ubuntu向けの手順をそのまま使う選択肢として触れられています.導入手順はMicrosoftのドキュメントを参照してください Git for Windows(Git Bash) や MSYS2 のbash環境 なお,ビルドと書き込みだけをUNIX環境で行い,ThonnyでのMicroPython操作はWindows側から,という分け方もできます.ThonnyもmpremoteもWindowsでそのまま動くので,3章以降はWindowsだけで進められます. MicroPython ZephyrポートのビルドにはZephyrの開発環境(west,Zephyr SDK,Pythonの仮想環境など)が必要です. Zephyr環境の構築手順は,NXPコミュニティの日本語ブログで詳しく解説されています.まだ環境を作っていない方は,まずそちらを参照してください. Zephyr シリーズ 第2回 はじめてのビルドと実機動作 (日本語ブログ) この記事で参照していただきたいのは,開発環境をインストールする部分です.記事の後半ではZephyrのサンプルプログラム( blinky など)をビルドして動かしますが,このブログでビルドするのはZephyrのサンプルではなくMicroPythonです.ビルドの対象を指定する部分だけが違うと考えてください. west build が通る状態まで作れていれば,準備は完了です. Zephyrの公式ドキュメントは以下です. Zephyr Getting Started Guide 環境ができていれば, ~/zephyrproject のようなディレクトリにwest workspaceが用意されているはずです.以降はこれを ~/zephyrproject として説明します. 2.2 MicroPythonのソースを取得する MicroPythonのソースは,Zephyrのworkspaceとは別の場所に置いて構いません.Zephyrのworkspaceを汚さずに済むので,むしろ別の場所を推奨します. git clone https://github.com/micropython/micropython.git cloneしたら,作られたディレクトリに移ってサブモジュールを取得します. cd micropython git submodule update --init lib/micropython-lib micropython-lib はMicroPython用の標準ライブラリ群で,サブモジュールとして分離されています.これを取得しておかないとビルド時にエラーになるので,忘れずに実行してください. 冒頭で書いたとおり,FRDM-MCXN947用の設定は本家のmasterに入っています.パッチをあてる必要はありません. 念のため,ボード用のファイルがあることを確認しておきましょう. micropython ディレクトリにいる状態のまま実行します. ls ports/zephyr/boards/ | grep mcxn947 frdm_mcxn947_mcxn947_cpu0.conf と frdm_mcxn947_mcxn947_cpu0.overlay の2つが表示されればOKです. なぜファイル名が長いのか Zephyrでは,同じボードでもコアや動作モードによって複数の構成を持つことがあります.FRDM-MCXN947はCortex-M33をデュアルで搭載しているため, frdm_mcxn947/mcxn947/cpu0 のように「ボード名/SoC名/コア名」で指定します.これをボード修飾子(board qualifier) と呼びます. MicroPythonのZephyrポートは,この修飾子を含めた名前でconf/overlayを探します.つまり frdm_mcxn947.conf という名前では読み込まれません. frdm_mcxn947_mcxn947_cpu0.conf としてはじめて認識されます.自分でボード設定を追加するときは,ここでつまずきやすいので注意してください. 2.3 ビルドする まずZephyrの仮想環境を有効にします. source ~/zephyrproject/.venv/bin/activate 次に,Zephyrのバージョンを合わせます. cd ~/zephyrproject/zephyr git checkout v4.4.0 west update MicroPythonのZephyrポートが対応を明言しているのは,v3.7(LTS)とv4.4,そして開発版です.本家のCIはv4.4でビルドを検証しています.workspaceがそれ以外のバージョンになっていると,ビルドが通らなかったり,通っても動作が違ったりすることがあるので,ここでv4.4.0に揃えておきます. west update は,切り替えたZephyrのバージョンに合わせて,HALやライブラリなどの関連モジュールを取り直すためのものです. git checkout だけでは不整合が残るので,必ずセットで実行してください. 準備ができたら west build を実行します. cd ~/zephyrproject west build -b frdm_mcxn947/mcxn947/cpu0 ~/micropython/ports/zephyr -b がボード指定,最後の引数がビルド対象のアプリケーション(MicroPythonのZephyrポート)です. ~/micropython の部分は,実際にcloneした場所に読み替えてください. ビルドが通ると build/zephyr/ の下に zephyr.bin , zephyr.hex , zephyr.elf が生成されます. 2回目以降,設定を変えてビルドし直すときは, --pristine (または -p )を付けて前回の結果を消してからビルドすると確実です. cd ~/zephyrproject west build -p -b frdm_mcxn947/mcxn947/cpu0 ~/micropython/ports/zephyr 2.4 ボードに書き込む FRDM-MCXN947にはMCU-Linkデバッガがオンボードで載っているので,書き込みに別途デバッガを用意する必要はありません. USBケーブルはJ17(MCU-Link側のUSBコネクタ)に接続します. 図2:USBケーブルはJ17(MCU-Link側)に接続する 接続したら, west flash を実行するだけです. cd ~/zephyrproject west flash 書き込みが終わると,ボードは自動的にリセットされてMicroPythonが起動します. このJ17は書き込みだけでなく,MicroPythonと対話するためのシリアル通信にも使います.つまりケーブル1本で書き込みと操作の両方ができます.詳しくは3.2節で説明します. ▲ 目次に戻る 3. MicroPythonを使ってみる — 基本編 ファームウェアが書き込めたら,いよいよMicroPythonを触っていきます. 3.1 Thonnyを用意する MicroPythonを使うには,ボードのシリアルポートに繋いでコマンドを打ち込む環境が必要です.ターミナルソフトでも構いませんが,ここでは Thonny を使います. ThonnyはMicroPython向けの機能を最初から持っているエディタ兼IDEです.無償で,Windows / macOS / Linuxで動きます. Thonny 公式サイト Thonnyのインストールと基本操作については,以下の動画の該当部分がわかりやすいです. MicroPythonをi.MX RTクロスオーバーMCUで動かしてみた (YouTube) — Thonnyの導入部分から再生されます Thonnyを使う利点は,シリアル通信ができることに加えて, 上部のエディタでスクリプトを書いて,そのままボード上で実行できる ボードのファイルシステム( /flash )の中身をGUIで見られる PCとボードの間でファイルをドラッグ&ドロップでコピーできる という点です.4章でファイルをボードに置くときに効いてきます. 3.2 どのUSBコネクタに繋ぐのか FRDM-MCXN947にはUSB Type-Cのコネクタが複数あります.MicroPythonのコンソールに繋ぐのは J17,MCU-Link側のコネクタです(2.4節の図2と同じ場所です). MicroPythonのコンソールは,Zephyrのコンソール( zephyr,console )に出力されます.FRDM-MCXN947のcpu0では,これが flexcomm4_lpuart4 (P1_8 / P1_9)に割り当てられていて,その先がMCU-LinkのVCOM(仮想COMポート)に繋がっています. つまり J17の1本で,ファームウェアの書き込みとコンソールの両方ができます.もう一方のUSBコネクタはMCXN947本体のUSBに繋がっていますが,今回の構成では使いません. 3.3 接続してプロンプトを確認する ケーブルを繋いだらThonnyを起動します. Thonnyの右下(またはメニューの「実行」→「インタプリタの選択」)から,インタプリタとして 「MicroPython (generic)」 を選び,ポートにボードのVCOMを指定します. Windows: COM3 のような名前 macOS: /dev/cu.usbmodem… Linux: /dev/ttyACM0 など 図3:インタプリタに「MicroPython (generic)」を選ぶ   うまく繋がると,下部のシェル(Shell)ペインにプロンプトが出ます.出ないときは,シェルペインをクリックしてから Ctrl-D(ソフトリセット)を押してみてください. MicroPython v1.30.0-preview.17.g47e9329e51 on 2026-08-30; zephyr-frdm_mcxn947 with mcxn947 Type "help()" for more information. >>>   図4:接続に成功すると,シェルペイン(ウィンドウ下部)にバナーとプロンプトが表示される 最後の zephyr-frdm_mcxn947 with mcxn947 の部分に注目してください. zephyr-frdm_mcxn947 はZephyrの CONFIG_BOARD , mcxn947 は CONFIG_SOC から作られる名前です.ここが期待どおりになっていれば,狙ったボード用のバイナリが動いていると確認できます. >>> がプロンプトです.ここにPythonの式を打ち込めます.まず「Hello, world!」の表示から試してみましょう. >>> print("Hello, world!") Hello, world! MicroPythonはPythonなので,式を打つだけでも結果が返ります. >>> 1 + 2 3 >>> "MCX" * 3 'MCXMCXMCX' ファイルシステムも確認しておきます. >>> import os >>> os.getcwd() '/flash' >>> os.listdir('/flash') [] 起動直後のカレントディレクトリが /flash になっています.これは今回マージされた設定でLittleFSがマウントされているからです.まだ何も置いていないので中身は空です. 3.4 「REPL」とは いま打ち込んでいるこの対話環境を REPL と呼びます.Read(読む),Eval(評価する),Print(表示する),Loop(繰り返す)の頭文字です. 1行入力するたびに,MicroPythonはそれを読み,実行し,結果を表示し,また次の入力を待ちます.これがREPLです. コンパイルして書き込んで実行して,という手順を踏まないと結果がわからないCの開発と比べると,試行錯誤の回しかたそのものが変わってきます.たとえば「このピンをHIGHにしたらLEDは点くのか,消えるのか」といった確認が,その場で1行打つだけで済みます.ハードウェアの挙動を手探りで確かめるとき,REPLは非常に強力な道具になります. REPLで覚えておくと便利なキー操作をまとめておきます. キー 動作 Ctrl-C 実行中のプログラムを中断する Ctrl-D ソフトリセット(MicroPythonを再起動する) Ctrl-E ペーストモードに入る Ctrl-A rawREPLモードに入る Ctrl-B 通常のREPLモードに戻る 表1:REPLの制御キー Ctrl-C は,無限ループに入ってしまったプログラムを止めるときに使います.Ctrl-D は,変数などをすべて忘れて最初からやり直したいときに使います. Ctrl-E のペーストモードは,複数行のコードをまとめて貼り付けるときに使います.通常のREPLは1行ごとにインデントを解釈しようとするので, for 文のような複数行のコードをそのまま貼るとうまくいかないことがあります.Ctrl-Eを押してからコードを貼り付け,Ctrl-Dで実行すると,まとめて処理されます. 3.5 スクリプトを書いてみる:Lチカ ここまではREPLに1行ずつ打ち込んできました.ちょっとした確認にはこれが一番早いのですが,繰り返しや条件分岐が入ってくるとさすがに窮屈になります.そういうまとまった処理は,スクリプトとして書いたほうが楽です. ではスクリプトを書いてみましょう.定番のLチカ(LEDチカチカ)です. FRDM-MCXN947にはRGBのLEDが載っています.まずは赤を点滅させてみます.赤のLEDはP0_10,つまり ("gpio0", 10) に繋がっています. Thonnyの上部のエディタペインに,次のコードを書いてください. import time from machine import Pin led = Pin(("gpio0", 10), Pin.OUT) # 赤LED (P0_10) while True: led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 time.sleep(0.5) 図5:上側のエディタペインにコードを書く.下側がシェルペイン   書けたら,ツールバーの「実行」ボタン(緑の三角のアイコン.ショートカットはF5)を押します.Thonnyが「保存しますか」と聞いてきたら,保存先として「このコンピュータ」か「MicroPythonデバイス」かを選べます.今は試すだけなので,どちらでも構いません. 赤いLEDが0.5秒ごとに点滅すれば成功です. 止めるときは,ツールバーの「停止」ボタン(赤い丸のアイコン)を押します.シェルペインで Ctrl-C を押しても同じように止まります. ここで「あれ?」と思った方へ コードをよく見てください. value(0) が点灯で, value(1) が消灯です.直感と逆に見えますが,これで合っています. FRDM-MCXN947のRGB LEDは,アノードコモンで接続されています.LEDのプラス側が電源に繋がっていて,マイコンのピンがマイナス側を引っ張る形です.つまりピンをLOW(0)にしたときに電流が流れて点灯します.このような接続をアクティブ・ローといいます. 図6:FRDM-MCXN947回路図のRGB LED部分の抜粋.LEDのアノード側が電源に繋がっている   Zephyrのdevicetreeには,このLEDが GPIO_ACTIVE_LOW であるという情報がちゃんと書かれています.しかしMicroPythonの machine.Pin は,devicetreeのこのフラグを見ずにGPIOを生の値のまま読み書きします(内部で gpio_pin_set_raw() を呼んでいます).そのため,論理を反転してくれることはありません. 0 を書けばピンはLOWになり,LEDは点きます. ちなみに, led.value(0) は led.off() とも書けます.つまり led.off() を呼ぶとLEDは点灯します.名前と実際の動作が逆になるので,混乱しそうなときは value(0) / value(1) で書くほうが安全かもしれません. もうひとつ注意点: toggle() はありません 他のポートのMicroPythonに慣れていると led.toggle() と書きたくなりますが,Zephyrポートの Pin にはこのメソッドがありません.使えるのは次のものだけです. メソッド / 定数 説明 value([x]) 引数なしで読み出し,引数ありで書き込み on() HIGH(1)を出力 off() LOW(0)を出力 init(...) ピンの設定を変更 irq(...) 割り込みハンドラを設定 Pin.IN / Pin.OUT / Pin.OPEN_DRAIN 入出力モード Pin.PULL_UP / Pin.PULL_DOWN プルアップ / プルダウン Pin.IRQ_RISING / Pin.IRQ_FALLING 割り込みエッジ 表2:Zephyrポートの machine.Pin で使えるもの トグルしたいときは,読んで反転して書けば済みます. led.value(not led.value()) 3.6 このボードで使えるピンを調べる さて,赤のLEDが ("gpio0", 10) であることは,どこから来た値なのかを説明しないまま使ってきました.では自分で調べるにはどうすればいいのでしょうか. この節では,答えを探しにZephyrの設定ファイルまで降りていきます.少し込み入った話になるので,先を急ぐ方は読み飛ばして4章に進んで構いません.4章では,ここで調べた対応表を一度作ってしまえば以降は名前でピンを指定できる,という話をします. 残念ながら,MicroPythonのZephyrポートには「使えるピンの一覧を表示する」機能がありません. machine モジュールの中身を見ても,ピンの名前は出てきません. >>> import machine >>> dir(machine) Pin , I2C , SPI , UART , PWM , ADC , Timer , WDT といったクラス名が並びます(実際に何が入っているかはビルド時の設定で変わるので,手元で実行して確かめてください). Pin というクラスがあることはわかりますが,どのピンが使えるかはわかりません. では,どこを見ればいいのか 答えは Zephyrのdevicetree です. devicetreeとは (Zephyrを使ったことがある方には既知の内容です.下の「FRDM-MCXN947のdevicetreeを読む」まで飛ばしてください) devicetree(デバイスツリー)は,ボードにどんなハードウェアが載っていて,どう繋がっているかを記述したテキストファイルです.もともとはLinuxカーネルで使われていた仕組みで,Zephyrもこれを採用しています. 「このSoCにはI²Cコントローラが何個あって,それぞれどのアドレスにあって,どのピンに出ていて,有効なのか無効なのか」といった情報が, .dts / .dtsi という拡張子のファイルに階層構造で書かれています.Zephyrはビルド時にこれを読み取り,必要なドライバの初期化コードやピンの設定を自動的に生成します. ソースコードにピン番号を直接書く代わりに,ハードウェアの構成情報をコードから分離しておく,という考え方です.おかげで,同じアプリケーションのソースを別のボード向けにビルドし直すことができます. MicroPythonのZephyrポートが ("gpio0", 10) というタプルを要求するのも,このdevicetreeの構造をそのまま反映しているからです. gpio0 はdevicetree上のデバイス名で, 10 はそのポート内のビット位置です. FRDM-MCXN947のdevicetreeを読む FRDM-MCXN947のピン配置は,Zephyrのリポジトリの以下のファイルに書かれています. zephyr/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi この中の arduino_header というノードに,Arduinoヘッダーの各ピンがどのGPIOに繋がるかが書かれています. arduino_header: arduino-connector { compatible = "arduino-header-r3"; gpio-map = , , , , , /* RX */ , /* TX */ , ... , /* SCK */ , /* SDA */ ; /* SCL */ }; は「ヘッダーのD13は gpio0 の25ビット目」という意味です.これをMicroPythonのタプルに直すと ("gpio0", 25) になります. 同じファイルの中に,LEDとスイッチの定義もあります. leds { compatible = "gpio-leds"; green_led: led_1 { gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; ... }; blue_led: led_2 { gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; ... }; red_led: led_3 { gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; ... }; }; gpio_keys { compatible = "gpio-keys"; user_button_2: button_0 { gpios = <&gpio0 23 ...>; }; /* SW2 */ user_button_3: button_1 { gpios = <&gpio0 6 ...>; }; /* SW3 */ }; 赤のLEDが &gpio0 10 ,つまり ("gpio0", 10) であることがここで確認できます. GPIO_ACTIVE_LOW と書かれているのも見えますね.先ほど説明したアクティブ・ローの根拠がこれです. 毎回devicetreeを読むのか? もちろん,毎回これを調べるのは現実的ではありません.「LEDを光らせたいだけなのにdevicetreeを読む」というのは,MicroPythonの手軽さを台無しにしています. そこで4章では,この対応表を一度だけ作って,以降は名前で書けるようにする方法を紹介します. 3.7 Lチカの色を変えてみる 対策の前に,タプル指定の不便さをもう少し体感しておきましょう.3色のLEDを順番に光らせてみます. devicetreeから読み取った値は次のとおりでした. 色 ピン タプル 赤 P0_10 ("gpio0", 10) 緑 P0_27 ("gpio0", 27) 青 P1_2 ("gpio1", 2) 表3:RGB LEDのピン割り当て import time from machine import Pin red = Pin(("gpio0", 10), Pin.OUT, value=1) green = Pin(("gpio0", 27), Pin.OUT, value=1) blue = Pin(("gpio1", 2), Pin.OUT, value=1) while True: for led in (red, green, blue): led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 Pin() の value=1 は,ピンを出力に設定すると同時に初期値をHIGH(消灯)にする指定です.これを付けないと,設定した瞬間に一瞬光ることがあります. 赤→緑→青と順番に光れば成功です. さて,このコードを見てどう思うでしょうか. red = Pin(("gpio0", 10), Pin.OUT, value=1) ("gpio0", 10) という部分に,意味が読み取れません. red という変数名を付けたから読めるだけで,この数字だけを見て「赤のLED」だとわかる人はいないはずです. しかも,この数字を間違えてもエラーにはなりません. ("gpio0", 11) と書いてしまったら,存在するピンなので Pin は正常に作られ,ただLEDが光らないだけです.「どこが悪いのか」を探すのに時間を取られることになります. この問題を,次の章で片付けます. ▲ 目次に戻る 4. 応用編:ピン名を工夫する Zephyrポートがピン名を提供してくれないなら,自分で用意すればいい.それがこの章の方針です. 段階を追って,3つの段階で進めます. スクリプトの中に辞書を書く config.py という別ファイルに切り出す ボードのストレージに置いて,すべてのスクリプトから共有する 4.1 まずはスクリプトの中にPINS辞書を書く 一番簡単なのは,スクリプトの先頭にPythonの辞書を書いてしまう方法です. import time from machine import Pin PINS = { "LED_RED": ("gpio0", 10), "LED_GREEN": ("gpio0", 27), "LED_BLUE": ("gpio1", 2), } red = Pin(PINS["LED_RED"], Pin.OUT, value=1) while True: red.value(0) time.sleep(0.5) red.value(1) time.sleep(0.5) Pin(PINS["LED_RED"], ...) と書けるようになりました.これなら何をしているか一目でわかります. さらに良いのは,タイプミスがエラーになることです. >>> Pin(PINS["LED_RD"], Pin.OUT) Traceback (most recent call last): File " ", line 1, in KeyError: LED_RD 先ほどの「数字を間違えても黙って動く」状態と比べてください.辞書のキーを間違えれば KeyError で止まってくれます.これだけでもデバッグの手間がかなり減ります. 4.2 config.pyに切り出す しかし,スクリプトを書くたびにこの辞書をコピーするのは面倒です.実際,LEDだけでなくArduinoヘッダーやMikroBusのピンも定義したくなるので,辞書はどんどん長くなります.そのたびに全部のスクリプトの先頭に貼り付けるのは現実的ではありません. Pythonらしく,別ファイルに切り出してimportしましょう. config.py というファイルを作ります. PINS = { # --- Arduinoヘッダー --- "D0": ("gpio4", 3), # P4_3 (RX) "D1": ("gpio4", 2), # P4_2 (TX) "D2": ("gpio0", 29), # P0_29 "D3": ("gpio1", 23), # P1_23 "D4": ("gpio0", 30), # P0_30 "D5": ("gpio1", 21), # P1_21 "D6": ("gpio1", 2), # P1_2 "D7": ("gpio0", 31), # P0_31 "D8": ("gpio0", 28), # P0_28 "D9": ("gpio0", 10), # P0_10 "D10": ("gpio0", 27), # P0_27 (CS) "D11": ("gpio0", 24), # P0_24 (MOSI) "D12": ("gpio0", 26), # P0_26 (MISO) "D13": ("gpio0", 25), # P0_25 (SCK) "D14": ("gpio4", 0), # P4_0 (SDA) "D15": ("gpio4", 1), # P4_1 (SCL) "A2": ("gpio0", 14), # P0_14 "A3": ("gpio0", 22), # P0_22 "A4": ("gpio0", 15), # P0_15 "A5": ("gpio0", 23), # P0_23 # --- バス(Zephyrのデバイスノード名) --- "I2C": "lpi2c@94800", # flexcomm2_lpi2c2 (arduino_i2c) "SPI": "spi@93000", # flexcomm1_lpspi1 (D10〜D13) "MIKROBUS_I2C": "lpi2c@95800", # flexcomm3_lpi2c3 "MIKROBUS_SPI": "spi@b6000", # flexcomm6_lpspi6 # --- MikroBusのGPIO --- "MIKROBUS_RST": ("gpio1", 3), "MIKROBUS_CS": ("gpio3", 23), "MIKROBUS_SCK": ("gpio3", 21), "MIKROBUS_MISO": ("gpio3", 22), "MIKROBUS_MOSI": ("gpio3", 20), "MIKROBUS_PWM": ("gpio3", 19), "MIKROBUS_INT": ("gpio5", 7), "MIKROBUS_RX": ("gpio1", 16), # GPIOとして使える.UARTのRXではない "MIKROBUS_TX": ("gpio1", 17), # GPIOとして使える.UARTのTXではない "MIKROBUS_SCL": ("gpio1", 1), "MIKROBUS_SDA": ("gpio1", 0), # --- エイリアス --- "LED_RED": ("gpio0", 10), # = D9 "LED_GREEN": ("gpio0", 27), # = D10 "LED_BLUE": ("gpio1", 2), # = D6 "SW2": ("gpio0", 23), # = A5 "SW3": ("gpio0", 6), # P0_6 } すべてdevicetreeから転記した値です. いくつか補足します. RGB LEDはArduinoヘッダーと共用です. 赤のLED(P0_10)はArduinoヘッダーのD9と同じピンです.同様に緑がD10,青がD6です.Arduinoシールドを挿すときは,これらのピンを使うとLEDも一緒に光ります.逆に言えば,シールドがD6やD9を使っていると,LEDのつもりで操作するとシールド側に影響が出ます. SDA/SCLはA4/A5ではありません. Arduino UNO R3のボードでは,I²CのSDA/SCLがA4/A5と同じ配線になっていることが多く,「A4=SDA,A5=SCL」と覚えている方も多いと思います.しかしFRDM-MCXN947では違います.I²CはAREFの隣にある専用のSDA/SCLピン(Zephyrのdevicetree上ではD14/D15)に出ていて,これはP4_0/P4_1です.A4(P0_15)とA5(P0_23)は,I²Cバスには繋がっていない独立したGPIOです.5章でジャンパを繋ぐときに重要になるので,覚えておいてください. SW2はA5と同じピンです. ユーザースイッチのSW2(P0_23)は,ArduinoヘッダーのA5と同じピンに繋がっています.A5を出力として使うとスイッチの回路に影響するので注意してください. バスは文字列で指定します. machine.I2C と machine.SPI のid引数は,タプルではなくZephyrのデバイスノード名の文字列です. "lpi2c@94800" の 94800 は,MCXN947のメモリマップ上のペリフェラルのアドレス(0x94800)です.ここもdevicetree由来の値です. 4.3 ストレージに保存して共有する config.py ができました. スクリプトは「モジュール」として読み込める 先に進む前に, import について補足しておきます. config.py は特別な形式のファイルではありません. PINS = { ... } と書いただけの,ごく普通のPythonのスクリプトです.Lチカのスクリプトと同じ,ただのテキストファイルです. Pythonでは,こうしたスクリプトを他のスクリプトから読み込んで使えます.読み込まれる側をモジュールと呼び,読み込む命令が import です. from config import PINS これは「 config.py を読み込んで実行し,その中で作られた PINS をこちらに持ってくる」という意味になります.ファイル名から .py を取った config が,そのままモジュール名になります. config.py の中身が実行されるので PINS という辞書ができあがり,それをこちらで使える,というわけです. よく使う定義や関数を別ファイルにまとめておいて,必要なスクリプトから読み込む.これはPythonでごく一般的なやり方で,MicroPythonでも同じように使えます. どこに置けばよいか では config.py をボードのどこに置けば,すべてのスクリプトから import できるでしょうか. MicroPythonは,モジュールを sys.path に並んだディレクトリから探します.確認してみましょう. >>> import sys >>> sys.path ['', '.frozen', '/flash/lib'] /flash/lib が入っています.これは今回マージされた設定でLittleFSがマウントされたときに,起動処理( _boot.py )が自動的に追加してくれるものです. つまり /flash/lib/config.py として保存すれば,どのスクリプトからも from config import PINS で読めるということです. Thonnyで置く Thonnyのメニューから「表示」→「ファイル」を選ぶと,画面左側にファイルペインが表示されます.上半分がPC側,下半分がボード(MicroPythonデバイス)側です.   図7:Thonnyのファイルペインウィンドウ左側 ( config.py を /flash/lib へアップロードした)   手順は次のとおりです. 下半分(ボード側)が /flash を表示していることを確認する ボード側のペインで右クリック →「新しいディレクトリ」を選び, lib を作る 作られた lib をダブルクリックして中に入る 上半分(PC側)で config.py を右クリック →「/flash/lib へアップロード」を選ぶ 置けたか確認しましょう. >>> import os >>> os.listdir('/flash/lib') ['config.py'] コマンドラインから操作する場合(mpremote) Thonnyを使わず,コマンドラインから操作したい方には mpremote が便利です. pip install mpremote でインストールできます. まず lib ディレクトリを作ります. mpremote mkdir :/flash/lib その中に config.py をコピーします. mpremote cp config.py :/flash/lib/config.py スクリプトを実行するだけなら,ボードに保存せずに実行することもできます. mpremote run blink.py 4.4 config.pyを使った3色Lチカ 準備ができました.3.7節のコードを書き直してみましょう. import time from machine import Pin from config import PINS red = Pin(PINS["LED_RED"], Pin.OUT, value=1) green = Pin(PINS["LED_GREEN"], Pin.OUT, value=1) blue = Pin(PINS["LED_BLUE"], Pin.OUT, value=1) while True: for led in (red, green, blue): led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 3.7節と見比べてください.違いは, Pin() に渡しているものだけです. red = Pin(("gpio0", 10), Pin.OUT, value=1) # 3.7節 red = Pin(PINS["LED_RED"], Pin.OUT, value=1) # こちら ("gpio0", 10) のような数字はどこにも出てきません.「赤・緑・青のLEDを順番に光らせる」という意図が,そのままコードになりました. これで,1.5節で挙げたZephyrポートの弱点は,実用上ほぼ解消できました. config.py は一度作ってボードに置いてしまえば,以降ずっと使えます. なお,ここで使っている config.py の全文は4.2節に載せてあります.そのままコピーして使ってください. トラブルシューティング:うまくimportできないときは config.py を置いたのに ImportError が出る場合は,次を確認してください. ソフトリセットを試す.シェルペインで Ctrl-D を押します.MicroPythonは一度importしたモジュールをキャッシュするので,ファイルを置き換えても古いものが使われることがあります.これが一番よくある原因です. 置き場所を確認する. os.listdir('/flash/lib') で config.py が見えるか確かめます. lib ディレクトリを作る前にアップロードして, /flash/ の直下に置かれてしまっているケースがよくあります. sys.path を確認する. import sys; print(sys.path) に /flash/lib が入っているか見ます.入っていなければ, /flash のマウントに失敗している可能性があります. ファイル名を確認する. from config import PINS で読めるのは config.py という名前のファイルだけです.別の名前で保存していないか確かめてください. ▲ 目次に戻る 5. 応用編:スイッチを読む 3章ではLEDを光らせました.GPIOの出力です.今度は反対に,入力を扱ってみます. FRDM-MCXN947には,ユーザーが自由に使えるスイッチが2つ載っています.SW2とSW3です.ここではSW2を使います. 図8:ユーザースイッチSW2とSW3の位置   この章に追加の部品は要りません.ボードとUSBケーブルだけで進められます. 5.1 スイッチの状態を読む SW2はP0_23に繋がっていて, config.py に SW2 として入れてあります. from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) print(sw.value()) Pin.IN で入力に設定し, Pin.PULL_UP で内部のプルアップ抵抗を有効にしています. なぜプルアップが必要なのか このスイッチは,押すとピンがGNDに繋がる回路になっています.逆に言えば,押していないときはピンがどこにも繋がっていません.この状態では電圧が定まらず,読み出す値が安定しません. プルアップ抵抗を有効にすると,押していないときはピンが電源側に引き上げられてHIGHになります.押したときだけGNDに引かれてLOWになります.これで両方の状態がはっきりします. つまり読み出される値は次のようになります. 押していない → 1 押している → 0 ここでも 0 が「押されている」です. LEDのときと同じアクティブ・ローの考え方で(3.5節),このボードではよく出てくる形です. 実行して確かめてみましょう. >>> print(sw.value()) 1 押していないので 1 が返りました.押しながら実行すれば 0 になります. 繰り返し読む場合 状態を監視し続けるなら,こうなります. import time from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) last = sw.value() while True: now = sw.value() if now != last: print("押された" if now == 0 else "離された") last = now time.sleep_ms(20) 前回の値と比べて,変化したときだけ表示しています.毎回表示すると,押している間ずっと出力され続けてしまうためです. この方法をポーリングと呼びます.仕組みは単純ですが,欠点もあります. sleep_ms(20) の間にスイッチが押されて離されると,見逃してしまいます.かといって間隔を短くすると,その分だけCPUがこの確認に費やされます. 5.2 押されたことを割り込みで知る そこで使えるのが割り込みです. 「ピンの状態が変化したら,この関数を呼んでほしい」と登録しておく方式で,ふだんは他の処理をしていられます.見逃しもありません. machine.Pin では irq() メソッドで登録します. import time from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) n = 0 def pressed(pin): global n n += 1 print(" 割り込み %d 回目 value=%d" % (n, pin.value())) sw.irq(handler=pressed, trigger=Pin.IRQ_FALLING) print("SW2を数回押してください(30秒間)") for i in range(30): time.sleep(1) sw.irq(handler=None) print("合計 %d 回検出しました" % n) 実行してSW2を10回押した結果です. SW2を数回押してください(30秒間) 割り込み 1 回目 value=0 割り込み 2 回目 value=0 割り込み 3 回目 value=0 (中略) 割り込み 10 回目 value=0 合計 10 回検出しました 押した回数だけ,きちんと呼ばれました. コードの読みかた trigger には,どの変化で呼んでほしいかを指定します. 指定 意味 Pin.IRQ_FALLING HIGH→LOW の変化(このボードでは「押した」) Pin.IRQ_RISING LOW→HIGH の変化(「離した」) `Pin.IRQ_FALLING \ Pin.IRQ_RISING` 両方 表4: irq() の trigger に指定できるもの ここでは押した瞬間だけ知りたいので Pin.IRQ_FALLING を指定しています. handler に渡す関数は,引数を1つ受け取るように書きます.呼ばれるときに,割り込みの起きた Pin オブジェクトが渡されるためです.上の例では pin.value() として,そのピンの値を読んでいます. global n が必要なのは,関数の外にある変数を書き換えるためです.これはPythonの一般的な決まりで,MicroPythonでも同じです. 最後の sw.irq(handler=None) で割り込みを解除しています.解除しないと,そのあともスイッチを押すたびにハンドラが呼ばれ続けます. ハンドラの中で print() してよいのか 割り込みハンドラの中では,時間のかかる処理やメモリを確保する処理を避けるのが原則です. print() はどちらにも当てはまるので,本来は避けたいところです. ただしMicroPythonの irq() には hard という引数があり,既定値は hard=False です.このとき,ハンドラは割り込みが起きた瞬間ではなく,少し後の安全なタイミングにまわして実行されます.そのため print() を書いても問題ありません. hard=True を指定すると,割り込みが起きた瞬間に実行されます.応答は速くなりますが, print() やメモリ確保はできなくなります.まずは既定のままで構いません. チャタリングについて 機械式のスイッチは,接点が触れる瞬間に細かくON/OFFを繰り返すことがあります.これをチャタリングと呼び,1回押しただけで割り込みが何度も入る原因になります. FRDM-MCXN947のSW2で試したかぎりでは,10回の押下に対して割り込みは10回で,チャタリングは観測されませんでした.ただしスイッチの個体や押しかたによっては起こりうるので,数が合わないときは,前回からの経過時間を見て短すぎるものを無視する,といった対策を入れてください. ▲ 目次に戻る 6. 応用編:I²Cを使ってみる GPIOの次はI²Cです.温度センサを読んでみましょう. 6.1 このボードのI²C事情 FRDM-MCXN947には P3T1755 という温度センサが載っています.I²CとI3Cの両方に対応した,分解能12ビット,±0.5℃精度のセンサです. ところが,これをMicroPythonからそのまま読むことはできません.理由は,このセンサがI3Cバスに接続されているからです. MCXN947のI3C1は,devicetree上で次のピンに割り当てられています. pinmux_i3c1: pinmux_i3c1 { group0 { pinmux = , ; ... }; }; つまり SDAがP1_16,SCLがP1_17 です. 一方で,MicroPythonのZephyrポートには I3Cのドライバがありません. machine モジュールにあるのは I2C だけで, I3C というクラスは存在しないのです.つまりMicroPythonからは,このセンサに手が届きません. しかしI3Cのターゲットデバイスは,I²CのコントローラからもI²Cデバイスとしてアクセスできる仕様になっています(レガシーI²Cモード).P3T1755もそうです.ということは,I3Cバスの信号線をI²Cコントローラに繋ぎ替えれば読めるはずです. ここで,先ほど config.py に書いたMikroBusのピン定義を思い出してください. "MIKROBUS_RX": ("gpio1", 16), # GPIOとして使える.UARTのRXではない "MIKROBUS_TX": ("gpio1", 17), # GPIOとして使える.UARTのTXではない P1_16とP1_17です.I3C1のSDA/SCLと,同じピンです. FRDM-MCXN947では,このI3Cの信号線がMikroBusコネクタのRX/TXピンにも引き出されています(devicetreeでは「GPIO, Not a RX」というコメント付きで,GPIOとして扱えることが示されています).つまり,MikroBusコネクタのRX/TXピンに,P3T1755がぶら下がっているわけです. コネクタに出ているのなら,ジャンパ線で他のバスに繋げます. 6.2 ジャンパを2本つなぐ 繋ぎ先は,ArduinoヘッダーのI²C( flexcomm2_lpi2c2 )にします.4.2節で強調したとおり,このバスが出ているのはAREFの隣にある専用のSDA/SCLピンです.A4/A5ではありません. 配線は次のようになります. 接続元(MikroBusコネクタ) 信号 接続先(Arduinoヘッダー) 信号 RX (P1_16) I3C1_SDA SDA (P4_0) LPI2C2 SDA TX (P1_17) I3C1_SCL SCL (P4_1) LPI2C2 SCL 表5:ジャンパ配線 図9:ジャンパ線の接続 注意点 SDAとSCLを取り違えないでください. 逆に繋ぐと,当然ながら通信できません.MikroBus側はRXがSDA,TXがSCLです.名前から想像すると間違えやすいので気をつけてください. プルアップ抵抗:I²Cはオープンドレインなので,本来はプルアップ抵抗が必要です.ただし筆者の環境では,外付けの抵抗なしで通信できました.I3C1側のピンにはdevicetreeで bias-pull-up が指定されていて,内部プルアップが有効になるためです.もし通信できない場合は,4.7kΩ程度の抵抗をSDA/SCLそれぞれと3.3Vの間に入れてみてください. A4/A5に繋がないでください. このボードのA4/A5はI²Cバスではありません. 6.3 バスをスキャンする 配線ができたら,まずバス上に何が見えるかを確認します. I2C.scan() は,7ビットアドレスの範囲(0x08〜0x77)に順番に問い合わせを出して,応答(ACK)を返したアドレスの一覧を返します. REPLで直接試してみましょう. >>> from machine import I2C >>> from config import PINS >>> i2c = I2C(PINS["I2C"]) >>> [hex(a) for a in i2c.scan()] ['0x48'] 0x48 が見つかりました.これがP3T1755です. freq= は指定できません 他のポートのMicroPythonでは I2C(id, freq=400_000) のようにクロック周波数を指定できますが,Zephyrポートでは例外になります. >>> i2c = I2C(PINS["I2C"], freq=100_000) Traceback (most recent call last): File " ", line 1, in NotImplementedError: explicit choice of freq is not implemented scl / sda / timeout も同様に指定できません.これらはすべてdevicetreeで決まる値だからです.FRDM-MCXN947のI²Cは,devicetreeで clock-frequency = ,つまり100kHzに設定されています.速度を変えたい場合はdevicetree(またはoverlay)を書き換えて,ファームウェアをビルドし直すことになります. 何も見つからないときは 空のリスト [] が返る場合は,次を確認してください. ジャンパ線がきちんと刺さっているか(半挿しになっていないか) SDAとSCLが逆になっていないか ボードの電源が入っているか(当たり前ですが,USBが抜けかけていることがあります) プルアップ抵抗が効いているか ロジックアナライザやオシロスコープがあれば,SCLにクロックが出ているかを見るのが一番確実です. scan() は相手がいなくても波形自体は出るので,「クロックが出ていない」のか「クロックは出ているが応答がない」のかを切り分けられます. I²Cの信号の見かたやトラブルシューティングについては,10章に挙げたI²C関連のブログを参照してください. 6.4 温度を読む P3T1755のレジスタ構成は,古くからあるLM75というセンサと互換です.温度を読む手順は次のようになります. ポインタレジスタに 0x00 (温度レジスタ)を書く 2バイト読む 読んだ2バイトは16ビットの値ですが,有効なのは上位12ビットです.下位4ビットは常に0です.上位12ビットは2の補数の符号付き整数で,1LSBが 0.0625℃ に対応します. コードにするとこうなります. import time from machine import I2C from config import PINS ADDR = 0x48 # P3T1755のI2Cアドレス REG_TEMP = 0x00 # 温度レジスタ def read_temperature(i2c, addr=ADDR): """P3T1755から温度を読んで摂氏で返す.""" i2c.writeto(addr, bytes([REG_TEMP])) # ポインタレジスタを指定 data = i2c.readfrom(addr, 2) # 2バイト読む raw = (data[0] << 8) | data[1] # 16ビットに合成 raw >>= 4 # 有効なのは上位12ビット if raw & 0x800: # 12ビットの符号を展開 raw -= 0x1000 return raw * 0.0625 # 1LSB = 0.0625℃ i2c = I2C(PINS["I2C"]) print("found:", [hex(a) for a in i2c.scan()]) while True: print("{:.4f} degC".format(read_temperature(i2c))) time.sleep(1) 実行すると,1秒ごとに温度が表示されます. found: ['0x48'] 25.5000 degC 25.5625 degC 25.5000 degC ... センサに指で触れると,値が上がっていくのがわかります.0.0625℃刻みなので,指を近づけただけでも動きが見えるはずです. コードの補足 raw >>= 4 の部分がわかりにくいかもしれません.P3T1755が返す2バイトは,次のようなビット配置になっています. 図10:温度レジスタのビット配置   12ビットのデータが左詰め(MSB側に寄せて)格納されているので,4ビット右にシフトして右詰めに直しています. 符号の展開( if raw & 0x800 )は,氷点下を正しく扱うために必要です.12ビットの2の補数では,最上位のビット11が1なら負の数です.Pythonの整数は桁数の制限がないので,「12ビットの負数」を「Pythonの負数」に直すために 0x1000 を引いています.0℃以上しか測らないなら省略しても動きますが,入れておくのが安全です. MikroBus側のI²Cを使う場合 同じセンサをMikroBusのI²C( flexcomm3_lpi2c3 )から読むこともできます.その場合はジャンパの接続先をMikroBusコネクタのSDA(P1_0)/SCL(P1_1)にして,コードの PINS["I2C"] を PINS["MIKROBUS_I2C"] に変えるだけです. i2c = I2C(PINS["MIKROBUS_I2C"]) 同じMikroBusコネクタの中で,RX/TXからSCL/SDAへジャンパを渡す形になるので,配線は短くて済みます. ▲ 目次に戻る 7. 応用編:SPIを使ってみる 最後にSPIです. 7.1 ループバックで試す I²Cと違って,FRDM-MCXN947にはSPIで繋がったデバイスが載っていません.そこで ループバックで試します. ループバックというのは,MOSI(送信)とMISO(受信)を直結してしまう方法です.自分が送ったデータがそのまま自分に返ってくるので,外部にデバイスがなくてもSPIが正しく動いているかを確認できます. ArduinoヘッダーのSPI( flexcomm1_lpspi1 )は,次のピンに出ています. 信号 Arduinoヘッダー ピン タプル CS D10 P0_27 ("gpio0", 27) MOSI D11 P0_24 ("gpio0", 24) MISO D12 P0_26 ("gpio0", 26) SCK D13 P0_25 ("gpio0", 25) 表6:Arduino SPIのピン割り当て D11(MOSI)とD12(MISO)をジャンパ線で繋いでください. 図11:MOSIとMISOを直結してループバックにする   from machine import Pin, SPI from config import PINS spi = SPI(PINS["SPI"], baudrate=1_000_000, polarity=0, phase=0) tx = bytes([0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08]) rx = bytearray(len(tx)) spi.write_readinto(tx, rx) print("送信:", [hex(b) for b in tx]) print("受信:", [hex(b) for b in rx]) print("一致:", tx == bytes(rx)) 実行結果はこうなります. 送信: ['0x0', '0xff', '0xaa', '0x55', '0x1', '0x2', '0x4', '0x8'] 受信: ['0x0', '0xff', '0xaa', '0x55', '0x1', '0x2', '0x4', '0x8'] 一致: True 送ったデータがそのまま返ってきました.SPIが正しく動作しています. ジャンパ線を外して実行すると,受信データは変わります.MISOがどこにも繋がっていない状態(ハイインピーダンス)になるので, 0x00 ばかりになったり,不定の値が返ったりします.これも「繋がっていないこと」が確認できたということなので,試してみてください. 送るデータの選び方 0x00 , 0xFF , 0xAA , 0x55 ,そして 0x01 〜 0x08 という並びには理由があります. 0x00 / 0xFF :全ビット0と全ビット1.線が固定されていないかを見る 0xAA / 0x55 : 10101010 と 01010101 .ビットごとに切り替わるので,タイミングの余裕を見るのに向く 0x01 , 0x02 , 0x04 , 0x08 …:1のビットを1つずつずらしていく.ビット順(MSBファーストかLSBファーストか)の確認ができる ロジックアナライザで波形を見るときにも,この並びは判別しやすくて便利です. SPIのモード polarity と phase はSPIのモードを決めるパラメータです. モード polarity (CPOL) phase (CPHA) 0 0 0 1 0 1 2 1 0 3 1 1 表7:SPIのモード ループバックでは自分が送ったものを自分で受けるだけなので,どのモードでも一致します.実際のデバイスに繋ぐときは,そのデバイスのデータシートに合わせてください. なお,I²Cと違ってSPIでは baudrate が指定できます. 7.2 CSは自動制御されない ループバックでは使いませんでしたが,実際のSPIデバイスを繋ぐときにはCS(チップセレクト) が必要になります. ここで,このポート特有の注意点があります. MicroPython ZephyrポートのSPIドライバは,CSを自動制御しません. 多くのMicroPythonのポートでは, SPI オブジェクトにCSピンを渡しておくと,転送のたびに自動でCSをLOWにして,終わったらHIGHに戻してくれます.しかしZephyrポートの実装では,内部でZephyrに渡すSPI設定のCS指定が空になっています. したがって,CSは machine.Pin で自分で制御する必要があります. import time from machine import Pin, SPI from config import PINS cs = Pin(PINS["D10"], Pin.OUT, value=1) # アイドル時はHIGH spi = SPI(PINS["SPI"], baudrate=1_000_000, polarity=0, phase=0) data = bytes([0x9F]) # 例:何かのコマンド rx = bytearray(3) cs.value(0) # CSをアサート(LOW) spi.write(data) spi.readinto(rx) cs.value(1) # CSをデアサート(HIGH) print([hex(b) for b in rx]) CSはアクティブ・ローなのが一般的です. value(0) で選択, value(1) で非選択になります.LEDのときと同じで, 0 が「有効」です. CSを戻し忘れないよう注意してください. LOWのままにすると,次の転送でデバイスが混乱します.転送のたびに cs.value(0) と cs.value(1) を対で書く,と覚えておくのが確実です. MikroBusのSPIを使う場合 MikroBusコネクタのSPI( flexcomm6_lpspi6 )も同じように使えます.これが今回のマージで新しく使えるようになったものです. cs = Pin(PINS["MIKROBUS_CS"], Pin.OUT, value=1) spi = SPI(PINS["MIKROBUS_SPI"], baudrate=1_000_000, polarity=0, phase=0) MikroBusには豊富な種類のClick boardが用意されているので,そちらを繋いで試すのも面白いと思います. ▲ 目次に戻る 8. 応用編:Ethernetを使ってみる 最後にEthernetです. 8.1 有線LANという強み 冒頭でも少し触れましたが,有線のEthernetを持っていることはこのボードの明確な強みです.ここで,その理由を具体的に見ておきます. 電波を使わないので,無線が禁止・制限される場所でも使えます 遅延が安定しているため,決まった周期で応答してほしい用途に向きます 配線した相手としか通信しないので,どこと通信しているかがはっきりします 工場やビル設備など,すでに有線のネットワークが敷かれている環境にそのまま入れます MCXN947のEthernetコントローラ(ENET QoS)はZephyrのドライバでサポートされていて,MicroPythonからは socket モジュールを通して使えます. 8.2 このポートのネットワークAPI 先に,できることとできないことをはっきりさせておきます.ここを知らずに始めると確実に戸惑います. 使えるのは socket モジュールだけです. >>> import socket >>> import network Traceback (most recent call last): File " ", line 1, in ImportError: no module named 'network' ここは,同じNXPのマイコン向けであるi.MX RTの専用ポート( ports/mimxrt )と比べるとわかりやすいと思います.あちらではEthernetを次のように扱えます. import network lan = network.LAN(0) lan.active(True) DHCPサーバがあればアドレスはそこから配られ,無ければ lan.ipconfig(addr4="...") で実行時に設定できます.インターフェースを有効にするのも無効にするのも lan.active() ひとつです. Zephyrポートには,この network モジュールがありません. network.LAN() も ifconfig() も存在せず,IPアドレスの設定や確認をするための専用APIが無い,ということです.アドレスはビルド時のKconfigで決まります(後述). socket オブジェクトが持つメソッドも,一般的なMicroPythonより少なめです. 使えるもの 使えないもの bind / listen / accept / connect getsockname() send / recv / recvfrom / sendto getpeername() read / write / readline / makefile settimeout() setsockopt / close   表8:Zephyrポートの socket で使えるもの・使えないもの 特に効いてくるのが次の3点です. getsockname() が無いので,自分のIPアドレスを直接は表示できません(8.4節で回避策を示します) settimeout() が無いので,通信待ちのブロックから抜ける手段がありません(8.8節で詳しく述べます) accept() が返す接続元アドレスは常に None です.ポートのソースにコメントで // TODO と書かれている,未実装の部分です IPアドレスはビルド時に決まります もうひとつ大きな制約があります.このポートには,実行時にIPアドレスを設定する手段がありません.アドレスはZephyrのKconfigで,ファームウェアをビルドするときに決まります. ports/zephyr/prj.conf の既定値は次のようになっています. CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0" CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" CONFIG_NET_DHCPV4=y DHCPも有効になっているので,DHCPサーバのあるネットワークに繋げばそちらからアドレスが割り当てられます.DHCPサーバがいない環境では,上の静的アドレス 192.0.2.1 が使われます. なお 192.0.2.x は,RFC 5737で文書の例示用に予約されたアドレスです.Zephyrのサンプル設定がそのまま入っているだけなので,実際の運用では自分のネットワークに合わせた値に変更することになります.変更する場合はボードの .conf に上書きの設定を書いて,ビルドし直してください. 8.3 PCと直結して試す DHCPサーバのあるLANに繋いでもいいのですが,その場合ボードがどのアドレスをもらったのかを知るのが面倒です( getsockname() が無いため). そこでここでは,ボードとPCをLANケーブルで直結して試します.この構成ならボードのアドレスは静的設定の 192.0.2.1 に決まるので確実です. (下の写真では「直結」と言ってもコンピュータにEthernetポートが無いのでUSB Type-CとEthernetの変換アダプタを介して接続しています.この接続でもEthernet接続は1対1の直結接続となります)   図12:ボードとPCを直結する(※ このコンピュータの場合,EthernetポートがないのでUSB Type-Cとの変換器を使って接続した) PC側の設定 PCのEthernetインターフェースを,ボードと同じサブネットにします. 項目 値 IPアドレス 192.0.2.2 サブネットマスク 255.255.255.0 デフォルトゲートウェイ 空欄でよい 表9:PC側のネットワーク設定 192.0.2.2 はボードがゲートウェイとして設定しているアドレスなので,これに合わせておくと都合がいいです. 最近のPCとボードはAuto MDI/MDI-Xに対応しているので,クロスケーブルでなくストレートケーブルで構いません. まずpingで確かめる MicroPythonを触る前に,PCからpingを打つのが確実です.ZephyrのIPスタックはMicroPythonとは別のスレッドで動いているので,REPLに何も入力しなくてもpingには応答します. ping 192.0.2.1 PING 192.0.2.1 (192.0.2.1): 56 data bytes 64 bytes from 192.0.2.1: icmp_seq=0 ttl=64 time=1.088 ms 64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.657 ms 64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=1.938 ms --- 192.0.2.1 ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss これが通れば,PHYのリンク・Ethernetドライバ・IPスタックまで動いていることになります.ここが通らないうちにMicroPythonのコードを書いても意味がないので,先に確認してください. 通らない場合は,ケーブル,PC側のIP設定,ボードの電源を順に確認します. 8.4 自分のIPアドレスを調べる getsockname() が無いので,ボードに「あなたのIPアドレスは?」と直接は聞けません. 代わりに使えるのが bind() の成否です.自分が持っていないアドレスに bind() しようとすると失敗するので,候補を順に試せば,どれを持っているかがわかります. import socket for ip in ("0.0.0.0", "192.0.2.1", "192.168.1.1"): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((ip, 9999)) print(" bind OK ->", ip) except Exception as e: print(" bind NG ->", ip, type(e).__name__, e) s.close() 実行するとこうなります. bind OK -> 0.0.0.0 bind OK -> 192.0.2.1 bind NG -> 192.168.1.1 OSError [Errno 2] ENOENT 0.0.0.0 はどの環境でも通る特別なアドレスなので判定には使えません.ここでは 192.0.2.1 だけが成功したので,ボードは静的設定のアドレスを使っているとわかります.DHCPでアドレスをもらっていれば,ここは別の値になります. DHCPを使う場合は,そもそも候補を挙げること自体が難しくなります.その場合は,ルータのDHCPリース一覧を見るのが確実です.「どの機器にどのアドレスを貸したか」の一覧が見られるので,そこからボードのアドレスを拾ってください. 8.5 ボードをWebサーバにする ここまでで疎通は確認できました.最後に,ボードをWebサーバにしてみます.PC側に用意するものはブラウザだけです. import socket srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(("0.0.0.0", 8080)) srv.listen(1) print("listen 0.0.0.0:8080 接続待ち...") cl, addr = srv.accept() # addr は常に None print("接続あり:", addr) req = cl.recv(256) print("リクエスト先頭:", req.split(b"\r\n")[0]) body = " FRDM-MCXN947 MicroPython on Zephyr " cl.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" + body) cl.close() srv.close() bind() に "0.0.0.0" を渡しているのは,「このボードが持っているすべてのアドレスで待ち受ける」という意味です.アドレスを決め打ちしなくて済むので,DHCPでも直結でもそのまま動きます. 実行するとボード側はこう表示して,接続を待ちます. listen 0.0.0.0:8080 接続待ち... この状態でPCのブラウザから http://192.0.2.1:8080/ を開いてください. 図13:ブラウザからボードにアクセスする   ボード側にはリクエストが表示されます. 接続あり: None リクエスト先頭: b'GET / HTTP/1.1' 接続あり: None となっているのが,7.2節で触れた accept() の未実装部分です.接続自体はできていて,通信にも支障はありません. 数十行のPythonで,マイコンがWebサーバになりました.ここから,センサの値をHTMLに埋め込んで返すようにすれば,6章の温度センサをブラウザから読める温度計になります. 8.6 LEDをブラウザから操作する 前節のサーバは,決まったページを1回返して終わりでした.今度はブラウザからボードのLEDを操作できるようにしてみます. 3章で光らせた赤色LEDを, /on と /off というURLで切り替えます. import socket from machine import Pin from config import PINS led = Pin(PINS["LED_RED"], Pin.OUT, value=1) # 1 = 消灯 srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(("0.0.0.0", 8080)) srv.listen(1) print("http://192.0.2.1:8080/ を開いてください") running = True while running: cl, _ = srv.accept() try: req = cl.recv(256) path = req.split(b" ")[1] if b" " in req else b"/" if path == b"/on": led.value(0) # アクティブ・ロー: 0で点灯 elif path == b"/off": led.value(1) elif path == b"/quit": running = False state = "ON" if led.value() == 0 else "OFF" cl.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n" "Connection: close\r\n\r\n" " FRDM-MCXN947 " " RED LED: %s " " ON / OFF " "" % state) except OSError as e: print("接続エラー(無視):", e) # 後述.握りつぶして継続する try: cl.close() except OSError: pass srv.close() print("サーバを終了しました") 前節が14行,こちらが38行です. ブラウザで http://192.0.2.1:8080/ を開くと,「ON」「OFF」のリンクが並んだページが出ます.クリックするたびに,ボードの赤色LEDが実際に点いたり消えたりします. 図14:ブラウザからボードのLEDを操作する http://192.0.2.1:8080/quit を開けばサーバが終わり,REPLに戻ります. ここまで動けば成功です.コードの中身と, try / except を入れてある理由については付録にまとめました. 8.7 電源を入れるだけで動くようにする ここまでは,PCからスクリプトを実行していました.最後に,PCを繋がずに電源だけで動くようにしてみます. MicroPythonは起動時に, /flash にある次のファイルを順に探して,あれば自動的に実行します. _boot.py … ファイルシステムのマウントなど(ファームウェアに内蔵,変更不可) boot.py … あれば実行される(起動時の設定用) main.py … あれば実行される(アプリケーション用) つまり /flash/main.py として保存したスクリプトは,電源を入れるだけで動きます. 7.6節のLED操作サーバを main.py として保存してみてください.Thonnyなら,エディタで開いた状態で「ファイル」→「名前を付けて保存」を選び,保存先に「MicroPythonデバイス」を選んで main.py という名前にします. mpremote なら次のとおりです. mpremote cp led_server.py :/flash/main.py 保存したらUSBケーブルを抜き,ACアダプタやモバイルバッテリーなど,電源だけを繋いでください.LANケーブルは繋いだままにします. しばらく待ってからPCのブラウザで http://192.0.2.1:8080/ を開くと,PCと繋がっていないボードのLEDが,ブラウザから操作できます. 数十行のPythonを書いて main.py という名前で置いただけで,ネットワーク越しに操作できる機器になりました. 必ず「抜け道」を用意してから保存してください ここで重要な注意があります. main.py は起動のたびに実行されます.もしその中身が accept() で待ち続けるサーバだと,REPLは永久に戻ってきません.8.8節で述べるとおり,このポートには settimeout() が無く,Ctrl-Cでも抜けられないからです. しかもREPLに入れないということは,その main.py を消すこともできないという状態になります. 7.6節のコードに /quit を入れてあるのは,このためです.ブラウザで http://192.0.2.1:8080/quit を開けばスクリプトが終了し,REPLが戻ってきます.ネットワーク経由の非常口というわけです. main.py を作るときは,次の順序を守ってください. まず普通のスクリプトとして実行し,期待どおり動くことを確認する 終了する手段があることを確認する( /quit など) それから main.py として保存する いきなり main.py に書いて試すのは避けてください. 8.8 ハマりやすい点 settimeout() が無いので,ブロックすると戻ってきません これが一番の注意点です. accept() や recv() は,相手が来るまで待ち続けます.通常のMicroPythonなら settimeout() で待ち時間の上限を決められますが,このポートには実装されていません. さらに,これらはC言語のレベルで待ちに入るため Ctrl-Cが効きません.一度この状態になると,REPLは入力を受け付けなくなります. 筆者はこの状態から復帰するのに,ボードの電源を入れ直す必要がありました.リセットボタンでも戻らないことがあります. 対策としては, accept() を実行したら,すぐに接続しに行く(ブラウザのアドレス欄にURLを入れておき,実行後すぐ開けるようにしておく) 繰り返し受け付けるサーバには,8.6節の /quit のような抜け道を必ず用意しておく 動作を確認するまでは main.py に置かない(8.7節.起動のたびに固まり,REPLに入れないので消すこともできなくなります) エラーで止まったあとは EADDRINUSE になります サーバのプログラムが途中でエラー終了すると,待ち受けに使っていたソケットが閉じられないまま残ります.その状態でもう一度実行すると,こうなります. Traceback (most recent call last): File " ", line 10, in __main__ OSError: [Errno 112] EADDRINUSE 「そのアドレスとポートはもう使われている」という意味です. SO_REUSEADDR を指定していても,前のソケットが本当に開いたままなら効きません. Ctrl-D でソフトリセットすれば,MicroPythonが再起動してソケットがすべて解放されます.サーバを書いて試しているときは,エラーが出たらまずCtrl-Dを押す,と覚えておくと楽です. ネットワークはREPLが止まっていても動いています これは知っておくと切り分けが楽になります.ZephyrのIPスタックはMicroPythonとは別のスレッドで動いているので,MicroPythonが固まっていてもpingには応答します. つまり「pingは通るのにREPLが無反応」という状況は,Ethernetの故障ではなくMicroPythonがブロックしていることを示しています.逆に「pingも通らない」ならケーブルや設定を疑う,という切り分けができます. DNSは環境次第です socket.getaddrinfo() で名前解決もできますが,DNSサーバのアドレスは CONFIG_DNS_SERVER1 の既定値が 192.0.2.2 になっています.DHCP環境ならDHCPから配られたDNSサーバが使われます.直結の構成では名前解決はできないので,IPアドレスを直接指定してください. ▲ 目次に戻る 9. まとめ FRDM-MCXN947でMicroPythonを動かすまでの一通りを見てきました.最後に要点を整理します. 今回のマージで得られたもの 本家 micropython/micropython のmasterにFRDM-MCXN947の設定が入ったことで,パッチをあてずに本家のソースからそのままビルドできるようになりました.オンボードのQSPIフラッシュが /flash として使え,I²C・SPI(ArduinoヘッダーとMikroBusの両方)が動きます. 有線Ethernetが使えること MicroPythonが動く安価なボードの多くは無線でネットワークに繋ぎますが,このボードは有線のEthernetを持っています.電波を使えない場所や,遅延を安定させたい用途では代えがききません.本記事ではpingでの疎通確認から,ボードをWebサーバにしてブラウザから見るところまでを実機で確認しました. Zephyrポートの弱点と,その対策 ピンを ("gpio0", 10) のようなタプルで指定しなければならない点が,このポートの一番の使いにくさです.これは config.py に PINS 辞書を用意して /flash/lib/ に置くことで,実用上ほぼ解消できます.名前で書けるようになるだけでなく,タイプミスが KeyError で検出できるようになるという副次的な効果もあります. 引っかかりやすいポイント ボード設定ファイルの名前は,ボード修飾子込みの frdm_mcxn947_mcxn947_cpu0.conf でないと読まれない cloneしたあとに git submodule update --init lib/micropython-lib が必要 RGB LEDはアクティブ・ロー. value(0) で点灯する( off() を呼ぶと光る) Pin に toggle() はない スイッチ入力は Pin.IN, Pin.PULL_UP で構成する.押すと 0 (LEDと同じアクティブ・ロー) Pin.irq() が使える.既定は hard=False なのでハンドラ内で print() してよい このボードのArduinoヘッダーのI²Cは,A4/A5ではなく専用のSDA/SCLピン(P4_0/P4_1) machine.I2C に freq= / scl= / sda= / timeout= は指定できない(devicetreeで決まる) SPIのCSは自動制御されないので, machine.Pin で手動制御する オンボードのP3T1755はI3Cバスに繋がっていて,MicroPythonにはI3Cドライバがないため,ジャンパでI²Cバスに引き込む必要がある os.uname() はこのポートでは組み込まれていない ネットワークは socket のみ. network モジュールは無い socket に getsockname() が無いので,自分のIPは bind() の成否で調べる socket に settimeout() が無い. accept() や recv() でブロックするとCtrl-Cでも抜けられず,電源の入れ直しが必要になることがある accept() が返す接続元アドレスは常に None accept() は失敗しても例外を投げない.無効なソケットが返り,次の recv() が EBADF になるので, try / except OSError で囲む サーバがエラー終了するとポートが掴まれたままになる.Ctrl-Dで解放する IPアドレスは実行時に変更できない.Kconfigで決まるのでビルドし直す このビルドでは input() が使えない(機能レベルが BASIC_FEATURES のため.対話待ちが必要なときは time.sleep() によるカウントダウンで代用します) MicroPythonは「動くものを早く作る」ことにかけては非常に強力です.FRDM-MCXN947のような高性能なマイコンでも,まずはMicroPythonで動かして感触をつかんでから本番の実装をCで書く,という進め方は十分に現実的だと思います. ぜひ試してみてください. ▲ 目次に戻る 10. 参考資料 MicroPython MicroPython 公式サイト MicroPython ドキュメント MicroPython GitHub リポジトリ MicroPython Zephyrポートのreadme 今回マージされたPull Request (#19573) Zephyr Zephyr Project 公式サイト Zephyr Getting Started Guide Zephyr FRDM-MCXN947 ボードドキュメント Zephyr シリーズ 第2回 はじめてのビルドと実機動作 (日本語ブログ) ツール Thonny 公式サイト Thonnyのインストールと基本操作 (YouTube) mpremote ドキュメント ハードウェア FRDM-MCXN947 製品ページ MCX Nシリーズ 製品ページ P3T1755 製品ページ バス NXPコミュニティ・ブログ:I²Cバスの概要 (日本語ブログ) NXPコミュニティ・ブログ:SPIバスの概要 (日本語ブログ) NXPコミュニティ・ブログ:I3Cバスの概要 次のシリアルバス (日本語ブログ) NXPコミュニティ・ブログ:I²Cハードウェア・デバッグ (日本語ブログ) ▲ 目次に戻る 11. 付録:LED操作サーバのコード解説 8.6節のコードについて,中身の説明をここにまとめました.本文の流れを止めたくないので分けてあります.動かすだけなら読まなくても構いません. 11.1 ここまでの内容が1つにまとまっている このコードは短いわりに,この記事で扱ってきたことをほとんど使っています. from config import PINS — 4章で作ってボードに置いたピン定義 Pin(PINS["LED_RED"], ...) — 3章のLED. value(0) で点灯するのは3.5節で説明したアクティブ・ローだからです socket — 7章のネットワーク 11.2 コードの3つの仕掛け (1) while True で繰り返し受け付ける 8.5節のサーバは1回で終わりでしたが,操作を続けるには繰り返しが要ります.ただしこれには代償があります. accept() で待ち続けるループになるので,8.8節で述べたブロックの問題がずっと続く状態になります. そこで /quit を用意しました. elif path == b"/quit": running = False ブラウザで http://192.0.2.1:8080/quit を開くと,最後の応答を返してからループを抜け,REPLが戻ってきます.たった2行ですが,これが無いとプログラムを止める手段が電源の入れ直ししかなくなります.繰り返し受け付けるサーバを書くときは,必ず抜け道を用意しておくことをおすすめします. (2) リクエストからパスを取り出す ブラウザは,接続すると次のような文字列を送ってきます. GET /on HTTP/1.1 Host: 192.0.2.1:8080 ... このうち必要なのは真ん中の /on の部分だけです.空白で区切って2つ目を取れば済みます. path = cl.recv(256).split(b" ")[1] b" " のように b が付いているのは,通信で受け取るのが文字列ではなくバイト列だからです.比較する側も b"/on" と書く必要があります. (3) 現在の状態をページに反映する led.value() を引数なしで呼ぶと,いまの出力値が読めます.アクティブ・ローなので 0 が点灯です. state = "ON" if led.value() == 0 else "OFF" これで,ページを開き直すたびに現在の状態が表示されます. 11.3 例外処理が必要な理由 素直に書くと, try / except を省いて次のようにしたくなります. cl, _ = srv.accept() path = cl.recv(256).split(b" ")[1] # ← ここで落ちることがある ところがこう書くと,ブラウザで操作を繰り返すうちに必ず次のエラーで止まります. Traceback (most recent call last): File " ", line 16, in OSError: [Errno 9] EBADF EBADF は「無効なファイル記述子」という意味です. accept() が返してきたソケットが,そもそも使える状態になっていません. 原因はこのポートの実装にあります. ports/zephyr/modsocket.c の accept は,こうなっています. int ctx = zsock_accept(socket->ctx, &sockaddr, &addrlen); socket_obj_t *socket2 = socket_new(); socket2->ctx = ctx; /* エラーチェックが無い */ 同じファイルの他の関数は RAISE_SOCK_ERRNO(res) で戻り値を検査しているのに, accept だけが検査をしていません. zsock_accept() が失敗して -1 を返しても,それをそのままソケットの中身として持ち帰ってしまいます.その結果,次の recv() が EBADF になる,という流れです. ではなぜ accept() が失敗するのか.Zephyrが同時に扱えるネットワーク接続の数に上限があるためです. CONFIG_NET_MAX_CONTEXTS=6 CONFIG_NET_TCP_TIME_WAIT_DELAY=1500 同時に使える通信の枠が6個しかなく,しかも閉じた接続も1.5秒間は枠を占有し続けます(TCPの TIME_WAIT という状態です).ブラウザはページ本体のほかに /favicon.ico なども取りに来るので,続けてクリックしていると,あっという間に6個を使い切ります. そこで,例外が出ても握りつぶして次の接続を待つようにしてあります.これで,たまに応答が返らないことがあっても,サーバは動き続けます. except OSError as e: print("接続エラー(無視):", e) cl.close() も try で囲んであるのは,壊れたソケットを閉じようとして,そこでまた例外が出るのを防ぐためです. 実際にどのくらい失敗するのか 筆者の環境で測ってみました. 操作のペース 成功 / 試行 間隔をあけずに連打 32 / 40 1秒間隔 15 / 15 2秒間隔 10 / 10 表10:クリックの速さと応答の取りこぼし 人がブラウザをクリックする程度の速さであれば,取りこぼしは起きません.連打すると一部が応答しなくなりますが,例外処理を入れてあるのでサーバが止まることはありません.再度クリックすれば普通に反応します. 11.4 Connection: close について これは「この応答を返したら接続を切ってください」とブラウザに伝えるものです.ブラウザは既定では接続を使い回そうとしますが,そうすると上で述べた6個の枠を長く占有してしまいます.明示的に切ってもらうことで,枠の解放を早めています. 11.5 そのほか気をつける点 ページの文字はASCIIにしてあります.日本語を入れる場合は Content-Type: text/html; charset=utf-8 としてください req.split(b" ")[1] if b" " in req else b"/" としているのは, recv() が空を返したときに IndexError で落ちないようにするためです Connection: close を返している理由も付録で説明します 11.6 この挙動は将来変わるかもしれません accept() のエラーチェックが無い点は,本家に報告すれば修正されうる部分です.修正されれば accept() が正しく例外を投げるようになるので, try / except の書き方も素直になります.ここに書いた内容は,2026年8月時点のものとしてお読みください. ここまで来れば,あとは応用です. led を3色それぞれに増やせばRGBの操作盤になりますし,6章の温度センサの値をページに埋め込めば,ブラウザから読める温度計になります. ▲ 目次に戻る 変更履歴:2026-09-02:初版 ========================= 本投稿の「Comment」欄にコメントをいただいても、現在返信に対応しておりません。お手数をおかけしますが、お問い合わせの際には「NXPへの技術質問 - 問い合わせ方法 (日本語ブログ)」をご参照ください。(既に弊社NXP代理店、もしくはNXPとお付き合いのある方は、直接担当者へご質問いただいてもかまいません。) MicroPythonの本家リポジトリ,そのZephyrポートに,FRDM-MCXN947向けの設定がマージされました.これまでNXPのマイコンでMicroPythonを使う選択肢は事実上 i.MX RT シリーズに限られていましたが,そこに,より小規模で手を出しやすい MCX N シリーズが加わったことになります. この記事では,ファームウェアのビルドと書き込みから始めて,REPLでの対話操作,Lチカ,スイッチ入力と割り込み,I²Cでの温度センサ読み出し,SPI,そして有線EthernetでボードをWebサーバにしてブラウザから LED を操作するところまでを,順を追って解説します.掲載したコードはすべて実機で動作を確認したものです. 「MicroPythonを触るのは初めて」という方を想定し,途中でつまずきやすい点や,このポート固有の制約とその回避策も含めて書きました. MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947 Ethernet Interface introduction MCX 日本語ブログ Re: FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) 这篇文章值得付费阅读,非常有趣。 Re: FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) 谢谢
記事全体を表示
FRDM-MCXN947でMicroPythonを动かす (日本语ブログ) MicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, Zephyr MicroPython 's main family R&D , Zephyr's Zephyr , FRDM-MCXN947's FRDM-MCXN947 setting. Zephyr ポートというのは, MicroPython をZephyr RTOSの上でかす transplanted version です. MicroPython is usually used in microPython. "(Ported version) を志ちますが, MCX シリーズに専用ポートはありません.その代わり, Zephyr が対応しているボードなら动かせるこの士组みを使います (Detailed しくはSection 1.3 ). ビルド自体は, これまでもできました.ただしボード inherent setting が无かったため, come out on がるのはminimum limitのMicroPythonで,スクリプトをSaveするファイルシステムも无く,I²CもSPIも使えませんでした. This time, the first step is to make the first step. これでNXPのマイコンでMicroPythonをmake the selection択limbが広がりました.これまでは事実上,上上のクロスオーバーMCUであるi.MX RTシリーズにlimited られていましたが,そこにMCX Nシリーズという,より小scaleで手を出しやすい选択limbがplusわったことになります. このボードにWired のEthernetが load っている点も见狠せません. MicroPython が安価なボードの多くは, Wi-Fi やBluetooth でネットワークにつなぎます. The purpose is the same as the radio wave, the wired one is the wired one, the scene is the same.この记事の后halfでは,ボードをWebサーバにしてブラウザからLEDをoperationするところまで动かします. On one side, the restriction is on one side. Zephyr ポートは, チップ専用のポートに比べると Function がtwisting られます.たとえば同じNXPのマイコンでも, i.MX RTけの ports/mimxrt には network.LAN() があってIPアドレスを実行时にSETできますが, Zephyrポートには network モジュール自体がありません. Make the えるのは socket だけで, IP アドレスはビルド时にしかdetermine められません.この记事では, そうした restricts と, 実记にぶつかったproblem のevasion strategy も有めて书いています( section 8.2にorganizing しました). Since then, MicroPython has begun, and MicroPython has begun ,LED を光らせ,スイッチを読み,I²CやSPIのデバイスを动かし, the last にEthernet をmake うところまでを一通り Explain します. 「MicroPythonをtouchるのは初めて」という方を思定して, on the way, the hand is smooth and the way is omitted.せずに书きました. この记事の読み方 It’s a long story, it’s a long story, it’s a must. Zephyr's open environment environment → Section 2.1から すでにビルドと书き込みが済んでいる方→ Chapter 3から How to do it first? → Section 8.6 (Example of how to operate an LED) Chapter ごとにNecessaryなものは时のとおりです. Chapters 1~5 : FRDM-MCXN947 main body and USB cable [Assignment time: 60 minutes] Chapter 6 (I²C) : ジャンパ线 2 books [Assignment time: 20 minutes] Chapter 7 (SPI) : ジャンパ线 1 [Assignment time: 20 minutes] Chapter 8 (Ethernet) : LAN Controller 1 [Assignment time: 20 minutes] 0. Catalog Table of contents MicroPythonとはなんなのか? 1.1 どういうところで使われているのか 1.2 MicroPythonのいいところ,悪いところ 1.3 MCX Maintenance: 「Zephyrポート」form 1.4 This time's の対応でできるようになったこと 1.5 Zephyr's Weakness: Designated by Zephyr MicroPython Zephyrポートのビルド 2.1 Zephyr open environment environment 2.2 MicroPython のソースをGet する 2.3 ビルドする 2.4 ボードに书き込む MicroPython ってみる — Basic Editor 3.1 Thonny する 3.2 USB USB 3.3 Accept the confirmation 3.4 「REPL」とは 3.5 スクリプトを书いてみる:Lチカ 3.6 このボードで使えるピンを动べる 3.7 Lチカの色を変えてみる Edited by: ピン名を公夫する 4.1 まずはスクリプトの中にPINS Dictionary を书く 4.2 config.pyにcutり出す 4.3 ストレージにSaved by してShared by する 4.4 config.pyった3色Lチカ Editor: スイッチを読む 5.1 スイッチのSTATEを読む 5.2 杀されたことを Cut り込みで知る User editor: I²C ってみる 6.1 このボードのI²C matter 6.2 ジャンパを2本つなぐ 6.3 バスをスキャンする 6.4 Temperature control Editor: SPI ってみる 7.1 ループバックでtrial 7.2 CS automatic control system Editor: Ethernet ってみる 8.1 Wired LAN connection 8.2 このポートのネットワークAPI 8.3 PC direct connection test 8.4 Self-divided IP address 8.5 ボードをWebサーバにする 8.6 LED display operation method 8.7 The power supply is connected to the power supply. 8.8 ハマりやすいPoint まとめ References Additional Notes: LED Operation System Explanation 11.1 ここまでのcontentが1つにまとまっている 11.2 コードの3つのShi hangけ 11.3 Reasons why exceptions are necessary 11.4 Connection: close について 11.5 そのほか気をつける点 11.6 The future of the future 1. MicroPython とはなんなのか? MicroPythonは,マイコンの上でdirect actionくPython 3のインタプリタです. Damien in 2013 George's Kickstarter fund collection is open now.はオープンソース(MITライセンス)のプロジェクトとして开発が続いています. "Python 3 processing system" といっても, PC で动くCPython をそのままhold ってきたわけではありません. There are hundreds of KB of ROM and dozens of KB of RAM, and the language can be used in a variety of ways.そのためgrammarはPython 3とほぼ Same as じですが, standard ライブラリはnecessary なものだけがpurpose されています. その代わりに,マイコンならではのモジュールが意されています. GPIO, I²C, SPI, UART, PWM, ADC and other machine functions.このブログでも machine モジュールを使っていきます. なお,この章はBackground descriptionです. すぐに手を动かしたい方はChapter 2へ入んでください. 1.1 どういうところで使われているのか MicroPython is used to perform tasks, and times are used to perform scenes. Educational use : BBC micro:bitがMicroPythonをadoptsしたことで,一気に知られるようになりました. Raspberry Pi Pico も MicroPython を formula に サ ポ ー ト し て い ま す. プロトタイピング:センサをとりあえず动かしてデータを见てみたい,というstageでは. Jig and measuring device : Manufacturer of ラインの検CHECK Jig や, のように of simple measuring device for 実験 use, 『A small amount of でいいのでEarly work りたい』ものに向いています. ホビー:Electronic work is divided into different areas. いずれも                                            sincecessous by early く作る」ここがMicroPython's one-stop proud division といえます. 1.2 MicroPythonのいいところ,悪いところ このsectionのcontentは, specific のマイコンやポートにlimit らない, MicroPython’s general properties です. Make the judgment of うかどうかをできるように, 両面を挙げておきます. いいところ コードが简単に书ける:Python 3のgrammarがそのまま使えます. The character string processing is the same as the operation, and the C processing is the number of lines and the writing is the same. The answer to the question is: ボードに与続して, 1 line of ずつコマンドを打ち込みながらactionを正かめられます. 「このピンをHIGHにしたらLEDはPointくのか, eliminateえるのか」といったconfirmationが,その fieldで1 row hitつだけで済みます.ハードウェアの挙猙动を Manual detection りで真かめるとき, これは very strong です. (この対情码ENVIREPLとHUびます.Section 3.4 detailed explanationします) ビルドが要らない:スクリプトを书いて実行するだけです.コンパイル・リンク・书き込みのサイクルが不要なので, trial and error がspeed く ります. Learn コストがlowい: Python を知っていれば, マイコンのknowledge だけ Foot せば开 められます. 悪いところ The speed of running is : インタプリタなので, Cで书いたコードに is dozens of times higher than べると, and it is a hundred times higher than ぅくなります. It is necessary to control the necessary processing and high-speed signal processing.ただし対泽はあって,Guan Shuに @micropython.native や @micropython.viper のデコレータをpayけると, その关数だけをネイティブコードにコンパイルできます.それでも足りないoccasionは,そのpartだけCで书いてモジュールとして组み込むこともできます. メモリを食う: インタプリタ main body and standard ライブラリをマイコンにせる Required があります. Hundreds of KB of RAM, tens of KB of RAM, consumption of books in front of the time. The small さなマイコンでは is now the ではありません. ガベージコレクションがThe action of the movement is complete and the control is complete. MCXN947は2MBのフラッシュと512KBのSRAMをチップ上にholdっているので,メモリの点では yuyu をもってMicroPythonを开せられます. 1.3 MCX Maintenance: 「Zephyrポート」form MicroPythonは,マイコンのkindごとに「ポート」とcallingばれるported versionをholdっています. ports/rp2 (Raspberry Pi Pico), ports/mimxrt (i.MX RT), ports/esp32 といったtool合です. The これらはeach マイコンのレジスタやSDKを is directly 叩く, and the そのチップ専用の実装です. MCX シリーズについては, このような専用ポートはexistent しません.その代わりに使えるのが ports/zephyr , つまりZephyr RTOSの上で动かすポートです. Zephyrがサポートしているボードなら, principle of the same "MicroPython" Zephyr Zephyrめ, MicroPython side has a unique and necessary function. FRDM-MCXN947 は Zephyr が に サ ポ ー ト し て る ボ ー ド な の で, こ の士组 み に ride る こ と が で き ま す. NXPのマイコンでMicroPython is used ここで小しorganize しておきます. NXPのマイコンでMicroPythonを动かそうとしたとき,これまで実性的な选択limbはi.MX RTシリーズでした。 Exclusive use of ポートの ports/mimxrt がRT1010からRT1170までのEVKやTeensy 4 . Zephyrポートにも前からいくつかNXPボードのSETが入っていましたが, mimxrt1020_evk や mimxrt685_evk_cm33 といったクロスオーバーMCU to けか, frdm_k64f / frdm_kw41z のようにかなり前のKinetis to けで, しかもlater はファイルシステムやI²C/SPIまで全えられたものではありませんでした. i.MX RT has high performance and high performance, while MCU has a high-end product group. "MicroPython's use of microPython" and its purpose are as follows: This time, the settings of FRDM-MCXN947 are set up, and the general-purpose MCU is MCX Nシリーズという, より手を出しやすい选択limbs plus わりました.これもThis time's の対応のmeaningのひとつだと思います. 図1: MicroPython Zephyr class   この道には, 强的do と无码 の両方があります. Changsuo, Zephyr, Zephyr, が対応しているボードに纃く unfolds できること. Short place, Zephyr's abstraction, すぶん, チップ専用ポートに比べて「そのボードらしい书きFlavour」が thin くなることです. The specific details will be discussed later. 1.4 This time's の対応でできるようになったこと Zephyr's own body has been used before, and the settings used for FRDM-MCXN947 have been set up.そのままビルドすると,対语的にコマンドを打ち込むことはできても,ストレージもI²CもSPIも使えない,というSTATEでした. This time, the following の2つのファイルが本家 micropython/micropython のmasterにマージされました. ports/zephyr/boards/frdm_mcxn947_mcxn947_cpu0.conf ports/zephyr/boards/frdm_mcxn947_mcxn947_cpu0.overlay これによって,时のことができるようになっています. (1) オンボードのフラッシュをファイルシステムとして使える FRDM-MCXN947にっている8 MiBのQSPIフラッシュ(Winbond W25Q64JV)の storage_partition を,LittleFSとして /flash にマウントします. The book is saved by the book いたスクリプトをボード上にしておけるようになる, the というmeans で, and the これが一大きい変changes です. 実界にマウントしたstatusでCapacityをconfirmationすると,时のようになります. >>> import os >>> os.statvfs('/flash') (4096, 4096, 2048, 2043, 2043, 0, 0, 0, 0, 255) ブロックサイズ4096バイト × 2048ブロック = 8 MiB のうち, LittleFS management area をexcept いたabout 7.98 MiB が えます. (2) MikroBusのSPIが使えるようになった MikroBusコネクタのSPI( flexcomm6_lpspi6 )をeffectiveにしています.このSPIは, ボード通のdevicetree ではピンDefinition まで意されているものの, status = "disabled" のままになっていました. MOSI/SCK is used for P3_20/P3_21, SAI1 is shared with others. SAIは Serial Audio Interfaceの slightly, I²SやTDMといったデジタルオーディオのデータをやり出りするためのシリアル・インターフェースです.オーディオコーデックやマイクを行ぐときに使うもので, Same as じピンをSPIとSAIの両squareにsimultaneouslyに Cutり为てることはできません.そのためボード common definition では, どちらともdetermine めずに invalid にしてありました. では, どちらに使うのか. This time the overlay is valid and the SPI is valid and the judgment is valid. Gen拠は単正で,MicroPythonのZephyrポートにはI²S /SAIをうドライバも machine.I2S のようなクラスもexistent しないからです.つまりSAI1のピンとして半しておいても, MicroPython からは making いようがありません.それならSPIとしてmakes えるようにしたほうが useful だろう, というわけです. (3) I²CとSPIのドライバが组み込まれるようになった CONFIG_I2C=y と CONFIG_SPI=y しています.これがないと machine.I2C や machine.SPI を作ろうとしてもFAILURE します. 1.5 Zephyr's Weakness: Designated by Zephyr さて, ここでZephyrポートの「使いにくいところ」を前に说しておきます.あとで対 Ceをshowすので,まずはquestionを知っておいてください. Normally MicroPython is used, and the name of MicroPython is specified by name. # i.MX RTの専用ポート(ports/mimxrt)の場合 led = Pin('D9', Pin.OUT) # Raspberry Pi Pico の場合 led = Pin(25, Pin.OUT) # ESP32 の場合 led = Pin(2, Pin.OUT) Same as NXP's のマイコンでも, i.MX RT's の専用ポートでは 'D9' というボード上の表记そのままの名前が使えます. ところがZephyr ポートでは, GPIO ポートname とビットposition のタプルでspecified します. # FRDM-MCXN947(Zephyrポート)の場合 led = Pin(("gpio0", 10), Pin.OUT) ("gpio0", 10) は「GPIO0ポートの10ビット目」,つまりデータシート上のP0_10を Refers to します. The form of the violation is the crossing, and the time is the crossing. >>> Pin(25, Pin.OUT) Traceback (most recent call last): File " ", line 1, in ValueError: Pin id must be tuple of ("GPIO_x", pin#) なぜこうなっているかというと, ZephyrのdevicetreeではGPIOが gpio0 , gpio1 ,…というポート単position のデバイスとしてDefinition されていて, その中のビットposition でピンをrefers to すからです. MicroPython side is open and closed. The problem is that the digital circuit is printed and printed .たとえば    っても,そのD9が ("gpio0", 10) であることは,devicetreeを読まないとわかりません. Arduino ヘッダーの D9 や, RGB LED の 赤 といった名前は, MicroPython everything seen えないのです. これはかなりIt’s inconvenient. Chapter 4 : この対 CeをStep by StepをChasingってIntroductionします. コラム:Zephyrは「SDKの下注り」としても使われている Zephyr み込みアプリケーションを书くためのRTOS" というイメージが强いと思います.実记そのとおりなのですが, recently the はもうひとつの使われ方が目立ってきました. Don't use the SDK to install the platform on the ground . This time's MicroPython Zephyrポートがまさにそれです.ユーザーが书くのはPythonのコードで, Zephyr's existence をconsciousness することはほとんどありません. MicroPy thonのインタプリタ自も, Zephyrのスレッドのひとつとして実行されています. Example of the same structure: ArduinoCore-zephyrがあります.これはArduinoのAPI( pinMode() , digitalWrite() , Wire , SPI ...)をZephyrの上に実装したもので, Arduino IDEから使うlimitりはZephyrは见えません.けれども下注りはZephyrなので, Zephyrが対応しているボードにArduino environment をhold ち込めることになります. このように「Zephyrをdirect use」に「Zephyrの上にったものを使う」という选択 Limb が壗えてきています. Zephyr's のボードサポートを preparation することが, そのままMicroPython やArduino's 対応にもつながる, というrelations です. ▲ Catalog に戻る 2. MicroPython Zephyrポートのビルド ここからは実记に手を动かしていきます.まずはファームウェアをビルドしてボードに书き込みます. 2.1 Zephyr open environment environment この记事のコマンド Exampleは, macOSやLinuxのシェル(bashやzsh)をpremiseにしています. Windows is easy to use, and the environment is easy to use. コラム:Windows does not enter the situation The first conclusion is the book, the Windows PowerShell (cmd.exe), the Windows PowerShell, and the PowerShell .コマンドを书きchangeえても駄目です. MicroPython's processing is done, and UNIX's dependency is maintained.ビルドを定めている py/mkrules.cmake の中で, cat ・ sed ・ touch が directly call ばれています.たとえばqstr (character sequence テーブル) する箇所は, 时のようなシェルのパイプライン1 で书かれています. cat … | sed … | (Cプリプロセッサ) | sed … > 出力ファイル これらのコマンドはWindowsにexistingしません. cmd.exe There cat is sed no ending, and the ending is ending.シェルを変えてもsolvedしないのはこのためです. 実记,MicroPython's main familyのCIでも, Zephyrポートのビルドは ubuntu-latest でのみ実行されています. Windows でのビルドは Thought されていません. 风らわしいのですが, Zephyr's own はネイティブのWindows でビルドできます.この节で IntroductionするZephyrのGetting Started Guideにも、wingetでツールを入れるWindows 到けの手顺があります. MicroPythonをビルドするdan step になって初めて行き诘まる, ということが出こります. Windows has entered the environment, and the environment of the UNIX environment has improved.どちらでも、この记事のコマンドはそのまま使えます. WSL2 (Windows Subsystem for Linux). Zephyr's Getting Started Guideでも, Ubuntu's application to the user's hand is easy to use. Import instructions for Microsoft Git for Windows (Git Bash) やMSYS2のbash environment なお,ビルドと书き込みだけをUNIX environment で行い, Thonny でのMicroPython operation は Windows side から, という分け方 もできます. ThonnyもmpremoteもWindowsでそのまま动くので, from chapter 3 onwardsはWindowsだけで入められます. MicroPython Zephyr's environment (west, Zephyr SDK, Python's environment) is not necessary Zephyr environment construction guide, NXP Japanese language explanation and explanation The まだenvironment is made by the っていない方は, and the まずそちらを refers to the してください. Zephyr シリーズ Chapter 2 はじめてのビルドと実机动(日本语ブログ) この记事で Reference していただきたいのは, Kailu environment をインストールする partです. The second half of the story, Zephyr, Zephyr blinky など)をビルドして动かしますが,このブログでビルドするのはZephyrのサンプルではなくMicroPythonです.ビルドの対相をSpecificationするPartだけがviolationうとtestえてください. west build The status of the pass is the same as the work, and the preparation is completed. Zephyr's formula is the following. Zephyr Getting Started Guide Environment ができていれば, ~/zephyrproject のようなディレクトリにwest workspace がpurpose されているはずです. Hereafter はこれを ~/zephyrproject として说します. 2.2 MicroPython のソースをGet する MicroPython のソースは, Zephyr のworkspace とはdifferent place に Location い て struct い ま せ ん. Zephyr's workspace is dirty, and it's a different place. git clone https://github.com/micropython/micropython.git cloneしたら,为られたディレクトリに动ってサブモジュールをGetします. cd micropython git submodule update --init lib/micropython-lib micropython-lib MicroPython uses the standard ライブラリgroup and サブモジュールとしてseparationされています.これをGet the しておかないとビルド时にエラーになるので, forget the れずに実行してください. The book that appears is the book, the setting for FRDM-MCXN947 is the master of the main house.パッチをあてるNecessaryはありません. Read the のため, and use the のファイルがあることを to confirm the しておきましょう. micropython ディレクトリにいるSTATUSのまま実行します. ls ports/zephyr/boards/ | grep mcxn947 frdm_mcxn947_mcxn947_cpu0.conf と frdm_mcxn947_mcxn947_cpu0.overlay の2つが means されればOKです. なぜファイル名が长いのか Zephyr では, the same as じボードでもコアやaction モードによってplural の constitute をhold つことがあります. FRDM-MCXN947 Cortex-M33 Cortex-M33 をデュアルで is equipped with しているため, frdm_mcxn947/mcxn947/cpu0 のように「ボードName/SoC name/コアname」specified します. Board qualifier (board qualifier) and board qualifier. MicroPython's Zephyr ポートは, このmodifier をincluding めた名前でconf/overlay をExploration します.つまり frdm_mcxn947.conf という名前では読み込まれません. frdm_mcxn947_mcxn947_cpu0.conf としてはじめて见されます. The self-divided settings are added to the setting, and the settings are added to the settings. 2.3 ビルドする まずZephyrの仮 Thinking about the environment をeffectiveにします. source ~/zephyrproject/.venv/bin/activate Zephyrのバージョンを合わせます. cd ~/zephyrproject/zephyr git checkout v4.4.0 west update MicroPython's Zephyr ポートが対応を明言しているのは, v3.7 (LTS) and v4.4, そして开発版です. Honke's CIはv4.4でビルドを検证しています.のバージョンになっていると, outside workspace , 通ってもactionがviolationったりすることがあるので,ここでv4.4.0に揃えておきます. west update HALやライブラリなどのrelated モジュールをtake り正すためのものです. git checkout だけでは不integrationが residualるので,必ずセットで実行してください. Preparationができたら west build を実行します. cd ~/zephyrproject west build -b frdm_mcxn947/mcxn947/cpu0 ~/micropython/ports/zephyr -b がボード specifies, the last argument is がビルド対相のアプリケーション(MicroPythonのZephyrポート)です. ~/micropython のpartは,実记にcloneしたplaceに読み为えてください. ビルドが通ると build/zephyr/ の下に zephyr.bin , zephyr.hex , zephyr.elf がGenerationされます. After 2 episodes, the settings are straight and straight, --pristine (または -p ) The result of the previous return is the result of the previous return. cd ~/zephyrproject west build -p -b frdm_mcxn947/mcxn947/cpu0 ~/micropython/ports/zephyr 2.4 ボードに书き込む FRDM-MCXN947にはMCU-LinkデバッガがオンボードでThe book is written in a different way, the purpose is necessary, and the book is written in a different way. USB ケーブルはJ17 (MCU-Link side USB コネクタ) connector 図2: USB connector J17 (MCU-Link side) connector Receive 続したら, west flash を実行するだけです. cd ~/zephyrproject west flash Book き込みがEnd わると, ボードはAutomatic にリセットされてMicroPython がStart します. このJ17は书き込みだけでなく, MicroPython と対语するためのシリアルcommunication にも使います.つまりケーブル1で书き込みとoperationの両方ができます. Detailed description in Section 3.2 . ▲ Catalog に戻る 3. MicroPython ってみる—Basic editor ファームウェアが书き込めたら, いよいよMicroPython をtouch っていきます. 3.1 Thonny する MicroPython is easy to use, and the environment of MicroPython is not necessary.ターミナルソフトでもstructuring いませんが, ここではThonnyをmaking います. Thonny is MicroPython's first functional function and is also an IDE. Free of charge, Windows / macOS / Linux can be used. Thonny formula サイト The basic operation of Thonny's のインストールと is the basic operation, and the following animation is the corresponding part. MicroPythonをi.MX RTクロスオーバーMCUで动かしてみた(YouTube) — Thonnyの Import PartからRegenerationされます Thonny is the advantage of the point, and the communication is the same. The upper part of the book, the upper part of the book, the upper part of the book, the upper part of the book ボードのファイルシステム( /flash )の中体をGUIで见られる PCとボードの间でファイルをドラッグ&ドロップでコピーできる という点です. Chapter 4. 3.2 USB USB FRDM-MCXN947にはUSB Type-Cのコネクタがpluralあります. MicroPython のコンソールにsystem ぐのはJ17 , MCU-Link side のコネクタです ( Section 2.4の図2と同じ地です). MicroPython のコンソールは, Zephyr のコンソール( zephyr,console )に出力されます. FRDM-MCXN947のcpu0では,これが flexcomm4_lpuart4 (P1_8 / P1_9) The original MCU-Link MCU-Link VCOM (仮愿COMポート) がっています. つまりJ17の1书で,ファームウェアの书き込みとコンソールの両方ができます. The main body of MCXN947 is the USB system of the main body, and the composition of this chapter is the USB system. 3.3 Accept the confirmation ケーブルを行いだらThonnyをStartします. Thonny's lower right (またはメニューの「実行」→「インタプリタの选択」)から,インタプリタとして「MicroPython (generic) "を Select び, ポートにボードのVCOM をSpecify します. Windows: COM3 のような名前 macOS: /dev/cu.usbmodem… Linux: /dev/ttyACM0 など 図3:インタプリタに「MicroPython (generic)」を选ぶ   The うまく system is a がると, the lower のシェル(Shell) ペインにプロンプトが出ます. Ctrl-D (ソフトリセット)を気てみてください. MicroPython v1.30.0-preview.17.g47e9329e51 on 2026-08-30; zephyr-frdm_mcxn947 with mcxn947 Type "help()" for more information. >>>   図4: The success of the 続にすると, シェルペイン(ウィンドウ下)にバナーとプロンプトが means される The last part of zephyr-frdm_mcxn947 with mcxn947 is the focus of attention. zephyr-frdm_mcxn947 はZephyrの CONFIG_BOARD , mcxn947 は CONFIG_SOC から作られる名前です.ここがLook forward to どおりになっていれば, snipe ったボード Use のバイナリが move いているとconfirm できます. >>> がプロンプトです.ここにPythonのstyleを打ち込めます.まず「Hello, world!」のexpressionから出してみましょう. >>> print("Hello, world!") Hello, world! MicroPython はPython なので, formula をhit つだけでも results が return ります. >>> 1 + 2 3 >>> "MCX" * 3 'MCXMCXMCX' ファイルシステムもconfirmationしておきます. >>> import os >>> os.getcwd() '/flash' >>> os.listdir('/flash') [] Start the straight back のカレントディレクトリが /flash になっています.これはThis time the マージされたsetでLittleFSがマウントされているからです.まだ何も志いていないので中体は空です. 3.4 「REPL」とは いま打ち込んでいるこの対情码ENVIRONMENT をREPLとHUびます. R ead (読む), E val (evaluation価する), P rint (expression す る), L oop (粲 り return す) no initial character で す. 1 line of input force, MicroPython はそれを読み, 実行し, the result を represents し, また时の enter force をWaiting ちます.これがREPLです. コンパイルして书き込んで実行して, という手顺をStep on the result of がわからないCの开発と比べると, trial and error の回しかたそのものが変わってきます.たとえば「このピンをHIGHにしたらLEDは点くのか, eliminateえるのか」といったconfirmationが, そのfieldで1 line hit つだけで済みます.ハードウェアの挙猙动を Manual detection りで真かめるとき, REPL はvery powerful な props になります. REPL is easy to use and easy to operate. キー Action Ctrl-C 実行中のプログラムをinterruptionする Ctrl-D MicroPython ソを restart する Ctrl-E ペーストモードに入る Ctrl-A rawREPLモードに入る Ctrl-B Normal REPLモードに戻る Table 1: REPL control system Ctrl-Cは, unlimited ループに入ってしまったプログラムをstop めるときに使います. Ctrl-D Ctrl-Eのペーストモードは, plural line のコードをまとめてsticker けるときに使います. Normally REPLは1行ごとにインデントを解釈しようとするので, for 文のようなplural lineのコードをそのままるとうまくいかないことがあります. Ctrl-E して ら コ ー ド を paste り け, Ctrl-D で実行 す る と, ま と め て さ れ ま す. 3.5 スクリプトを书いてみる:Lチカ ここまではREPLに1行ずつ打ち込んできました.ちょっとしたconfirm にはこれが一半hayいのですが,缲り回しやconditions divergence が into ってくるとさすがに俫なります.そういうまとまったprocessingは, スクリプトとして书いたほうが楽です. ではスクリプトを书いてみましょう. LED のLチカ(LEDチカチカ)です. FRDM-MCXN947にはRGBのLEDがっています.まずは红を点杀させてみます.红のLEDはP0_10,つまり ("gpio0", 10) に式がっています. Thonny's upper part is the upper part of the book, and the second part is the book. import time from machine import Pin led = Pin(("gpio0", 10), Pin.OUT) # 赤LED (P0_10) while True: led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 time.sleep(0.5) 図5: The upper side of the book. Lower side がシェルペイン   书けたら, ツールバーの「実行」ボタン(Green Triangleのアイコン.ショートカットはF5)を気ます. Thonnyが           ,                           ious Generation                   ched in in in on in MicroPython Today's test is the same as the test, and the test is the same as the test. The red LED lights up successfully in 0.5 seconds. Stop it, stop it, stop it, stop it.シェルペインでCtrl-Cを気ても同じように出まります. ここで「あれ?」と思った方へ コードをよく见てください. value(0) means turning on the lights, value(1) means turning off the lights. Intuition is the opposite of seeing the truth, and the harmony is the truth. FRDM-MCXN947のRGB LEDは,アノードコモンでConnect続されています. LED side power supply system, マイコンのピンがマイナス side を lead っ Zhang る-shaped です.つまりピンをLOW(0)にしたときにcurrent が流れてlighting します.このような涚をアクティブ・ローといいます. 図6: The RGB LED part of the FRDM-MCXN947 circuit . LED power supply system   Zephyrのdevicetreeには,このLEDが GPIO_ACTIVE_LOW であるというInformationがちゃんと书かれています.しかしMicroPythonの machine.Pin は,devicetreeのこのフラグを见ずにGPIOを生の値のまま読み书きします(内で gpio_pin_set_raw() をHUんでいます).そのため, 论理をanti転してくれることはありません. 0 を书けばピンはLOWになり,LEDは点きます. ちなみに, led.value(0) は led.off() とも书けます.つまり led.off() をHUぶとLEDはLight upします. Mingmao と実记のaction が inverse になるので, chaos しそうなときは value(0) / value(1) で书くほうが安全 かもしれません. もうひとつ Note: toggle() はありません His のポートのMicroPythonにcustomれていると led.toggle() と书きたくなりますが, Zephyr ポートの Pin にはこのメソッドがありません. Make it a new one. メソッド/fixed number Description value([x]) The quotation is なしで読み出し, the quotation is ありで书き込み on() HIGH(1)をoutput off() LOW(0)をoutput init(...) ピンのsettings update irq(...) Cut the り込みハンドラを setting Pin.IN / Pin.OUT / Pin.OPEN_DRAIN input and output power Pin.PULL_UP / Pin.PULL_DOWN プルアップ / プルダウン Pin.IRQ_RISING / Pin.IRQ_FALLING Cut り込みエッジ Table 2: Zephyrポートの machine.Pin で使えるもの トグルしたいときは,読んで転して书けば済みます. led.value(not led.value()) 3.6 このボードで使えるピンを动べる さて,红のLEDが ("gpio0", 10) であることは,どこから来た値なのかを Description しないまま使ってきました.では自分で调べるにはどうすればいいのでしょうか. この节では,answerえを探しにZephyrのSETファイルまでdropりていきます.小し込み入った说になるので, first をhurry ぐ方は読み飞ばして4 chapterに入んでstructure いません. Chapter 4: では, ここで调べた対応表をOnce made ってしまえば and then dropped は名前でピンを designated できる, という语をします. Cannian ながら, MicroPython のZephyr ポートには "make えるピンの一覧をexpression する" function がありません. machine モジュールの中身を见ても, ピンの名前は出てきません. >>> import machine >>> dir(machine) Pin , I2C , SPI , UART , PWM , ADC , Timer , WDT といったクラス名が和びます(実记に何が入っているかはビルド时のSETで変わるので, 手元で実行して真かめてください). Pin というクラスがあることはわかりますが. では,どこを见ればいいのか AnswerえはZephyrのdevicetreeです. devicetreeとは (Zephyr's original content is known as "FRDM-MCXN947 device tree" and "FRDM-MCXN947's device tree is the same as the original one") devicetree(デバイスツリー)は,ボードにどんなハードウェアがzai っていて, どう式 がっているかを说したテキストファイルです. The もともとはLinux カーネルで uses the われていた士组みで, and the Zephyr もこれを adopts the しています. 「このSoCにはI²Cコントローラが何的あって,それぞれどのアドレスにあって,どのピンに出ていて,effectiveなのか无なのか」といったinformationが, .dts / .dtsi とい拡张子のファイルにstrata structure で书かれています. Zephyr's にこれを読みtake り, necessary なドライバのInitialization コードやピンのsetting をautomatic にGenerationします. ソースコードにピン号をdirect bookく代わりに,ハードウェアのConstitution information をコードからSeparationしておく、というtestえ方です.おかげで, the same as じアプリケーションのソースをbie のボード to けにビルドしstraight すことができます. MicroPython のZephyr ポートが ("gpio0", 10) というタプルをRequirement するのも, このdevicetreeのconstruct をそのまま Reflect しているからです. gpio0 のデバイス名で on はdevicetree, 10 はそのポート内のビット Position です. FRDM-MCXN947のdevicetreeを読む FRDM-MCXN947 configuration は, Zephyr のリポジトリの下のファイルに书かれています. zephyr/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi この中の arduino_header というノードに,Arduinoヘッダーのeach ピンがどのGPIOに Department がるかが书かれています. arduino_header: arduino-connector { compatible = "arduino-header-r3"; gpio-map = , , , , , /* RX */ , /* TX */ , ... , /* SCK */ , /* SDA */ ; /* SCL */ }; は「ヘッダーのD13は gpio0 の25ビット目」というmeans です.これをMicroPythonのタプルに正すと ("gpio0", 25) になります. Same as じファイルの中に, LED とスイッチのDefinition もあります. leds { compatible = "gpio-leds"; green_led: led_1 { gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; ... }; blue_led: led_2 { gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; ... }; red_led: led_3 { gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; ... }; }; gpio_keys { compatible = "gpio-keys"; user_button_2: button_0 { gpios = <&gpio0 23 ...>; }; /* SW2 */ user_button_3: button_1 { gpios = <&gpio0 6 ...>; }; /* SW3 */ }; 红のLEDが &gpio0 10 , つまり ("gpio0", 10) であることがここでconfirmできます. GPIO_ACTIVE_LOW と书かれているのも见えますね. The first explanation is the root of the root. Every time devicetree を読むのか? もちろん, every time I return to the これを tune and the べるのは is now the ではありません. 「LEDを光らせたいだけなのにdevicetreeを読む」というのは, MicroPythonの手軽さを台无しにしています. そこで4 chapter では, この対応expression を once だけ作って, and then は名前で书けるようにするmethod を Introduction します. 3.7 Lチカの色を変えてみる 対泽の前に,タプルspecified inconvenienceさをもう小しphysical senseしておきましょう. 3-color LED light source. devicetreeから読みtakeった値は时のとおりでした. color ピン タプル red P0_10 ("gpio0", 10) green P0_27 ("gpio0", 27) green P1_2 ("gpio1", 2) Table 3: RGB LED lighting import time from machine import Pin red = Pin(("gpio0", 10), Pin.OUT, value=1) green = Pin(("gpio0", 27), Pin.OUT, value=1) blue = Pin(("gpio1", 2), Pin.OUT, value=1) while True: for led in (red, green, blue): led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 Pin() の value=1 は, ピンをOutputにsettingするとsimultaneousにInitial valueをHIGH(lights off)にするSpecificationです.これをpay けないと, set した moment に a moment light ることがあります. Red→green→green とshunfanに光ればsuccessです. さて, このコードを见てどう思うでしょうか. red = Pin(("gpio0", 10), Pin.OUT, value=1) ("gpio0", 10) The part of というに means が読みtake れません. red という変numeral nameをpayけたから読めるだけで,このnumeralだけを见て「redのLED」だとわかる人はいないはずです. しかも, このdigits えてもエラーにはなりません. ("gpio0", 11) と书いてしまったら, exist するピンなので Pin はnormal に为られ, ただLED らないだけです. 「どこが悪いのか」を探すのに时を取られることになります. このquestion を, times の Zhang で片Pay けます. ▲ Catalog に戻る 4. Urgent editor: ピン名を公夫する Zephyr ポートがピン名をprovides してくれないなら, and the intention is to separate it. The policy of それがこの章です. Step by step を chase っ て, 3 つ の step by step で advance め ま す. スクリプトの中にlexiconを书く config.py というfarewellファイルに Cutり出す ボードのストレージに出いて,すべてのスクリプトからshared 4.1 まずはスクリプトの中にPINS Dictionary を书く Ichiban 単なのは, スクリプトの前头にPythonのdictionaryを书いてしまうmethodです. import time from machine import Pin PINS = { "LED_RED": ("gpio0", 10), "LED_GREEN": ("gpio0", 27), "LED_BLUE": ("gpio1", 2), } red = Pin(PINS["LED_RED"], Pin.OUT, value=1) while True: red.value(0) time.sleep(0.5) red.value(1) time.sleep(0.5) Pin(PINS["LED_RED"], ...) と书けるようになりました.これなら何をしているか一目でわかります. さらに好いのは,タイプミスがエラーになることです. >>> Pin(PINS["LED_RD"], Pin.OUT) Traceback (most recent call last): File " ", line 1, in KeyError: LED_RD First of all, "Numbers and numbers are violated". Dictionary のキーを间violation えれば KeyError でstop まってくれます.これだけでもデバッグの手间がかなり minus ります. 4.2 config.pyにcutり出す しかし, スクリプトを书くたびにこのdictionary をコピーするのは面流です.実记, LEDだけでなくArduinoヘッダーやMikroBusのピンもDefinitionしたくなるので, Dictionaryはどんどん长くなります.そのたびにallのスクリプトの头にstickerりpayけるのは成実的ではありません. Pythonらしく,不ファイルに Cutり出してimportしましょう. config.py というファイルを作ります. PINS = { # --- Arduinoヘッダー --- "D0": ("gpio4", 3), # P4_3 (RX) "D1": ("gpio4", 2), # P4_2 (TX) "D2": ("gpio0", 29), # P0_29 "D3": ("gpio1", 23), # P1_23 "D4": ("gpio0", 30), # P0_30 "D5": ("gpio1", 21), # P1_21 "D6": ("gpio1", 2), # P1_2 "D7": ("gpio0", 31), # P0_31 "D8": ("gpio0", 28), # P0_28 "D9": ("gpio0", 10), # P0_10 "D10": ("gpio0", 27), # P0_27 (CS) "D11": ("gpio0", 24), # P0_24 (MOSI) "D12": ("gpio0", 26), # P0_26 (MISO) "D13": ("gpio0", 25), # P0_25 (SCK) "D14": ("gpio4", 0), # P4_0 (SDA) "D15": ("gpio4", 1), # P4_1 (SCL) "A2": ("gpio0", 14), # P0_14 "A3": ("gpio0", 22), # P0_22 "A4": ("gpio0", 15), # P0_15 "A5": ("gpio0", 23), # P0_23 # --- バス(Zephyrのデバイスノード名) --- "I2C": "lpi2c@94800", # flexcomm2_lpi2c2 (arduino_i2c) "SPI": "spi@93000", # flexcomm1_lpspi1 (D10〜D13) "MIKROBUS_I2C": "lpi2c@95800", # flexcomm3_lpi2c3 "MIKROBUS_SPI": "spi@b6000", # flexcomm6_lpspi6 # --- MikroBusのGPIO --- "MIKROBUS_RST": ("gpio1", 3), "MIKROBUS_CS": ("gpio3", 23), "MIKROBUS_SCK": ("gpio3", 21), "MIKROBUS_MISO": ("gpio3", 22), "MIKROBUS_MOSI": ("gpio3", 20), "MIKROBUS_PWM": ("gpio3", 19), "MIKROBUS_INT": ("gpio5", 7), "MIKROBUS_RX": ("gpio1", 16), # GPIOとして使える.UARTのRXではない "MIKROBUS_TX": ("gpio1", 17), # GPIOとして使える.UARTのTXではない "MIKROBUS_SCL": ("gpio1", 1), "MIKROBUS_SDA": ("gpio1", 0), # --- エイリアス --- "LED_RED": ("gpio0", 10), # = D9 "LED_GREEN": ("gpio0", 27), # = D10 "LED_BLUE": ("gpio1", 2), # = D6 "SW2": ("gpio0", 23), # = A5 "SW3": ("gpio0", 6), # P0_6 } すべてdevicetreeから転记した値です. いくつか complements します. RGB LED is shared with Arduino. Red LED (P0_10) is the same as Arduino D9 D9. Same as green D10, blue D6. Arduino シールドをinsert すときは, これらのピンを うとLED も一丝に光ります. Inverse wording, シールドがD6やD9をmakes っていると, LED のつもりでoperation するとシールドlateral influence が出ます. SDA/SCLはA4/A5ではありません. Arduino UNO R3 のボードでは, I²C のSDA/SCL がA4/A5 と same wiring になっていることが多く,「A4=SDA,A5=SCL」と覚えている方も多いと思います.しかしFRDM-MCXN947ではviolationいます. I²CはAREFの neighborにある専用のSDA/SCLピン(Zephyrのdevicetree上ではD14/D15)に出ていて,これはP4_0/P4_1です. A4 (P0_15) and A5 (P0_23), I²C system independent GPIO. Chapter 5: でジャンパを性ぐときにimportant になるので, 覚えておいてください. SW2はA5と同じピンです. ユーザースイッチのSW2 (P0_23)は, Arduino ヘッダーのA5と Same as the じピンに system がっています. A5's output is the same as the circuit's influence, and the attention is the same. バスは character string is specified by します. machine.I2C と machine.SPI のid parameterは,タプルではなくZephyrのデバイスノード名の character stringです. "lpi2c@94800" の 94800 は,MCXN947のメモリマップ上のペリフェラルのアドレス(0x94800)です.ここもdevicetree originの値です. 4.3 ストレージにSaved by してShared by する config.py ができました. スクリプトは「モジュール」として読み込める The first step is the first step, and the import step is the first step to complete the step. config.py はSpecial formのファイルではありません. PINS = { ... } と书いただけの、ごく ordinary Pythonのスクリプトです. Lチカのスクリプトと同じ,ただのテキストファイルです. Python では,こうしたスクリプトをhis のスクリプトから読み込んで使えます.読み込まれるlateral をモジュールとHUび, 譭み込むorderが import です. from config import PINS これは「 config.py を読み込んで実行し,その中で为られた PINS .py config config.py PINS という means になります.がのままモジュール名になります. の中体が実行されるので というdictionary ができあがり, それをこちらで使える, というわけです. よく making う definition や Off number を比ファイルにまとめておいて, necessary なスクリプトから読み込む.これはPython でごくGeneral なやり方で, MicroPython でも Same じように使えます. どこに志けばよいか では config.py をボードのどこに出けば,すべてのスクリプトから import できるでしょうか. MicroPythonは,モジュールを sys.path に和んだディレクトリからExploringします. Confirmation. >>> import sys >>> sys.path ['', '.frozen', '/flash/lib'] /flash/lib が入っています.これはThis time the マージされた setting is LittleFS がマウントされたときに, the startup process ( _boot.py ) is an automatic addition of してくれるものです. つまり /flash/lib/config.py としてsaveすれば,どのスクリプトからも from config import PINS でめるということです. Thonny's home Thonnyのメニューから「expression」→「ファイル」を选ぶと, the left side of the screen shows the されます. The upper half is for the PC side, and the lower half is for the MicroPython side.   図7:Thonny's config.py /flash/lib   Handy and smooth. The second half (ボード side)が /flash をexpressしていることをconfirmする ボードlateral のペインでright クリック →「新しいディレクトリ」を选び, lib を作る 作られた lib をダブルクリックして中に入る The first half (PC side)で config.py をright クリック →「/flash/lib へアップロード」を选ぶ Set it and confirm it. >>> import os >>> os.listdir('/flash/lib') ['config.py'] コマンドラインからoperation occasion (mpremote) Thonny is easy to use, easy to operate, easy to operate, and easy to use. mpremote pip install mpremote でインストールできます. まず lib ディレクトリを作ります. mpremote mkdir :/flash/lib その中に config.py をコピーします. mpremote cp config.py :/flash/lib/config.py スクリプトを実行するだけなら,ボードにSave せずに実行することもできます. mpremote run blink.py 4.4 config.pyった3色Lチカ Get ready. Section 3.7 のコードを书き正してみましょう. import time from machine import Pin from config import PINS red = Pin(PINS["LED_RED"], Pin.OUT, value=1) green = Pin(PINS["LED_GREEN"], Pin.OUT, value=1) blue = Pin(PINS["LED_BLUE"], Pin.OUT, value=1) while True: for led in (red, green, blue): led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 Section 3.7 と见比べてください.无いは, Pin() に多しているものだけです. red = Pin(("gpio0", 10), Pin.OUT, value=1) # 3.7節 red = Pin(PINS["LED_RED"], Pin.OUT, value=1) # こちら ("gpio0", 10) のようなdigitsはどこにも出てきません. 「Red・Green・Blue LEDをshunpanに光らせる」という meaning図が,そのままコードになりました. これで, 1.5 sections of で挙げたZephyr ポートの weak points, 実 use ほぼ to eliminate できました. config.py At one time, it was done by setting the いてしまえば, and then it was reduced by the ずっと making it えます. なお, ここで使っている config.py のfull textは4.2に contained せてあります.そのままコピーして使ってください. トラブルシューティング:うまくimportできないときは config.py をsetting the いたのに ImportError が出るoccasionは, time をconfirmationしてください. ソフトリセットをtrial す.シェルペインでCtrl-Dを気ます. MicroPython is imported onceするので, ファイルを出きchange えても古いものが使われることがあります.これが一买よくあるreason です. Confirm the place of purchase . os.listdir('/flash/lib') で config.py が见えるか真かめます. lib ディレクトリを作る前にアップロードして, /flash/ の正下に式かれてしまっているケースがよくあります. sys.path をConfirmationする. import sys; print(sys.path) に /flash/lib が入っているか见ます. Enter the っていなければ, /flash のマウントに failure している possibility があります. ファイル名をconfirmedする. from config import PINS で読めるのは config.py という名前のファイルだけです. Don't forget to save the name before you save it. ▲ Catalog に戻る 5. Editor: スイッチを読む Chapter 3ではLEDを光らせました. GPIO's contribution is very important. Today's degree is reversed, and the force is applied. FRDM-MCXN947には,ユーザーが免费に使えるスイッチが2つっています. SW2 and SW3 are the same.ここではSW2を使います. 図8:ユーザースイッチSW2とSW3のposition   この章にAdditional parts は要りません.ボードとUSBケーブルだけで入められます. 5.1 スイッチのSTATEを読む SW2はP0_23 がっていて, config.py に SW2 として入れてあります. from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) print(sw.value()) Pin.IN でEnter force setting, Pin.PULL_UP でInternal resistance is effective. なぜプルアップが必なのか このスイッチは, Otsu すとピンがGND に行がる路になっています. The opposite is true, the opposite is true, and the opposite is true. The state of the electricity is stable and the voltage is stable. プルアップresistant をeffectiveにすると, していないときはピンがpower side にciteき上げられてHIGH になります. Otsu し た と き だ け GND に cue か れ て LOW に な り ま す.これで両squareのstateがはっきりします. つまり読み出される値は时のようになります. Oshita していない → 1 Oshita している → 0 ここでも 0 が     です. LEDのときと同じアクティブ・ローの考え方で( section 3.5 ),このボードではよく出てくるshapedです. 実行して真かめてみましょう. >>> print(sw.value()) 1 杀していないので 1 が回りました.しながら実行すれば 0 になります. 粲り回し読む occasion Status を monitoring し続けるなら, こうなります. import time from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) last = sw.value() while True: now = sw.value() if now != last: print("押された" if now == 0 else "離された") last = now time.sleep_ms(20) In the previous chapter, の値と比べて, 変化したときだけ means しています. Each time, it means すると, and it means している间ずっと出力され続けてしまうためです. この法をポーリングと淳ます. The official group is pure and simple, and the shortcomings are small and clear. sleep_ms(20) の间にスイッチが阿されて里されると, 见出してしまいます.かといって Interval を Short くすると, その分だけCPU がこのConfirmation にcharge やされます. 5.2 杀されたことを Cut り込みで知る そこで使えるのが开り込みです. 「ピンのSTATEが変化したら,この关数をHUんでほしい」とHow to log in, how to deal with it, how to do it. See escape. machine.Pin では irq() メソッドで登录します. import time from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) n = 0 def pressed(pin): global n n += 1 print(" 割り込み %d 回目 value=%d" % (n, pin.value())) sw.irq(handler=pressed, trigger=Pin.IRQ_FALLING) print("SW2を数回押してください(30秒間)") for i in range(30): time.sleep(1) sw.irq(handler=None) print("合計 %d 回検出しました" % n) 実行してSW2を10 repayment resultsです. SW2を数回押してください(30秒間) 割り込み 1 回目 value=0 割り込み 2 回目 value=0 割り込み 3 回目 value=0 (中略) 割り込み 10 回目 value=0 合計 10 回検出しました The number of times is pressed, and the number of times is called, and the number of times is called. コードの読みかた trigger には, どの変化でHUんでほしいかをspecified します. Specify mean Pin.IRQ_FALLING HIGH→LOW の変化(このボードでは「した」) Pin.IRQ_RISING LOW→HIGH の変化(「   」) `Pin.IRQ_FALLING \ Pin.IRQ_RISING` 䡡方 Table 4: irq() の trigger できるもの ここでは pledge したinstant だけknow りたいので Pin.IRQ_FALLING をspecify しています. handler に crossing す pass number は, quotation を 1 つ Receive け take るよ う に书 き ま す. Call ばれるときに, cut り込みの起きた Pin オブジェクトが多されるためです. The above example is では pin.value() として, そのピンの値を読んでいます. global n がNecessary なのは, Guan Shu の外にある変数 を书きchange えるためです.これはPythonのNormalなdeterminationまりで,MicroPythonでも同じです. The last sw.irq(handler=None) is the last one. Undo it, let it go. ハンドラの中で print() してよいのか Cut り込みハンドラの中では, time のかかるprocess やメモリを ensure するprocess をavoid けるのが principle です. print() はどちらにも道てはまるので, originally I avoided it. ただしMicroPythonの irq() には hard というcitation があり, established value は hard=False です.このとき, ハンドラは Cut り込みが出きた Instant ではなく, 小し后の安全なタイミングにまわして実行されます.そのため print() を书いてもquestion ありません. hard=True をSpecify すると, cut り込みがきた instantly に実行されます.応 Answer はspeed くなりますが, print() やメモリsure はできなくなります.まずはestablishedのままでstructureいません. チャタリングについて Mechanical contact switch, the contact contact is instantaneous and the contact is fine and fine ON/OFF is turned on and off.これをチャタリングとcall び, 1 round of pressing しただけでcut り込みが多も入るreason になります. FRDM-MCXN947のSW2でしたかぎりでは, 10 times of pressingに対して Cut り込みは 10 times, チャタリングは観measure されませんでした.ただしスイッチの Individual しかたによってはRISE こりうるので, 数が合わないときは, The previous time has passed, and the time has passed, and the short time has passed, and the short time has passed, and the time has passed. ▲ Catalog に戻る 6. Usage editor: I²Cを使ってみる GPIO's sub-I²C's. Temperature is good. 6.1 このボードのI²C matter FRDM-MCXN947にはP3T1755というtemperatureセンサが开っています. I²CとI3Cの両方に対応した, decomposition energy 12ビット, accuracy ±0.5℃のセンサです. ところが,これをMicroPythonからそのまま読むことはできません. The reason is : MCXN947のI3C1は, the device tree is on the device tree. pinmux_i3c1: pinmux_i3c1 { group0 { pinmux = , ; ... }; }; つまりSDAがP1_16, SCLがP1_17です. One side, MicroPython's Zephyr's ポートにはI3C's のドライバがありません. machine モジュールにあるのは I2C だけで, I3C というクラスは EXISTENCE しないのです.つまりMicroPythonからは,このセンサに手が时きません. しかしI3Cのターゲットデバイスは,I²CのコントローラからもI²CデバイスとしてアクセスできるShi様になっています(レガシーI²Cモード). P3T1755もそうです. I3C Signal Line ここで, first ほど config.py に书いたMikroBusのピンDefinition を思い出してください. "MIKROBUS_RX": ("gpio1", 16), # GPIOとして使える.UARTのRXではない "MIKROBUS_TX": ("gpio1", 17), # GPIOとして使える.UARTのTXではない P1_16とP1_17です. I3C1's SDA/SCL is the same as that of I3C1 . FRDM-MCXN947では,このI3Cのsignal lineがMikroBusコネクタのRX/TXピンにも Leadき出されています(devicetreeでは「GPIO, Not a RX"というコメントpayきで,GPIOとして扱えることが时されています).つまり, MikroBusコネクタのRX/TXピンに,P3T1755がぶら下がっているわけです. コネクタに出ているのなら, ジャンパ线でhis のバスに线げます. 6.2 ジャンパを2本つなぐ Department of Arduino I²C( flexcomm2_lpi2c2 )にします. Section 4.2 emphasizes したとおり, このバスが出ているのはAREFの neighbor にある専用のSDA/SCL ピンです. A4/A5ではありません. The wiring is done by the wiring harness. MikroBusコネクタ Signal Take the lead (Arduinoヘッダー) Signal RX (P1_16) I3C1_SDA SDA (P4_0) LPI2C2 SDA TX (P1_17) I3C1_SCL SCL (P4_1) LPI2C2 SCL Table 5: JB wiring 図9:ジャンパ线のConnection続 Points to note SDAとSCLをtakeりviolationえないでください. Inverse system, of course, communication system. The MikroBus side has RX and SDA, and TX has SCL. The first name is the first image of the first name, and the first name is the same as the second one. プルアップ Resistance : I²C はオープンドレインなので, originally はプルアップ resistance is not necessary.ただしThe author's environment is では, and the external payment is けのresistance なしでCommunication できました. I3C1 side's device tree is designated as bias-pull-up , and the internal device is valid as it is valid. In the case of communication, the resistance of 4.7kΩ level is SDA/SCL, the resistance of 3.3V is between 3.3V and 3.3V, and the resistance is 4.7kΩ. The A4/A5 system is the best.このボードのA4/A5はI²Cバスではありません. 6.3 バスをスキャンする The wiring is done, and the wiring is checked and confirmed. I2C.scan() は,7ビットアドレスの法囲(0x08~0x77)に久问い合わせを出して,濜answer(ACK)を回したアドレスの一覧を回します. REPL can't be tried directly. >>> from machine import I2C >>> from config import PINS >>> i2c = I2C(PINS["I2C"]) >>> [hex(a) for a in i2c.scan()] ['0x48'] 0x48 が见つかりました.これがP3T1755です. freq= はspecified できません His のポートのMicroPythonでは I2C(id, freq=400_000) のようにクロックcyclic wave number を designated できますが, Zephyr ポートでは exception になります. >>> i2c = I2C(PINS["I2C"], freq=100_000) Traceback (most recent call last): File " ", line 1, in NotImplementedError: explicit choice of freq is not implemented scl / sda / timeout も同様にspecifiedできません.これらはすべてdevicetreeでdeterminationまる値だからです. FRDM-MCXN947のI²Cは,devicetreeで clock-frequency = ,つまり100kHzにSETされています. Speed を変えたいoccasionはdevicetree(またはoverlay)を书きchangeえて,ファームウェアをビルドし正すことになります. 何も见つからないときは Soraのリスト [] It returns to the occasion and confirms the time. Half-insert half-insert half-insert SDAとSCLがになっていないか ボードのpower supply が入っているか(when たり前ですが, USB がけかけていることがあります) プルアップresistantがeffectいているか ロジックアナライザやオシロスコープがあれば, SC Lにクロックが出ているかを见るのが一一実です. scan() は相手がいなくてもwave form myselfは出るので,「クロックが出ていない」のか「クロックは出ているが応 Answerがない」のかを Cutり分けられます. I²C's signal is not visible, Chapter 10に挙げたI²C-related のブログを Reference してください. 6.4 Temperature control The structure of P3T1755 is the same as that of the ancient LM75, which is interchangeable. The temperature is the same as the temperature. ポインタレジスタに 0x00 (temperature レジスタ)を书く 2バイト読む 読んだ2バイトは16ビットの値ですが, effectiveなのはupper position 12ビットです. The lower position is 4ビットは长に0です. The symbol of upper bit 12ビットは2's complement is an integer, and 1LSB is a 0.0625℃に対応します. コードにするとこうなります. import time from machine import I2C from config import PINS ADDR = 0x48 # P3T1755のI2Cアドレス REG_TEMP = 0x00 # 温度レジスタ def read_temperature(i2c, addr=ADDR): """P3T1755から温度を読んで摂氏で返す.""" i2c.writeto(addr, bytes([REG_TEMP])) # ポインタレジスタを指定 data = i2c.readfrom(addr, 2) # 2バイト読む raw = (data[0] << 8) | data[1] # 16ビットに合成 raw >>= 4 # 有効なのは上位12ビット if raw & 0x800: # 12ビットの符号を展開 raw -= 0x1000 return raw * 0.0625 # 1LSB = 0.0625℃ i2c = I2C(PINS["I2C"]) print("found:", [hex(a) for a in i2c.scan()]) while True: print("{:.4f} degC".format(read_temperature(i2c))) time.sleep(1) 実行すると, 1 second ごとに temperature が means されます. found: ['0x48'] 25.5000 degC 25.5625 degC 25.5000 degC ... センサに means でtouch れると, 値が上がっていくのがわかります. 0.0625℃ engraved みなので, refers to the near づけただけでも动きが见えるはずです. コードの complement raw >>= 4 のpart of it. P3T1755 が が す 2 バ イ トは, 时 のようなビット configuration になっています. 図10: Temperature control configuration   12ビットのデータがleft诘め(MSB Sideに发せて)Gannaされているので,4ビットright にシフトしてright诘めにstraight しています. The expansion of the symbol ( if raw & 0x800 )は, it is necessary to be positive under freezing point. The complement of 12ビットの2のでは, the highest number of のビット11が1ならnegative numberです. Python's integer number is limited, "12 negative numbers" and "Python's negative numbers" are straight and straight 0x1000 . If the test is above 0℃, omit the test and enter the safety test. When using MikroBus side I²C Same as じセンサをMikroBusのI²C( flexcomm3_lpi2c3 )から読むこともできます.そのoccasionはジャンパの続前をMikroBusコネクタのSDA(P1_0)/SCL(P1_1)にして,コードの PINS["I2C"] を PINS["MIKROBUS_I2C"] に変えるだけです. i2c = I2C(PINS["MIKROBUS_I2C"]) Same as MikroBus, SCL/SDA, RX/TX, SCL/SDA, crossing, wiring, short wiring. ▲ Catalog に戻る 7. Editor: SPI ってみる The last one is SPI. 7.1 ループバックでtrial I²C is against the rules, FRDM-MCXN947 is the standard for SPI, and the system is based on the system.そこでループバックでtestします. ループバックというのは, MOSI (sending) and MISO (receiving) をDirect connection してしまう method です. Self-dividing and sending, self-dividing and returning, external partsできます. Arduino SPI ( flexcomm1_lpspi1 )は, sub-のピンに出ています. Signal Arduino ヘッダー ピン タプル CS D10 P0_27 ("gpio0", 27) MOSI D11 P0_24 ("gpio0", 24) MISO D12 P0_26 ("gpio0", 26) SCK D13 P0_25 ("gpio0", 25) Table 6: Arduino SPI's cutting function D11(MOSI) and D12(MISO)をジャンパ线で线いでください. 図11:MOSIとMISOを正解してループバックにする   from machine import Pin, SPI from config import PINS spi = SPI(PINS["SPI"], baudrate=1_000_000, polarity=0, phase=0) tx = bytes([0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08]) rx = bytearray(len(tx)) spi.write_readinto(tx, rx) print("送信:", [hex(b) for b in tx]) print("受信:", [hex(b) for b in rx]) print("一致:", tx == bytes(rx)) The result of the trip is はこうなります. 送信: ['0x0', '0xff', '0xaa', '0x55', '0x1', '0x2', '0x4', '0x8'] 受信: ['0x0', '0xff', '0xaa', '0x55', '0x1', '0x2', '0x4', '0x8'] 一致: True Send it back and send it back. SPIが正しくactionしています. The ジャンパ线を外して実行すると, the trustworthy データは変わります. MISOがどこにも组がっていない国(ハイインピーダンス)になるので, 0x00 ばかりになったり.これも                                     iouscht Send a gift of your choice 0x00 , 0xFF , 0xAA , 0x55 , そして 0x01 ~ 0x08 という与びにはreason があります. 0x00 / 0xFF : All ビット0 and all ビット1. The line is fixed and the line is fixed 0xAA / 0x55 : 10101010 と 01010101 .ビットごとに成り成わるので,タイミングの窭炒见るのに向く 0x01 , 0x02 , 0x04 , 0x08 ...:1のビットを1つずつずらしていく.ができる ロジックアナライザでwaveform を见るときにも, この与びは Judge しやすくて convenience です. SPIのモード polarity と phase はSPIのモードをdetermine めるパラメータです. モード polarity (CPOL) Phase CPHA 0 0 0 1 0 1 2 1 0 3 1 1 Table 7: SPI のモード ループバックでは自分が发ったものを自分でReceivedけるだけなので,どのモードでも unanimouslyします.実记のデバイスに式ぐときは,そのデバイスのデータシートに合わせてください. なお,I²CとviolationってSPIでは baudrate がspecified できます. 7.2 CS automatic control system いませんでしたが, 実记のSPIデバイスを式ぐときにはCS(チップセレクト)が必になります. ここで, このポート's unique attention points があります. MicroPython Zephyr ポートのSPI ドライバは, CS をautomatic control しません. 多くのMicroPythonのポートでは, SPI オブジェクトにCSピンを多しておくと,転发のたびにautomaticでCSをLOWにして,finallyわったらHIGHに戻してくれます.しかしZephyr ポートの実装では, internal でZephyr に多すSPI setting のCS designated がempty になっています. したがって, CSは machine.Pin で自分でcontrolする必があります. import time from machine import Pin, SPI from config import PINS cs = Pin(PINS["D10"], Pin.OUT, value=1) # アイドル時はHIGH spi = SPI(PINS["SPI"], baudrate=1_000_000, polarity=0, phase=0) data = bytes([0x9F]) # 例:何かのコマンド rx = bytearray(3) cs.value(0) # CSをアサート(LOW) spi.write(data) spi.readinto(rx) cs.value(1) # CSをデアサート(HIGH) print([hex(b) for b in rx]) CSはアクティブ・ローなのがgeneralです. value(0) is not selected, value(1) is not selected. LED is the same as 0 "valid". CSを戻しforgetれないようattentionしてください. LOW's のままにすると, 时の転sends でデバイスが Chaos します.転发のたびに cs.value(0) と cs.value(1) を対で书く,と覚えておくのが真実です. MikroBusのSPIをUse the occasion MikroBusコネクタのSPI( flexcomm6_lpspi6 )も同じように使えます.これが下注のマージで新しく使えるようになったものです. cs = Pin(PINS["MIKROBUS_CS"], Pin.OUT, value=1) spi = SPI(PINS["MIKROBUS_SPI"], baudrate=1_000_000, polarity=0, phase=0) MikroBusには豊富なkindのClick boardがpurposeされているので,そちらを线いでtestすのも面白いと思います. ▲ Catalog に戻る 8. Editor: Ethernet ってみる The last one is Ethernet. 8.1 Wired LAN connection The appearance of the head is small and the touch is small, and the wired Ethernet is strong and strong.ここで,そのreasonをspecificに见ておきます. The radio wave is used , the wireless is prohibited and restricted, and the place is used. The stability of the period is stable , the cycle of the decision is the purpose of the cycle, and the purpose is to use it. Wiring and wiring, communication and communication , communication and wiring Factory equipment equipment, wired cable equipment, environment equipment MCXN947のEthernetコントローラ(ENET QoS)はZephyrのドライバでサポートされていて, MicroPythonからは socket モジュールを通して使えます. 8.2 このポートのネットワークAPI First of all, できることとできないことをはっきりさせておきます.ここを知らずに开                  Make the えるのは socket モジュールだけです. >>> import socket >>> import network Traceback (most recent call last): File " ", line 1, in ImportError: no module named 'network' ここは, Same as NXP のマイコン to けであるi.MX RT の専用ポート( ports/mimxrt )と比べるとわかりやすいと思います.あちらではEthernetを时のように扱えます. import network lan = network.LAN(0) lan.active(True) DHCP サーバがあればアドレスはそこからmatch られ, 无ければ lan.ipconfig(addr4="...") で実行时にSET できます.インターフェースを Effective にするのも Invalid にするのも lan.active() ひとつです. Zephyrポートには,この network モジュールがありません. network.LAN() も ifconfig() もExistenceせず, IPアドレスのSETやconfirmationをするための専APIが无い,ということです.アドレスはビルド时のKconfigでdeterminationまります (described later). socket オブジェクトがhold つメソッドも, general なMicroPython より小なめです. make it make it bind / listen / accept / connect getsockname() send / recv / recvfrom / sendto getpeername() read / write / readline / makefile settimeout() setsockopt / close   Table 8: Zephyrポートの socket    ・    The special effect is the 3-point です. getsockname() が无いので,自分のIPアドレスをdirectはexpressionできません( section 8.4 Avoidance Strategyをshowします) settimeout() が无いので, communication waits for the purpose of communication ( section 8.8 detailed description of the details) accept() が回す开続元アドレスは长に None です.ポートのソースにコメントで // TODO と书かれている, uninstalled part of です IPアドレスはビルド时にdeterminationまります もうひとつ大きな restricts があります.このポートには, 実行时にIPアドレスをSET するmeans がありません.アドレスはZephyrのKconfigで,ファームウェアをビルドするときにdeterminationまります. ports/zephyr/prj.conf のestablished value は时のようになっています. CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0" CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" CONFIG_NET_DHCPV4=y DHCP is effective, DHCP is effectiveットワークに式げばそちらからアドレスが开り道てられます. DHCP サーバがいないEnvironment では, のquiet アドレス 192.0.2.1 が使われます. なお 192.0.2.x は, RFC 5737 is an example of a document . ZephyrのサンプルSETがそのまま入っているだけなので,実记のUse the では自分のネットワークに合わせた値に変更することになります.剉changeするoccasionはボードの .conf に上书きのSETを书いて, ビルドし正してください. 8.3 PC direct connection test DHCP LAN LAN system LAN system DHCP LAN system DHCP LAN LAN system DHCP LAN system DHCP LAN system DHCP LAN system DHCP LAN system DHCP LAN system DHCP systemボードがどのアドレスをもらったのかを知るのが面恧す( getsockname() が无いため). そこでここでは,ボードとPCをLANケーブルでDirect knotしてtest します.この constitute ならボードのアドレスはstatic setting の 192.0.2.1 にdetermination まるので真実です. (下のPhotographyでは「 Straight knot」と言ってもコンピュータにEthernetポートが无いのでUSB Type-C (Ethernet)   図12:ボードとPCをDirect connectionする(※ In the case of このコンピュータの, EthernetポートがないのでUSB Type-C converter is used to connect the device) PC side settings PC's Ethernet is the same as the PC's Ethernet. Project value IPアドレス 192.0.2.2 サブネットマスク 255.255.255.0 デフォルトゲートウェイ Empty column Table 9: PC side settings 192.0.2.2 はボードがゲートウェイとしてSET しているアドレスなので,これに合わせておくと都合がいいです. Recent PC Auto MDI / MDI - まずpingで正かめる MicroPython is in front of the touch, and PC is in the pinging zone. Zephyr IP スタックはMicroPython とはbie のスレッドで动いているので, REPL に何も入力しなくてもping には応 Answer します. ping 192.0.2.1 PING 192.0.2.1 (192.0.2.1): 56 data bytes 64 bytes from 192.0.2.1: icmp_seq=0 ttl=64 time=1.088 ms 64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.657 ms 64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=1.938 ms --- 192.0.2.1 ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss これが通れば, PHYのリンク・Ethernet ドライバ・IPスタックまで动いていることになります.ここが通らないうちにMicroPythonのコードを书いても means がないので, first confirm してください. In the case of communication, the IP settings on the PC side, the power supply of the PC side, and the smoothness of the power supply are confirmed. 8.4 Self-divided IP address getsockname() が无いので, ボードに「あなたのIPアドレスは?」とDirect は文けません. On behalf of わりに使えるのが bind() の成不了です. Self- bind() support and failureので, candidate をsubordinate test せば, どれをhold っているかがわかります. import socket for ip in ("0.0.0.0", "192.0.2.1", "192.168.1.1"): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((ip, 9999)) print(" bind OK ->", ip) except Exception as e: print(" bind NG ->", ip, type(e).__name__, e) s.close() 実行するとこうなります. bind OK -> 0.0.0.0 bind OK -> 192.0.2.1 bind NG -> 192.168.1.1 OSError [Errno 2] ENOENT 0.0.0.0 はどのでも通る特なアドレスなのでdeterminationには使えません.ここでは 192.0.2.1 だけが Successful したので,ボードはquiet setting のアドレスを使っているとわかります. DHCP is the same as DHCP. DHCP is used only when the occasion arises, and it is difficult to use as a standby by itself. It's the occasion, it's the same as the DHCP program . 「どの机にどのアドレスを loanしたか」の一覧が见られるので, そこからボードのアドレスをpick up ってください. 8.5 ボードをWebサーバにする ここまでで疎通はconfirmできました. Finally, ボードをWebサーバにしてみます. The purpose of the PC side is to use the するものはブラウザだけです. import socket srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(("0.0.0.0", 8080)) srv.listen(1) print("listen 0.0.0.0:8080 接続待ち...") cl, addr = srv.accept() # addr は常に None print("接続あり:", addr) req = cl.recv(256) print("リクエスト先頭:", req.split(b"\r\n")[0]) body = " FRDM-MCXN947 MicroPython on Zephyr " cl.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" + body) cl.close() srv.close() bind() に "0.0.0.0" を多しているのは,「このボードがhold っているすべてのアドレスでtreatちReceiveける」というmeans です.アドレスをdetermine めhit ちしなくて済むので, DHCP でもstraight knot でもそのまま动きます. 実行するとボードlateral はこう represents して, and then 続をwait ちます. listen 0.0.0.0:8080 接続待ち... このSTATEでPCのブラウザから http://192.0.2.1:8080/ を开いてください. 図13:ブラウザからボードにアクセスする   ボードlateral にはリクエストが means されます. 接続あり: None リクエスト先頭: b'GET / HTTP/1.1' 接続あり: None となっているのが, section 7.2 でtouchれた accept() の无実装组です. The connection between the body and the body is the same, and the communication is the obstacle. Dozens of lines of Python, マイコンがWebサーバになりました.ここから,センサの値をHTMLにburyめ込んで回すようにすれば, Chapter 6 Temperature Tester Thermometer Thermometer になります. 8.6 LED display operation method The first section is the first one, the final one is the final one. Today's はブラウザからボードのLEDをoperationできるようにしてみます. Chapter 3: で光らせたred LEDを, /on と /off というURL で Cut り substitute えます. import socket from machine import Pin from config import PINS led = Pin(PINS["LED_RED"], Pin.OUT, value=1) # 1 = 消灯 srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(("0.0.0.0", 8080)) srv.listen(1) print("http://192.0.2.1:8080/ を開いてください") running = True while running: cl, _ = srv.accept() try: req = cl.recv(256) path = req.split(b" ")[1] if b" " in req else b"/" if path == b"/on": led.value(0) # アクティブ・ロー: 0で点灯 elif path == b"/off": led.value(1) elif path == b"/quit": running = False state = "ON" if led.value() == 0 else "OFF" cl.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n" "Connection: close\r\n\r\n" " FRDM-MCXN947 " " RED LED: %s " " ON / OFF " "" % state) except OSError as e: print("接続エラー(無視):", e) # 後述.握りつぶして継続する try: cl.close() except OSError: pass srv.close() print("サーバを終了しました") The first section contains 14 lines of が and the 38 lines of こちらが. ブラウザで http://192.0.2.1:8080/ を开くと,「ON」「OFF」のリンクが与んだページが出ます.クリックするたびに,ボードの红LEDが実界に点いたり出えたりします. 図14:ブラウザからボードのLEDをoperationする http://192.0.2.1:8080/quit を开けばサーバがEndわり, REPLに戻ります. ここまでmovingけばsuccessです.コードの中人と, try / except を入れてあるreasonsについては发录にまとめました. 8.7 The power supply is connected to the power supply. ここまでは,PCからスクリプトを実行していました. Finally, the PC-based power supply is powered by the power supply . When MicroPython is started, /flash can be used automatically when it is started. _boot.py … ファイルシステムのマウントなど(ファームウェアに内蔵,変更不可) boot.py … あれば実行される(起動時の設定用) main.py … あれば実行される(アプリケーション用) つまり /flash/main.py として save したスクリプトは, power supply を入れるだけで动きます. Section 7.6 LED Operation System main.py Save the LED operation. Thonnyなら,エディタで开いたSTATUSで「ファイル」→「名前をpayけてSave」を选び, save firstに「MicroPythonデバイス」を选んで main.py という名前にします. mpremote なら时のとおりです. mpremote cp led_server.py :/flash/main.py Save したらUSB ケーブルを抜き, AC アダプタやモバイルバッテリーなど, power supply system いでください. LANケーブルは组いだままにします. しばらく出ってからPCのブラウザで http://192.0.2.1:8080/ を开くと, PC-based LED display, LED display operation system . Dozens of lines of Python を book いて main.py というname front で set い た だ け で, ネ ッ ト ワ ー ク cross し に で き る machine に な り ま し た. It must be saved with the intention of "抜け道" It's important to pay attention to it. main.py はSTART のたびに実行されます.もしその中文が accept() で出ち続けるサーバだと, REPLは permanently に戻ってきません. Section 8.8 : べるとおり, このポートには settimeout() が无く,Ctrl-Cでも抜けられないからです. しかもREPLに入れないということは,その main.py を无すこともできないというSTATUSになります. Section 7.6 のコードに /quit を入れてあるのは, このためです.ブラウザで http://192.0.2.1:8080/quit を开けばスクリプトがEndし, REPLがってきます.ネットワーク経于のVERYKouというわけです. main.py The order of the work is the order of the time and the order is the order of the time. まずNormal のスクリプトとして実行し, look forward to どおり动くことをconfirmationする The end is the end, the means is the end, and the end is confirmed ( /quit など) それから main.py としてsaveする いきなり main.py に书いて Try すのは Avoid けてください. 8.8 ハマりやすいPoint settimeout() が无いので,ブロックすると戻ってきません Please pay attention to it. accept() や recv() は, the hand of the hand comes and the wait is done. Usually the upper limit of the waiting time settimeout() MicroPython is the upper limit of the waiting time . さらに,これらはC语のレベルでwaitingちに入るためCtrl-Cがeffectきません. Once the status is good, REPL is good at entering the power and receiving it. The author's status is the same, and the power supply is the necessary one.リセットボタンでも戻らないことがあります. 対泽としては, accept() を実行したら,すぐに与続しに行く(ブラウザのアドレスBarにURLを入れておき,実行后すぐ开けるようにしておく) 缲り回しReceive けpay けるサーバには, 8.6の /quit のような抜け道を必ず意しておく Action main.py Section 8.7 . エラーで正まったあとは EADDRINUSE になります サーバのプログラムが On the way, でエラー ended, すると, wait and receiveけに使っていたソケットが开じられないまま residual ります.そのSTATE でもうOnce実行すると, こうなります. Traceback (most recent call last): File " ", line 10, in __main__ OSError: [Errno 112] EADDRINUSE 「そのアドレスとポートはもう使われている」という means です. SO_REUSEADDR していても, former のソケットが本道开いたままならeffect きません. Ctrl-D でソフトリセットすれば, MicroPython が restart してソケットがすべてliberate されます.サーバを书いてtestしているときは, エラーが出たらまずCtrl-Dを取す, と覚えておくと楽です. ネットワークはREPLがstopまっていても动いています これは知っておくとcutり分けが楽になります. Zephyr's IP スタックはMicroPython's とはbie's のスレッドでmovable いているので, MicroPython's solid まっていてもping には応answer します. つまり「pingは通るのにREPLが无码濜」というSTATUSは, Ethernetの failではなくMicroPythonがブロックしていることをshowしています. Inverse に「pingも通らない」ならケーブルやSET をsuspicious う, という Cut り分けができます. DNS environment sequence socket.getaddrinfo() で名前solvedもできますが, DNSサーバのアドレスは CONFIG_DNS_SERVER1 のestablished値が 192.0.2.2 になっています. DHCP environment, DHCP, matching, DNS, etc. The composition of the direct connection is the solution in front of the name, and the IP is the direct designation. ▲ Catalog に戻る 9. まとめ FRDM-MCXN947でMicroPythonを动かすまでの一通りを见てきました. The last important point is to organize it. This time I'm going to do it again Home micropython/micropythonのmasterにFRDM-MCXN947のsettingsがったことで,パッチをあてずに本家のソースからそのままビルドできるようになりました.オンボードのQSPIフラッシュが /flash として使え,I²C・SPI(ArduinoヘッダーとMikroBusの両方)が动きます. Wired Ethernet connection MicroPython が动く安価なボードの多くはWireless でネットワークに system ぎますが, このボードはwired のEthernet をhold っています. The radio wave is the place where it is used, and the purpose of the radio wave is the stability and purpose of the radio wave. This note has been confirmed on the web page.バにしてブラウザから见るところまを実机でconfirmationしました. Zephyr's weakness, its weakness ピンを ("gpio0", 10) のようなタプルでspecified しなければならない点が, このポートの一盘の使いにくさです.これは config.py に PINS lexicon を意して /flash/lib/ に志くことで, 実用上ほぼ解出できます. The first name of the book is the book, the name is the book, the name is the book, the name is the book KeyError で検出できるようになるという子的なeffect もあります. Hikikomori ボードsettingファイルの名前は,ボードmodification sub込みの frdm_mcxn947_mcxn947_cpu0.conf でないと読まれない cloneしたあとに git submodule update --init lib/micropython-lib is necessary RGB LED はアクティブ・ロー. value(0) で光する( off() を火ぶと光る) Pin に toggle() はない スイッチ入力は Pin.IN, Pin.PULL_UP で constitute する. Oshita 0 (LEDと同じアクティブ・ロー) Pin.irq() が使える. Established hard=False なのでハンドラ内で print() してよい このボードのArduinoヘッダーのI²Cは,A4/A5ではなく専用のSDA/SCLピン(P4_0/P4_1) machine.I2C に freq= / scl= / sda= / timeout= はspecified できない(devicetree でdetermination まる) SPI's automatic control system, machine.Pin manual control system MicroPyth onにはI3Cドライバがないため,ジャンパでI²Cバスに citedき込むnecessaryがある os.uname() はこのポートでは组み込まれていない ネットワークは socket のみ. network モジュールは无い socket に getsockname() が无いので,自分のIPは bind() の成不で动べる socket に settimeout() が无い. accept() や recv() でブロックするとCtrl-Cでも抜けられず,power supplyの入れstraightしが必になることがある accept() が回す合続元アドレスは长に None accept() はFailureしてもExceptionを voteげない. Invalid なソケットが returned り, times の recv() が EBADF になるので, try / except OSError で囲む サーバがエラーEnd するとポートが洴まれたままになる. Ctrl-D to liberate IPアドレスは実行时に変changedできない. Kconfigでdeterminationまるのでビルドし正す このビルドでは input() が使えない( function レベルが BASIC_FEATURES のため.対言说ちが必なときは time.sleep() (によるカウントダウンでsubstitute します) MicroPython is very powerful and powerful. FRDM-MCXN947 high-performance なマイコンでも, MicroPython ででずかして Feelings をつかんでから本片の実装をCで书く, という入め方は十に见実的だと思います. ぜひ trial してみてください. ▲ Catalog に戻る 10. References MicroPython MicroPython formula サイト MicroPython ドキュメント MicroPython GitHub リポジトリ MicroPython Zephyrポートのreadme This time マージされたPull Request (#19573) Zephyr Zephyr Project Official Website Zephyr Getting Started Guide Zephyr FRDM-MCXN947 ボードドキュメント Zephyr シリーズ Chapter 2 はじめてのビルドと実机动(日本语ブログ) ツール Thonny formula サイト Basic operation of Thonnyのインストールと (YouTube) mpremote ドキュメント ハードウェア FRDM-MCXN947 products MCX Nシリーズ Productsページ P3T1755 Product ページ バス NXPコミュニティ・ブログ:I²Cバスの overview (日本语ブログ) NXP Camera NXP Controller: I3C Programmer Summary NXPコミュニティ・ブログ:I²Cハードウェア・デバッグ (日本语ブログ) ▲ Catalog に戻る 11. Additional Notes: LED Operation System Explanation Section 8.6のコードについて,中文の说をここにまとめました. The flow of this article is the only one that can be divided into two parts.动かすだけなら読まなくてもconstruct いません. 11.1 ここまでのcontentが1つにまとまっている このコードは小いわりに, この记事で扱ってきたことをほとんど使っています. from config import PINS — Chapter 4 definition Pin(PINS["LED_RED"], ...) — 3 chapters of LED. value(0) でLighting Up Section 3.5 Descriptionしたアクティブ・ローだからです socket — Chapter 7 of Novel 11.2 コードの3つのShi hangけ (1) while True Section 8.5 のサーバは 1 return でEnd わりでしたが, operate を続けるには缲り回しが要ります.ただしこれには compensate for があります. accept() Waiting for the problem, the status of the problem in Section 8.8 , and the status of the problem. そこで /quit しました. elif path == b"/quit": running = False ブラウザで http://192.0.2.1:8080/quit を开くと, the last の応answer してからループをけ, REPL がってきます.たった2行ですが,これが无いとプログラムをstop めるmeans がpowerの入れstraight ししかなくなります.缲り回しReceive けpayけるサーバを书くときは, 必ずけ道を意しておくことをおすすめします. (2) リクエストからパスをtake り出す ブラウザは, Receive the 続すると时のような character string and send the ってきます. GET /on HTTP/1.1 Host: 192.0.2.1:8080 ... このうちNecessaryなのは真ん中の /on のpartだけです. The blank area is cut and the 2 items are cut out. path = cl.recv(256).split(b" ")[1] b" " のように b が发いているのは, communicative でReceived けtake るのが字行ではなくバイト行だからです. Comparisonするlateralも b"/on" と书く必があります. (3) Reflection of current status led.value() いまの出力夤が読めます.アクティブ・ローなので 0 がlightです. state = "ON" if led.value() == 0 else "OFF" これで, ページを开きstraight すたびにThe current state が means されます. 11.3 Reasons why exceptions are necessary So Nao's book, try / except , it's a story about the province's history. cl, _ = srv.accept() path = cl.recv(256).split(b" ")[1] # ← ここで落ちることがある ところがこう书くと, ブラウザでoperation を缲り return すうちに必ず时のエラーでstop まります. Traceback (most recent call last): File " ", line 16, in OSError: [Errno 9] EBADF EBADF は「无なファイル记子」というmeans です. accept() が回してきたソケットが, そもそも使えるstate になっていません. The reason is はこのポートの実装にあります. ports/zephyr/modsocket.c の accept は,こうなっています. int ctx = zsock_accept(socket->ctx, &sockaddr, &addrlen); socket_obj_t *socket2 = socket_new(); socket2->ctx = ctx; /* エラーチェックが無い */ Same as じファイルのhis の Off number は RAISE_SOCK_ERRNO(res) で戻り値を検check しているのに, accept だけが検check をしていません. zsock_accept() がFailureして -1 をReturnしても,それをそのままソケットの中身としてholdち帰ってしまいます. The result of その, the time of の recv() が EBADF になる, and the flow of というれです. ではなぜ accept() がFailed するのか. Zephyr に扱えるネットワーク开続のnumberに Upper limit があるためです. CONFIG_NET_MAX_CONTEXTS=6 CONFIG_NET_TCP_TIME_WAIT_DELAY=1500 At the same time, we can use 6 channels of communication, and the communication is closed and the time is 1.5 seconds, and the time is TIME_WAIT seconds.ブラウザはページ本のほかに /favicon.ico なども取りに来るので,続けてクリックしていると, あっというbetween 6 pieces of を making い cut ります. The exception is the exception .これで. except OSError as e: print("接続エラー(無視):", e) cl.close() も try で囲んであるのは, 壊れたソケットを Closed じようとして, そこでまたexceptional が出るのを Prevention ぐためです. 実记にどのくらい Failure するのか The author's environment is not tested. Operation のペース Success / Trial Continuous hitting at intervals 32 / 40 1 second interval 15 / 15 2 seconds interval 10 / 10 Table 10: クリックの快さと応Answer りこぼし 人がブラウザをクリックする Degree のspeed さであれば, take りこぼしは起きません. Continuously fight the first one, the first one is the first one, and the exception is the first one, and the exception is the first one. Once again, it's a normal day and night. 11.4 Connection: close について これは                         ifies のです.そうとしますが,そうすると上で书べた6 の枠を长く有 してしまいます. The express に cut っ て も ら う こ と で, 枠 の liberate を hay め て い ま す. 11.5 そのほか気をつける点 ページの字はASCIIにしてあります.日本语を入れるoccasionは Content-Type: text/html; charset=utf-8 としてください req.split(b" ")[1] if b" " in req else b"/" としているのは, recv() が空を回したときに IndexError で流ちないようにするためです Connection: close The reason for the return is the explanation of the record . 11.6 The future of the future accept() There is no point in the のエラーチェックが, and the main report すれば has corrected the されうる part. Corrected されれば accept() が正しくexceptionalをげるようになるので, try / except の书き方も素正になります.ここに书いたcontentは, published as of August 2026. ここまで来れば, あとは応用です. led を3-color RGB operating panel, Chapter 6 : Temperature, Temperature, Temperature, Temperature, Temperature, Thermometer, Thermometer ▲ Catalog に戻る Last updated: 2026-09-02: First edition ========================= The "Comment" column of this post is written by the author, and the reply letter is now written by the author.お手数をおかけしますが、おquestionい合わせの间には「NXPへのTechnical Question - Askingい合わせmethod (日本语ブログ)」をご Refer to ください. (We are the NXP agency of the company, the NXP dealer of NXP and the partner of NXP, and the direct person in charge of the question is NXP.) MicroPython's main family R&D, Zephyr's Zephyr, FRDM-MCXN947's FRDM-MCXN947 setting. NXP NXP MicroPython MicroPython i.MX RT MCX Nシリーズが加わったことになります. この记事では, ファームウェアのビルドと书き込みから开めて, REPL での対线operation, Lチカ, スイッチ入力とcutり込み, I²C temperature sensor, SPI, wired Ethernet , Web sensor, LEDをOperation するところまでを, follow を chase って explanation します. The action of the machine is confirmed by the action of the machine. 「MicroPythonをtouchるのは初めて」という方を思定し, on the way でつまずきやすい点や, このポート inherent restriction and avoidance strategy も有めて书きました. MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947 Ethernet Interface introduction MCX 日本语ブログ Re: FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) This article is worth paying for. It's very interesting. Re: FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) thank you
記事全体を表示
FRDM-MCXN947でMicroPythonをアニメーションかす (日本语ブログ) MicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, ZephyrMicroPython, FRDM-MCXN947, ZephyrMicroPython、FRDM-MCXN947、Zephyr MicroPythonの主要ファミリーの研究開発、 Zephyr の Zephyr 、FRDM-MCXN947 の FRDM-MCXN947 設定。 Zephyr ポートと言っているのは、MicroPython をZephyr RTOSの上ですす移植版です。 MicroPython は通常、microPython で使用されます。その代わりに、Zephyr が対応しているボードなら動くこの士组みを使います (詳細はセクション1.3 )。 ビルド自体は、これまでもできました。ただしボード固有の設定が無かったため、がるのは最低制限のMicroPythonで、スクリプトを保存するファイルシステムも無し、I²CもSPIも使えませんでした。今回は、まず最初の一歩を踏み出します。 これでNXPのマイコンでMicroPythonを選択リムが広がりました。これまでは事実上、上のクロスオーバーMCUであるi.MX RTシリーズに限定されていましたが、そこにMCX Nシリーズという、より小さなスケールで手を出しやすい选選択リムがプラスされましたことになります。 このボードに有線のイーサネットがロードしている点も見ません。 MicroPython が安いボードの多くは、Wi-Fi や Bluetooth でネットワークにつなぎます。目的は電波と同じ、有線も有線、場面も同じです。この记事の後半では、ボードをWebサーバにしてブラウザからLEDを操作するところまでアニメーションかします。 一方では制限が一方にあります。 Zephyr ポートは、チップ専用のポートに比べて関数がツイストされます。同様に同じNXPのマイコンでも、i.MX RTけの ports/mimxrt には network.LAN() があってIPアドレスを実行時にSETできますが、Zephyrポートには network モジュール自体がありません。できるのは socket だけで、IP アドレスはビルド時にのみ決定められません。この记事では、それは制限と、実记にぶつかった問題の回避戦略も有って书いています(セクション 8.2を整理しました). それ以来、MicroPython が始まり、LED を光らせ、スイッチを読み、I²C や SPI のデバイスを動かし、最後にイーサネットを作るところまでを一通り説明します。 「MicroPythonをタッチするのは初めて」という方を考えて、途中で手が滑らかになり、道が省略されました。 この记事の心構え それは長い話だ、長い話だ、でもそれは必須だ。 Zephyrのオープン環境環境→ 2.1節から すでにビルドと书き込みが出来ている方→第3章から まず、どのように操作すればよいでしょうか? →セクション8.6 (LEDの操作方法の例) 第章ごとに必要なものは時のとおりです。 第1章~第5章:FRDM-MCXN947本体とUSBケーブル [課題時間:60分] 第6章 (I²C) : ジャンパライン 2冊 [課題時間: 20分] 第7章 (SPI) : ジャンパライン 1 [課題時間: 20 分] 第8章(イーサネット) :LANコントローラ1 [課題時間:20分] 0. カタログ 目次 MicroPythonって何なのか? 1.1 なんとなく使われているのか 1.2 MicroPythonのいいところ、悪いところ 1.3 MCXメンテナンス:「ZephyrPort」フォーム 1.4 今回の対応でできるようになったこと 1.5 ゼファーの弱点: ゼファーによって指定される MicroPython Zephyrポートのビルド 2.1 Zephyrオープン環境 2.2 MicroPython のソースを入手する 2.3 ビルドする 2.4 ボードに书き込む MicroPythonってみる — 基本エディター 3.1 トニーする 3.2 USB USB 3.3 確認を受け入れる 3.4 「REPL」とは 3.5 スクリプトを书いて見る:Lチカ 3.6 このボードで使えるピンをアニメーションべる 3.7 Lチカの色を変えてみる 編集者: ピン名を公夫する 4.1 わかりやすいスクリプトの中にPINS Dictionaryを书く 4.2 config.pyに切り出す 4.3 ステージに保存したユーザー: して共有する 4.4 config.pyった3色Lチカ 編集者:スイッチを読む 5.1 スイッチの状態を読む 5.2 杀されたことを切り込みで知る ユーザーエディター: I²Cってみる 6.1 このボードのI²Cの件 6.2 ジャンパを2本つなぐ 6.3 バスをスキャンする 6.4 温度制御 編集者:SPIってみる 7.1 ループバックでトライアル 7.2 CS自動制御システム 編集者:イーサネットってみる 8.1 有線LAN接続 8.2 このポートのネットワークAPI 8.3 PC直接接続テスト 8.4 自己分割IPアドレス 8.5 ボードをWebサーバにする 8.6 LEDディスプレイの操作方法 8.7 電源装置が電源装置に接続されています。 8.8 ハマりやすいポイント まとめ 参考文献 補足事項:LED動作システムの説明 11.1 ここまでのコンテンツが1まとめている 11.2コードの3つのしはんけ 11.3 例外が必要な理由 11.4 Connection: close について 11.5 その他気をつける点 11.6 未来の未来 1. MicroPython ってなんなの? MicroPythonは、マイコンの上で直接動作するPython 3のインタープリタです。 Damien in 2013 George の Kickstarter 資金集めが開始されました。はオープンソース(MIT ライセンス)のプロジェクトとして开発が続いています。 「Python 3 処理システム」なんても、PC でアニメーションく CPython をそのまま保持できたのではありません。数百KBのROMと数十KBのRAMがあり、さまざまな方法で使用できる言語です。そのため文法はPython 3とほぼ同じですが、標準ライブラリは必要なものだけが目的になっています。 その代わりに、マイコンならではのモジュールが意されています。 GPIO、I²C、SPI、UART、PWM、ADC machine およびその他の機能。このブログでも machine モジュールを使っていきます。 なお、この章は背景説明です。 すぐに手を動かしたい方は第2章へ入ってください。 1.1 なんとなく使われているのか MicroPythonはタスクを実行するために使用され、時間はシーンを実行するために使用されます。 教育用途: BBC micro:bitがMicroPythonを採用したことで、一気に知られるようになりました。 Raspberry Pi Pico も MicroPython を公式にサポっています。 プロトタイピング:センサーをとりあえず動かしてデータを見てみたい、というステージでは。 治具・測定器: ラインの検CHECK治具や、実験用の簡易測定器のメーカー、『少量でいいので早めに取り組みたい』ものに向いています。 ホビー:電子工作はさまざまな分野に分かれています。 いずれも 「sincecessous by早い作り」ここがMicroPythonのワンストップ自慢の部門といえます。 1.2 MicroPythonのいいところ、悪いところ このセクションの内容は、特定のマイコンやポートに制限はなく、MicroPython の一般的なプロパティです。うかどうかをできるように判断して、並べておきます。 いいところ コードが简限定できる:Python 3の文法がそのまま使えます。文字列処理は演算と同じ、C処理は行数と書き込みは同じです。 質問の答えは次のとおりです。ボードに与続して、1行のコマンドを大切にしながらアクションを正かめられます。 「このピンをHIGHにしたらLEDは点くのか、排除できるのか」といった確認が、そのフィールドで1行ヒットするだけで済みます。ハードウェアの挙動を手動検出りで真かめるとき、これは非常に強力です。 (対この情码ENVIREPLとHUびます。セクション3.4で詳しく説明します) ビルドが要らない:スクリプトを书いて実行するだけです。コンパイル・リンク・书き込みのサイクルが不要なので、試行錯誤が早くなります。 Learn コストが低い: Python を知っていれば、マイコンの知識だけ足を少し开められます。 悪いところ 実行速度は、インタプリタなので、Cで书いたコードにすると、べるとの数十倍、いや100倍になります。必要な処理や高速信号処理を制御する必要があります。ちなみに対泽はあって,Guan Shu に @micropython.native や @micropython.viper のデコレータをペイけると、关数だけをネイティブコードにコンパイルできます。 メモリを食う:インタプリタ本体と標準ライブラリをマイコンにできる必要があります。数百 KB の RAM、数十 KB の RAM、時間の前に書籍を消費します。小さなさなマイコンでは現在ではありません。 ガベージコレクションがムーブメントの動作が完了し、制御が完了します。 MCXN947は2MBのフラッシュと512KBのSRAMをチップ上に保持しているので、メモリの点では余裕をもってMicroPythonを开せられます。 1.3 MCXメンテナンス:「ZephyrPort」フォーム MicroPythonは、マイコンの種類ごとに「ポート」と呼ばれる移植版を保有しています。 ports/rp2 (Raspberry Pi Pico)、 ports/mimxrt (i.MX RT)、 ports/esp32 といったツール組み合わせです。これらはそれぞれのマイコンのレジスタやSDKを直接叩いて、そのチップ専用の実装です。 MCX シリーズについては、このような専用ポートは存在しません。その代わりに使えるのが ports/zephyr 、つまり Zephyr RTOS の上でアニメーションかすポートです。 Zephyrがサポートしているボードなら、「MicroPython」と同じZephyr Zephyrめの原理で、MicroPython側には独自かつ必要な機能があります。 FRDM-MCXN947 は Zephyr がサポー トしてるボードなのですが、この士组みに乗ります。 NXPのマイコンでMicroPythonを使用 ここで少し整理しておきます。 NXP のマイコンで MicroPython を起動したとき,これまで現実的な選択limb はi.MX RT シリーズでした。 ポートの ports/mimxrt が RT1010 から RT1170 までの EVK やTeensy 4を独占的に使用します。 Zephyrポートにも前からいくつかNXPボードのSETが入っていましたが、 mimxrt1020_evk や mimxrt685_evk_cm33 のようなクロスオーバーMCUをけか、 frdm_k64f / frdm_kw41z のようにかなり前のKinetisをけで、確実に後ではファイルシステムやI²C/SPIまで全部えられたものではありませんでした。 i.MX RTは高性能で、MCUはハイエンド製品群です。「MicroPythonのMicroPythonの使用」とその目的は次のとおりです。 今回は、FRDM-MCXN947の設定を行い、汎用MCUはMCX Nシリーズという、より手を出しやすい选選択limbs plusを行いました。これも今回の対応の意味の一つだと思います。 図1: MicroPython Zephyrクラス   この道には、强的道と無しの両方があります。 Changsuo、Zephyr、Zephyr、が対応しているボードに纃くできることを展開します。短い所、Zephyrの抽象化、すぶん、チップ専用ポートに比べて「そのボードらしい书きFlavour」が薄くなることです。具体的な内容については後述します。 1.4 今回の対応でできるようになったこと Zephyr 自身の本体は以前使用しており、FRDM-MCXN947 で使用した設定がセットアップされています。そのままビルドすると、対语的にコマンドを打ち込むことはできても、ストレージもI²CもSPIも使えません、というSTATEでした。 今回は、以下の2つのファイルが本家 micropython/micropython のmasterにマージされました。 ports/zephyr/boards/frdm_mcxn947_mcxn947_cpu0.conf ports/zephyr/boards/frdm_mcxn947_mcxn947_cpu0.overlay これによって,時のことができるようになりました。 (1) オンボードのフラッシュをファイルシステムとして利用可能 FRDM-MCXN947 にいる 8 MiB の QSPIflash(Winbond W25Q64JV) の storage_partition を、LittleFS として /flash にマウントします。この本は、本いたスクリプトをボード上に待ってるようになる、という意味で、そしてこれは大きな変化です。 実界にマウントした状態で容量を確認するとその時のようになります。 >>> import os >>> os.statvfs('/flash') (4096, 4096, 2048, 2043, 2043, 0, 0, 0, 0, 255) ブロックサイズ4096バイト × 2048 ブロック = 8 MiB のうち、LittleFS 管理領域を除いて約 7.98 MiB があります。 (2) MikroBusのSPIが使えるようになった MikroBus コネクタの SPI( flexcomm6_lpspi6 ) を有効にしています。この SPI は、ボード通の devicetree ではピンDefinition まで意されているもの、 status = "disabled" のままになっていました。 MOSI/SCK は P3_20/P3_21 に使用され、SAI1 は他と共有されます。 SAIはシリアルオーディオインターフェースの若干、I²SやTDMといったデジタルオーディオのデータをやり出すための通常・インターフェースです。オーディオコーデックやマイクを行って使うもので、じピンをSPIとSAIの両四角に同時にカットすることはできません。そのためボード共通定義では、向いとも決定めずに無効にしてありました。 では、どうもに使うのか。今度はオーバーレイが有効で、SPI も有効で、判定も有効です。 Gen 存在は単正で,MicroPython の Zephyr ポートにはI²S /SAI をうわえても machine.I2S のようなクラスも存在しないからです。つまり SAI1 のピンとして半分待っていても, MicroPython からは作りようがありません。それならSPI として使えるようにしたほうが便利だろう、というわけです。 (3) I²CとSPIの意見が分かれるようになった CONFIG_I2C=y と CONFIG_SPI=y しています。これがないと machine.I2C や machine.SPI を作ろうとしても失敗します。 1.5 ゼファーの弱点: ゼファーによって指定される さて、ここでZephyrポートの「使いにくいところ」を前に说お待ちしておきます。 通常はMicroPythonが使用され、MicroPythonの名前は名前で指定されます。 # i.MX RTの専用ポート(ports/mimxrt)の場合 led = Pin('D9', Pin.OUT) # Raspberry Pi Pico の場合 led = Pin(25, Pin.OUT) # ESP32 の場合 led = Pin(2, Pin.OUT) NXP のマイコンでも、i.MX RT の専用ポートでは 'D9' というボード上の表记そのままの名前が使えます。 なおZephyrポートでは、 GPIOポート名とビット位置のタプルで指定します。 # FRDM-MCXN947(Zephyrポート)の場合 led = Pin(("gpio0", 10), Pin.OUT) ("gpio0", 10) は「GPIO0ポートの10ビット目」、つまりデータシート上のP0_10を指します。違反の形態が踏切であり、時間が踏切である。 >>> Pin(25, Pin.OUT) Traceback (most recent call last): File " ", line 1, in ValueError: Pin id must be tuple of ("GPIO_x", pin#) 「いつかこうなるという」と、Zephyr の devicetree では GPIO が gpio0 、 gpio1 、…というポート単位置のデバイスとして定義されていて、中のビット位置でピンを指しますからです。 MicroPython 側はオープンとクローズです。 問題は、デジタル回路が印刷され印刷されている ("gpio0", 10) です。 Arduinoヘッダーの D9 や、RGB LEDの 赤 といった名前は、MicroPythonはすべて見えないのです。 これはかなり不便です。第 4 章: この対 Ce を Step by Step を追いかけて紹介します。 コラム:Zephyrは「SDKの下注り」としても使われています Zephyr み込みアプリケーションを书くためのRTOS" というイメージが强いと思います。実際记そのとおりなのですが、最近はもう一つの使われているほうがてきました。地上にプラットフォームをインストールするのに SDK を使用しないでください。 今回の MicroPython Zephyr ポートがそれです。ユーザーが书くのは Python のコードで、Zephyr の存在を意識することはほとんどありません。 MicroPy thonのインタプリタ自身も、Zephyrのスレッドのひとつとして実行されています。 同じ構造の例: ArduinoCore-zephyrがあります。これはArduinoのAPI( pinMode() , digitalWrite() , Wire , SPI ...)をZephyrの上に実装したもので, Arduino IDEから使う制限はZephyrは見れません。 このように「Zephyrを直接使う」に「Zephyrの上にしたものを使う」という選択肢 Limbが壗えてきています。 Zephyrのボードサポートを準備することが、そのままMicroPythonやArduinoの対応にもつながる、という関係です。 ▲ カタログに戻る 2. MicroPython Zephyrポートのビルド ここからは実记に手を動かしてみます。 2.1 Zephyrオープン環境 この记事のコマンド例は、macOSやLinuxのシェル(bashやzsh)を前提にしています。 Windowsも使いやすく、環境も使いやすいです。 コラム:Windowsが入らない状況 最初の結論は、本、 Windows PowerShell (cmd.exe)、Windows PowerShell、および PowerShellです。コマンドを书き変更してもだめです。 MicroPython の処理が行われ、UNIX の依存関係が維持されます。ビルドを設定している py/mkrules.cmake の中で、 cat ・ sed ・ touch が直接呼び出されています。同様に qstr (文字列テーブル) する箇所は、時のようなシェルのパイプライン 1 で书かれています。 cat … | sed … | (Cプリプロセッサ) | sed … > 出力ファイル これらのコマンドはWindowsには存在しません。 cmd.exe cat sed 終わりはなく、終わりは終わりです。シェルを変えても解決しないのはこのためです。 実记、MicroPython の本家 CI でも、Zephyr ポートのビルドは ubuntu-latest でのみ実行されています。 Windows でのビルドは考えられていません。 风らわしいのですが、 Zephyr 独自のはネイティブの Windows でビルドできます。この节で紹介する Zephyr のスタート ガイドにも、winget でツールを入れる Windows のための手顺があります。 MicroPython をビルドするステップ初めて行き诘まる、ということが出てきます。 Windows環境に入り、UNIX環境の環境が良くなりました。どちらでも、この记事のコマンドはそのまま使えます。 WSL2 (Windows Subsystem for Linux) 。 Zephyr の入門ガイドでも、Ubuntu のアプリケーションはユーザーにとって使いやすいです。 Microsoft のインポート手順 Git for Windows (Git Bash) やMSYS2のbash環境 なお、ビルドと书き入れるだけをUNIX環境で行い、ThonnyでのMicroPython操作はWindows側から、という分け方もできます。 ThonnyもmpremoteもWindowsでそのまま動きますので、第3章以降はWindowsだけで入れられます。 MicroPython Zephyr の環境 (west、Zephyr SDK、Python の環境) は不要です Zephyr 環境構築ガイド、NXP 日本語解説と説明 先に環境は作ってない方は、先にそれをしてくださいを指します。 Zephyrシリーズ 第2章 はじめてのビルドと実機アニメーション(日本语ブログ) この记事で参考にしていただきたいのは、 Kailu 環境をインストールする部分です。物語の後半、Zephyr、Zephyr blinky など) をビルドしてアニメーションしますが、このブログでビルドするのは Zephyr のサンプルではなく MicroPython です。ビルドの対相を仕様する部分だけが違反をテストしてください。 west build パスのステータスは作業と同じであり、準備は完了しています。 ゼファーの公式は以下のとおりです。 Zephyr入門ガイド 環境があれば, ~/zephyrproject のようなディレクトリに西のワークスペースが目的されているはずです.以下、これを ~/zephyrproject とします。 2.2 MicroPython のソースを入手する MicroPython のソースは、Zephyr のワークスペースとは別の場所にある構造になっています。ゼファーの作業場は汚いし、別の場所だ。 git clone https://github.com/micropython/micropython.git cloneしたら、ディレクトリにアニメーションってサブモジュールを入手します。 cd micropython git submodule update --init lib/micropython-lib micropython-lib MicroPython は標準のライブラリグループとサブモジュールとして分離されています。これを入手するには準備がないとビルド時にエラーになるので、忘れて実行してください。 登場する本は本、FRDM-MCXN947の設定は本家の主人です。パッチを当てている必要はありません。 のためを読んで、のファイルがあることを使って確認してください。 micropython ディレクトリにあるSTATUSはそのまま実行します。 ls ports/zephyr/boards/ | grep mcxn947 frdm_mcxn947_mcxn947_cpu0.conf と frdm_mcxn947_mcxn947_cpu0.overlay の 2 つが意味すればOKです。 もしやファイル名が长いのか Zephyrでは、じボードでもコアやアクションモードによって複数の構成をホールドすることがあります。 FRDM-MCXN947 Cortex-M33 Cortex-M33をデュアルで搭載しているため、 frdm_mcxn947/mcxn947/cpu0 のように「ボード名/SoC名/コア名」が指定されます。ボードクオリファイアー(board qualifier)とボードクォリファイアー。 MicroPython の Zephyr ポートは、この修飾子を含めた名前でconf/overlay を探索します。つまり frdm_mcxn947.conf という名前では読み込めません。 frdm_mcxn947_mcxn947_cpu0.conf として初めて見られます。自己分割した設定は設定に追加され、設定は設定に追加されます。 2.3 ビルドする まずZephyrの仮 環境について考えるのが効果的です。 source ~/zephyrproject/.venv/bin/activate Zephyrのバージョンを合わせます。 cd ~/zephyrproject/zephyr git checkout v4.4.0 west update MicroPython の Zephyr ポートが対応を明言しているのは、v3.7 (LTS) および v4.4、そして开発版です。本家のCIはv4.4でビルドを検査しています。のバージョンになっていると、ワークスペースの外に、通ってもアクションが違反になったりすることがあるので、ここでv4.4.0に揃えておきます。 west update HALやライブラリなどの関連モジュールを取り正すためのものです。 git checkout だけでは不統合が残っているため、必ずセットで実行してください。 準備ができたら west build を実行します。 cd ~/zephyrproject west build -b frdm_mcxn947/mcxn947/cpu0 ~/micropython/ports/zephyr -b がボードで指定する、最後の引数はがビルド対相のアプリケーション(MicroPythonのZephyrPort)です。 ~/micropython の部分は,実记にクローンした場所に読んでください。 ビルドが通ると build/zephyr/ 下に zephyr.bin , zephyr.hex , zephyr.elf が生成されます。 2 エピソード後、設定はストレートでストレートです。 --pristine (または -p ) 前回の戻りの結果は前回の戻りの結果です。 cd ~/zephyrproject west build -p -b frdm_mcxn947/mcxn947/cpu0 ~/micropython/ports/zephyr 2.4 ボードに书き込む FRDM-MCXN947にはMCU-Linkデバッガがオンボードで本は別の方法で書かれており、目的が必要であり、本は別の方法で書かれています。 USBケーブルはJ17 (MCU-Link側USBコネクタ)コネクタ 図2:USBコネクタJ17(MCUリンク側)コネクタ 続きを受け取ったら, west flash を実行するだけです。 cd ~/zephyrproject west flash 本き込みが終わりわると、ボードは自動にリセットされてMicroPythonが始まります。 このJ17は书き込みだけでなく、MicroPythonと対语するための通常通信にも使います。詳細についてはセクション 3.2を参照してください。 ▲ カタログに戻る 3. MicroPythonってみる—基本エディター とりあえずが书き込めたら、いよいよMicroPythonをタッチっていきます。 3.1 トニーする MicroPython は使いやすく、MicroPython の環境は必要ありません。ターミナルソフトでも構造化していませんが、ここではThonnyを作っています。 ThonnyはMicroPython初の関数型プログラミング言語であり、同時に統合開発環境(IDE)でもあります。無料で利用でき、Windows、macOS、Linuxに対応しています。 ソニー公式サイト Thonny's のインストールとの基本操作が基本操作で、以下のアニメーションが該当部分です。 MicroPythonをi.MX RTクロスオーバーMCUでアニメーションかしてみた(YouTube) — Thonnyのインポート部分から再生成されます トニーはポイントの利点であり、コミュニケーションは同じです。 本の上部、本の上部、本の上部、本の上部 ボードのファイルシステム( /flash ) の中の体をGUIで見られる PCとボードのファイルをポータル&ドロップでコピーできる という点です。第4章。 3.2 USB USB FRDM-MCXN947にはUSB Type-Cのコネクタが複数あります。 MicroPython のコンソールにシステム ぐのはJ17 、MCU-Link 側のコネクタです (セクション 2.4の図 2 と同じ地です). MicroPython のコンソールは、Zephyr のコンソール( zephyr,console ) に出力されます。 FRDM-MCXN947のcpu0では,これが flexcomm4_lpuart4 (P1_8 / P1_9) オリジナルのMCU-Link MCU-Link VCOM (仮愿COMポート) があります. つまりJ17の1书で、一時の书き込みとコンソールの両方ができます。 MCXN947 の本体は本体の USB 方式であり、この章の構成は USB 方式です。 3.3 確認を受け入れる ケーブルを行いましたThonnyをスタートします。 Thonnyの右下(またはメニューの「実行」→「インタプリタの選択」)から、インタプリタとして「MicroPython (generic)」を選択して、ポートニボードのVCOMを指定します。 Windows: COM3 のような名前 macOS: /dev/cu.usbmodem… Linux: /dev/ttyACM0 など 図3:インタプリタに「MicroPython (generic)」を选ぶ   うまくいくシステムががると、下のシェル(Shell) ペインにプロンプトが出ます。 Ctrl-D (ソフトリセット)を試してみてください。 MicroPython v1.30.0-preview.17.g47e9329e51 on 2026-08-30; zephyr-frdm_mcxn947 with mcxn947 Type "help()" for more information. >>>   図4: 続に成功すると、シェルペイン(ウィンドウ下)にバナーとプロンプトがされることを意味します zephyr-frdm_mcxn947 with mcxn947 の最後の部分に注目してください。 zephyr-frdm_mcxn947 は Zephyr の CONFIG_BOARD 、 mcxn947 は CONFIG_SOC から作られる名前です。ここが楽しみになって進行していれば、スナイプしたボードを使用のバイナリが移動していると確認できます。 >>> まずは「Hello, world!」の式から出してみましょう。 >>> print("Hello, world!") Hello, world! MicroPython は Python なので、数式をヒットするだけでも結果が返ります. >>> 1 + 2 3 >>> "MCX" * 3 'MCXMCXMCX' ファイルシステムも確認しておきます。 >>> import os >>> os.getcwd() '/flash' >>> os.listdir('/flash') [] ストレートバックを開始しますのカレントディレクトリが /flash になっています。これは今回はマージされたセットでLittleFSがマウントされているからです。まだ何も志していないので中体は空です。 3.4 「REPL」とは 今生きているこの対情码ENVIRONMENTをREPLとHUびます。 Read (読む)、 E val(評価価する)、 Print (式する)、 Loop (粲り返すす)の頭文字はありません。 1行の入力強制、MicroPythonはそれを読み、実行し、結果を表し、また時の強制入力を待ちます。これがREPLです。 コンパイルして书き真剣で実行して、という手顺を踏んで、分からないCの开発と比較的と、試行錯誤の回しかた一瞬が変わってきます。例えば「このピンをHIGHにしたらLEDは点くのか、排除できるのか」のような確認が、そのフィールドで1行ヒットするだけで済みます。ハードウェアの挙動を手動検出りで真かめるとき、REPLは非常に強力です小道具になります。 REPLは使いやすく、操作も簡単です。 キー アクション Ctrl-C 実行中のプログラムを中断する Ctrl-D MicroPython を再起動する Ctrl-E ペーストモードに入る Ctrl-A rawREPLモードに入る Ctrl-B 通常のREPLモードに戻る 表1:REPL制御システム Ctrl-Cは、無制限ループ発生したプログラムを停止してください。 Ctrl+D Ctrl-Eのペーストモードは、複数行のコードをまとめてステッカーできる時に使います。通常 REPL は 1 行ごとにインデントを解釈しようと考えるので、 for 文のような複数行のコードをそのままにしてもうまくいかないことが起こります。 Ctrl-E してらコ-ドを貼り付けます、Ctrl-D で実行しますと、まとめられます。 3.5 スクリプトを书いて見る:Lチカ ここまではREPLに1行ずつなんとかんできました。ちょっとした確認にはこれここ半分はいのですが、缲り回しや条件分岐が入ってきて当然に俫になります。 ではスクリプトを书いてみましょう。 LEDのLチカ(LEDチカチカ)です。 FRDM-MCXN947にはRGBのLEDがあります。まずは红を点杀させてみます。红のLEDはP0_10、つまり ("gpio0", 10) に式があります。 トニーの上半身は本の上半身であり、下半身は本そのものである。 import time from machine import Pin led = Pin(("gpio0", 10), Pin.OUT) # 赤LED (P0_10) while True: led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 time.sleep(0.5) 図5: 本の上面。下側がシェルペイン   书けたら、ツールバーの「実行」ボタン(緑色の三角形のアイコン。ショートカットはF5)を気をつけます。 Thonnyがious Generation ched in in in on in MicroPython今日のテストはテストと同じ、テストはテストと同じ。 赤色LEDが0.5秒で正常に点灯します。 やめて、やめて、やめて、やめて。シェルペインでCtrl-Cを気にしても同じように出ます。 ここで「あれ?」と思った方へ コードをよく読んでください。 value(0) は照明をオンにすることを意味し、 value(1) は照明をオフにすることを意味します。直感は真実を見ることの反対であり、調和は真実です。 FRDM-MCXN947のRGB LEDは、アノードコモンで接続され続けています。 LED側電源方式、マイコンのピンがマイナス側をリードっ張る形です。つまりピンをLOW(0)にしたときに電流が流れて点灯します。 図6: FRDM-MCXN947回路のRGB LED部分。LED電源システム   Zephyr の devicetree には、この LED が GPIO_ACTIVE_LOW という情報がちゃんとあります。ただし MicroPython の machine.Pin は、devicetree のこのフラグを见ずにGPIO を生の値を読み続けます(内で gpio_pin_set_raw() をHU しています)。そのため、论理を反転してくれることはありません。 0 を书すればピンはLOWになり、LEDは点きます。 さて、 led.value(0) は led.off() とも书けます。つまり led.off() をハブとLEDは点灯します。ミンマオと実记の行動が逆になるので、カオスしそうなときは value(0) / value(1) で书くほうが安全かもしれません。 もうひとつ 注: toggle() はありません 彼のポートのMicroPythonにカスタムされていますと led.toggle() と来ましたが、Zephyrポートの Pin にはこのメソッドがありません。新しいものにしてください。 メソッド/固定数 説明 value([x]) 引用はなしで読み出し、引用はありで书き込み on() HIGH(1)を出力 off() LOW(0)を出力 init(...) ピンの設定更新 irq(...) カットり込みハンドラを設定 Pin.IN / Pin.OUT / Pin.OPEN_DRAIN 入力電力と出力電力 Pin.PULL_UP / Pin.PULL_DOWN プルアップ / プルダウン Pin.IRQ_RISING / Pin.IRQ_FALLING カットり込みエッジ 表 2: ZephyrPort の machine.Pin で使えるもの トグルしたいときは、読んで転んで书れば済みます。 led.value(not led.value()) 3.6 このボードで使えるピンをアニメーションべる さて、红のLEDが ("gpio0", 10) であることは、どこから来た値なのかを description しないまま使ってきました。では自分で调べるにはどうすればいいのでお願いします。 この节では、答えを探しにZephyrのSETファイルまでドロップしていきます。小さく入った说になるので、最初を急いでぐ方は読んで飞ばして4章に入って構造ではありません。第4章:では、ここで调べた対応表を一度作ってしまえば、その後ドロップしたは名前でピンを指定できる、という语をします。 Cannian ながら、 MicroPython の Zephyr ポートには「できるピンの一覧を作る」関数がありません。 machine モジュールの中身を見ても、ピンの名前は出てきません。 >>> import machine >>> dir(machine) Pin 、 I2C 、 SPI 、 UART 、 PWM 、 ADC 、 Timer 、 WDT のようなクラス名が和びます(実记に入るはビルド時のセットで変わるので、手元で実行して真かまってください)。 Pin というクラスがあることはわかりますが。 では、どこを見ればいいのか 答えへはZephyrのdevicetreeです。 デバイスツリーとは (Zephyrのオリジナルコンテンツは「FRDM-MCXN947デバイスツリー」として知られており、「FRDM-MCXN947のデバイスツリーはオリジナルと同じである」) devicetree(デバイスツリー)は、ボードにどんなハードウェアが在っていて、どうやって話しているテキストファイルです。当初はLinuxカーネルで使われていた士组みで、Zephyrもこれを採用しています。 「この SoC には I²C コントローラが何的にあって、それぞれのアドレスにあって、どのピンに出ていて、効果的なのか無いのか」 といった情報が、 .dts / .dtsi とい拡张子のファイルのストラタ構造で书かれています。 Zephyr にこれを読み取って、必要な方の初期化コードやピンの設定を自動で生成します。 ソースコードにピン番号をダイレクトブックの代わりに、ハードウェアの構成情報をコードから分離しておく、というテストえ方です。おかげで、じアプリケーションのソースを使うボードと同じでけにビルドすることができます。 MicroPython の Zephyr ポートが ("gpio0", 10) というタプルを要件とするのも、このdevicetree の構築をそのまま反映しているからです。 gpio0 のデバイス名はdevicetree、 10 はそのポート内のビット位置です。 FRDM-MCXN947のデバイスツリーを読む FRDM-MCXN947 構成は、Zephyr のリポジトリ下のファイルに书かれています。 zephyr/boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi この中の arduino_header というノードに、Arduinoヘッダーの各ピンがどのGPIOに部門があるかがわかります。 arduino_header: arduino-connector { compatible = "arduino-header-r3"; gpio-map = , , , , , /* RX */ , /* TX */ , ... , /* SCK */ , /* SDA */ ; /* SCL */ }; は「ヘッダーのD13は gpio0 の25ビット目」という意味です。これをMicroPythonのタップに正すと ("gpio0", 25) になります。 じファイルの中と同様に、LEDとスイッチの定義もあります。 leds { compatible = "gpio-leds"; green_led: led_1 { gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; ... }; blue_led: led_2 { gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; ... }; red_led: led_3 { gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; ... }; }; gpio_keys { compatible = "gpio-keys"; user_button_2: button_0 { gpios = <&gpio0 23 ...>; }; /* SW2 */ user_button_3: button_1 { gpios = <&gpio0 6 ...>; }; /* SW3 */ }; 红のLEDが &gpio0 10 、つまり ("gpio0", 10) であることがここで確認できます。 GPIO_ACTIVE_LOW と书かれているのも見ますね。最初の説明は根の根です。 毎回 devicetree を読むのか? さて、これを曲に戻すたびに、べるのはは今ではありません。 「LEDを光らせたいだけなのにdevicetreeを読む」というのは、MicroPythonの手軽さを台無しにしています。 そこで4章では、この対応表現を一度だけ作って、その後は名前で书けるようにする方法を紹介します。 3.7 Lチカの色を変えてみる 対泽の前に、タップル指定の不便さをもう小さい身体感覚にしておきましょう。 3色LED光源。 devicetreeから読み取った値は時の正しくでした。 色 ピン タップル 赤 P0_10 ("gpio0", 10) 緑 P0_27 ("gpio0", 27) 緑 P1_2 ("gpio1", 2) 表3:RGB LED照明 import time from machine import Pin red = Pin(("gpio0", 10), Pin.OUT, value=1) green = Pin(("gpio0", 27), Pin.OUT, value=1) blue = Pin(("gpio1", 2), Pin.OUT, value=1) while True: for led in (red, green, blue): led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 Pin() の value=1 は、ピンを出力に設定すると同時に初期値をHIGH(消灯)にする仕様です。これを払えないと、設定した瞬間に瞬間点灯することがあります。 赤→緑→緑とシュンファンに光れば成功です。 とりあえず、このコードを見てどう思いますか。 red = Pin(("gpio0", 10), Pin.OUT, value=1) ("gpio0", 10) という部分は「が読めません」という意味です。 red という変な数字の名前を払ったから書けるだけで、この数字だけを見て「赤いLED」だとわかる人はいないはずです。 まさか、この数字てもエラーにはなりません。 ("gpio0", 11) と书いたら、存在するピンなので Pin は正常にされ、LED だけないだけです。 「どこが悪いのか」を探すのに時に取られることになります。 この質問を、回の張で片払って下さい。 ▲ カタログに戻る 4. 緊急編集者: ピン名を公夫する Zephyr ポートがピン名を提供できないなら、それを分離することが目的です。それがこの章です。 Step by stepを追いかけて、3つのstep by stepで進めます。 スクリプトの中の辞書を书く config.py という別れのファイルに切り出す ボードのストレージに出ています,すべてのスクリプトから共有 4.1 わかりやすいスクリプトの中にPINS Dictionaryを书く 一番単くない、スクリプトの前头にPythonの辞書を书いてしまうメソッドです。 import time from machine import Pin PINS = { "LED_RED": ("gpio0", 10), "LED_GREEN": ("gpio0", 27), "LED_BLUE": ("gpio1", 2), } red = Pin(PINS["LED_RED"], Pin.OUT, value=1) while True: red.value(0) time.sleep(0.5) red.value(1) time.sleep(0.5) Pin(PINS["LED_RED"], ...) これなら何をしているのか一目でわかります。 さらに良いのは、タイプミスがエラーになることです。 >>> Pin(PINS["LED_RD"], Pin.OUT) Traceback (most recent call last): File " ", line 1, in KeyError: LED_RD まず「数字や数値に違反する」ということ。 Dictionary のキーを间violation えれば KeyError で停止まってくれます。これだけでもデバッグの手间がかなりマイナスです。 4.2 config.pyに切り出す しかし、スクリプトを书くたびにこの辞書をコピーするのは面流です。実记、LEDだけでなくArduinoヘッダーやMikroBusのピンも定義になったので、辞書はどんどん长になります。そのたびにすべてのスクリプトの头にステッカーりペイけるのは成実的ではありません。 Pythonらしく、不ファイルに切り出してインポートしましょう。 config.py というファイルを作ります。 PINS = { # --- Arduinoヘッダー --- "D0": ("gpio4", 3), # P4_3 (RX) "D1": ("gpio4", 2), # P4_2 (TX) "D2": ("gpio0", 29), # P0_29 "D3": ("gpio1", 23), # P1_23 "D4": ("gpio0", 30), # P0_30 "D5": ("gpio1", 21), # P1_21 "D6": ("gpio1", 2), # P1_2 "D7": ("gpio0", 31), # P0_31 "D8": ("gpio0", 28), # P0_28 "D9": ("gpio0", 10), # P0_10 "D10": ("gpio0", 27), # P0_27 (CS) "D11": ("gpio0", 24), # P0_24 (MOSI) "D12": ("gpio0", 26), # P0_26 (MISO) "D13": ("gpio0", 25), # P0_25 (SCK) "D14": ("gpio4", 0), # P4_0 (SDA) "D15": ("gpio4", 1), # P4_1 (SCL) "A2": ("gpio0", 14), # P0_14 "A3": ("gpio0", 22), # P0_22 "A4": ("gpio0", 15), # P0_15 "A5": ("gpio0", 23), # P0_23 # --- バス(Zephyrのデバイスノード名) --- "I2C": "lpi2c@94800", # flexcomm2_lpi2c2 (arduino_i2c) "SPI": "spi@93000", # flexcomm1_lpspi1 (D10〜D13) "MIKROBUS_I2C": "lpi2c@95800", # flexcomm3_lpi2c3 "MIKROBUS_SPI": "spi@b6000", # flexcomm6_lpspi6 # --- MikroBusのGPIO --- "MIKROBUS_RST": ("gpio1", 3), "MIKROBUS_CS": ("gpio3", 23), "MIKROBUS_SCK": ("gpio3", 21), "MIKROBUS_MISO": ("gpio3", 22), "MIKROBUS_MOSI": ("gpio3", 20), "MIKROBUS_PWM": ("gpio3", 19), "MIKROBUS_INT": ("gpio5", 7), "MIKROBUS_RX": ("gpio1", 16), # GPIOとして使える.UARTのRXではない "MIKROBUS_TX": ("gpio1", 17), # GPIOとして使える.UARTのTXではない "MIKROBUS_SCL": ("gpio1", 1), "MIKROBUS_SDA": ("gpio1", 0), # --- エイリアス --- "LED_RED": ("gpio0", 10), # = D9 "LED_GREEN": ("gpio0", 27), # = D10 "LED_BLUE": ("gpio1", 2), # = D6 "SW2": ("gpio0", 23), # = A5 "SW3": ("gpio0", 6), # P0_6 } すべてdevicetreeから転记した値です。 いくつか補足します。 RGB LEDはArduinoと共有されています。 赤色LED(P0_10)はArduino D9 D9と同じです。緑D10、青D6と同じ。 Arduino シールドを挿入しますときは、これらのピンをうと LED も一丝に光ります。逆に言うと、シールドがD6やD9をしていると、LEDのつもりで動作するとシールド側への影響が出ます。 SDA/SCLはA4/A5ではありません。 Arduino UNO R3 のボードでは、I²C の SDA/SCL が A4/A5 と同じ配線になっていることが多く、「A4=SDA,A5=SCL」と覚えている方も多いと思います。 I²CはAREFのネイバーにある専用のSDA/SCLピン(Zephyrのdevicetree上ではD14/D15)に出ていて、これはP4_0/P4_1です。 A4 (P0_15) および A5 (P0_23)、I²C システム独立 GPIO。第 5 章: ジャンパを性ぐときになるので、覚えておいてください。 SW2はA5と同じピンです。 ユーザースイッチのSW2(P0_23)は、ArduinoヘッダーのA5と じピンにシステムがついています。 A5の出力も回路の影響も同じで、注意点も同じです。 バスは文字列を「します」で指定します。 machine.I2C と machine.SPI のidパラメータは、タプルではなくZephyrのデバイスノード名の文字列です。 "lpi2c@94800" の 94800 は、MCXN947のメモリマップ上のペリフェラルのアドレス(0x94800)です。ここもdevicetreeの原点の値です。 4.3 ステージに保存したユーザー: して共有する config.py ができました。 スクリプトは「モジュール」として読み込む 最初のステップは最初のステップであり、 import ステップはステップを完了するための最初のステップです。 config.py は特別なフォームのファイルではありません。 PINS = { ... } と使える、ごく普通の Python のスクリプトです。 Lチカのスクリプトと同じ、ただのテキストファイルです。 Python では,そばスクリプトを彼のスクリプトから読み進め import 使えます。 from config import PINS これは「 config.py を読み込んで実行し、その中でされた PINS .py config 」という意味になります。がそのままモジュール名になります。 config.py 中体が実行されるので PINS という辞書ができます、それをここで使えます、というわけです。 よく作る定義やオフ数を比ファイルにまとめて書いて、必要なスクリプトから読み込む。これはPythonでごく一般的なやり方で、MicroPythonでも同じように使えます。 どこに志せばよいか config.py をボードのどこに出ても、すべてのスクリプトから import できるでお願いします。 MicroPython は、モジュールを sys.path に和んだディレクトリから探索します。確認。 >>> import sys >>> sys.path ['', '.frozen', '/flash/lib'] /flash/lib これは今回マージされた設定は LittleFS がマウントされたときに、起動プロセス ( _boot.py ) は自動的に追加されますが通常です。 つまり /flash/lib/config.py として保存すれば、どのスクリプトからも from config import PINS でめるということです。 トニーの家 Thonnyのメニューから「式」→「ファイル」を选ぶと、画面左側に表示されます。上半分がPC側、下半分がMicroPython側です。   図7:トニー /flash/lib config.py   使いやすく、スムーズです。 後半(ボード側)が /flash を表現していることを確認する ボード横のペインで右クリック→「新しいディレクトリ」を選択して、 lib を作ります 作られた lib をダブルクリックして中に入る 前半(PC側)で config.py を右クリック→「/flash/libへアップロード」を选ぶ 設定して確認してください。 >>> import os >>> os.listdir('/flash/lib') ['config.py'] コマンドラインから操作時(リモート) Thonnyは使いやすく、操作も簡単で、操作も簡単です。 mpremote pip install mpremote でインストールできます。 まず lib ディレクトリを作ります。 mpremote mkdir :/flash/lib その中に config.py をコピーします。 mpremote cp config.py :/flash/lib/config.py スクリプトを実行するだけなら、ボードに保存せずに実行することもできます。 mpremote run blink.py 4.4 config.pyった3色Lチカ 準備をしましょう。セクション 3.7 のコードを书き正してみましょう。 import time from machine import Pin from config import PINS red = Pin(PINS["LED_RED"], Pin.OUT, value=1) green = Pin(PINS["LED_GREEN"], Pin.OUT, value=1) blue = Pin(PINS["LED_BLUE"], Pin.OUT, value=1) while True: for led in (red, green, blue): led.value(0) # 点灯 time.sleep(0.5) led.value(1) # 消灯 セクション 3.7 と比べてください。ないは、 Pin() に複数あるものだけです。 red = Pin(("gpio0", 10), Pin.OUT, value=1) # 3.7節 red = Pin(PINS["LED_RED"], Pin.OUT, value=1) # こちら ("gpio0", 10) のような数字はどこにも出てきません。 「赤・緑・青のLEDを瞬発に光る」という意味図が、そのままコードになりました。 これで、 1.5セクションで挙げたZephyrポートの弱点を、実際に使ってほぼ解消できました。 config.py かつては「もしよかったら」を設定することで行われていましたが、その後はずっと作成することで削減されました。 なお、ここで使っている config.py の全文は4.2に含まれていてあります。 トラブルシューティング:うまくインポートできないときは config.py いたのに ImportError が出る機会を設定しています、時間を確認してください。 ソフトをリセットします。シェルペインでCtrl-Dを気になります。 MicroPython は一度インポートするので、ファイルを出して変更しても古いものが使われることがあります。これにはよくある理由があります。 購入場所を確認してください。 os.listdir('/flash/lib') で config.py が見れるか真かめます。 lib ディレクトリを作る前にアップロードして、 /flash/ の正下に式かれているケースがよくあります。 sys.path を確認します。 import sys; print(sys.path) に /flash/lib が入ります。入っていなければ、 /flash のマウントに失敗している可能性があります。 ファイル名を確認します。 from config import PINS で読めるのは config.py という名前のファイルだけです。保存する前に、名前を保存することを忘れないでください。 ▲ カタログに戻る 5. 編集者:スイッチを読む 第3章ではLEDを光らせました。 GPIO の貢献は非常に重要です。今日は度数が逆転して力が入ります。 FRDM-MCXN947には,ユーザーが免費で使えるスイッチが2つついています. SW2とSW3は同じです。ここではSW2を使います。 図8:ユーザースイッチSW2とSW3の位置   この章に追加パーツは要りません。ボードとUSBケーブルだけで入ります。 5.1 スイッチの状態を読む SW2はP0_23がいてて、 config.py に SW2 として入れてあります。 from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) print(sw.value()) Pin.IN 力設定を入力してください。 Pin.PULL_UP 内部抵抗が有効です。 なぜプルアップが必要なのか このスイッチは、おつすとピンがGNDに行く路になっています。その逆も真、その逆も真、その逆も真。電気の状態が安定しており、電圧も安定しています。 プルアップ耐性を効果的にすると、いないときはピンがパワーサイドに上げられてHIGHになります。おつしたきだけ GND にキューかれて LOW になります。これで両四角の状態が分かります。 つまり読み出される値は時のようになります。 大下していない→ 1 大下している → 0 ここでも 0 が です。 LEDのときと同じアクティブ・ローの考え方で(セクション3.5 ),このボードではよく出てくる形です. 実行して真かめてみましょう。 >>> print(sw.value()) 1 杀していないので 1 が回りました。ながら実行すれば 0 になります。 粲り回し読む機会 ステータスを監視し続けるなら、こうなります。 import time from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) last = sw.value() while True: now = sw.value() if now != last: print("押された" if now == 0 else "離された") last = now time.sleep_ms(20) 前の章で、「の値と比べて」、「変化したときだけ」は「しています」を意味します。そのたびに、という意味であり、ずっと出力され続けているという意味です。 この法をポーリングと淳ます。公式グループは純粋で単純で、欠点は小さくて明らかです。 sleep_ms(20) の间にスイッチが阿されて里されると、见出してしまいます。かべき間隔を短くすると、その分だけCPUがこの確認に充電されます。 5.2 杀されたことを切り込みで知る そこで使えるのが开り込みです。 「ピンの状態が変化したら,この关数をHUNDE」とログイン方法、対処方法、やり方が欲しいです。 「脱出」を参照してください。 machine.Pin irq() メソッドで登録します。 import time from machine import Pin from config import PINS sw = Pin(PINS["SW2"], Pin.IN, Pin.PULL_UP) n = 0 def pressed(pin): global n n += 1 print(" 割り込み %d 回目 value=%d" % (n, pin.value())) sw.irq(handler=pressed, trigger=Pin.IRQ_FALLING) print("SW2を数回押してください(30秒間)") for i in range(30): time.sleep(1) sw.irq(handler=None) print("合計 %d 回検出しました" % n) 実行してSW2を10回の返済結果です。 SW2を数回押してください(30秒間) 割り込み 1 回目 value=0 割り込み 2 回目 value=0 割り込み 3 回目 value=0 (中略) 割り込み 10 回目 value=0 合計 10 回検出しました 押された回数、呼び出された回数、呼び出された回数。 コードの読み方 trigger には、どのような変化でHUNDE欲しいと思いますか。 特定 平均 Pin.IRQ_FALLING HIGH→LOWの変化(このボードでは「した」) Pin.IRQ_RISING LOW→HIGHの変化(「 」) `Pin.IRQ_FALLING \ Pin.IRQ_RISING` 䡡方 表 4: irq() の trigger できるもの ここでは誓約したインスタントだけ知りたいので Pin.IRQ_FALLING を指定しています . handler にまたがるパス番号は、見積を1つ受け取りますようにきます。ばれるときは、切り込みの起きた Pin オブジェクトが多くなるためです。上記の例は pin.value() として、そのピンの値をお読みになります。 global n これはPythonの正常な決定まりで、MicroPythonでも同じです。 最後の sw.irq(handler=None) が最後です。元に戻して、手放してください。 ハンドラの中で print() してよいのか カットり込みハンドラの中では、時間のかかるプロセスやメモリを確保するプロセスを避けるのが原則です。 print() はどちらにも道がありますので、元々は避けていました。 ただしMicroPythonの irq() には hard という引用があり、確立された値は hard=False です。このとき、ハンドラはカットり込みが出てきましたインスタントではなく、小し後の安全なタイミングにまわって実行されます。そのため print() を书いても質問はありません。 hard=True 応答応答は速度になりますが、 print() やメモリ確実はできなくなります。まずは確立されたままで構造はありません。 チャタリングについて 機械式接点スイッチ、接点接点は瞬時、接点は細かく細かくON/OFFがオンオフします。これをチャタリングと呼び出して、1周押すだけでカットり込みが多くも入る理由になります。 FRDM-MCXN947のSW2でわかりぎりでは、10回押しに対してカットり込みは10回、チャタリングは観尺されませんでした。ただしスイッチの個別しかたによってはRISEこりうるので、数が合わないときは、前回の時間が経過し、時間が経過し、短い時間が経過し、短い時間が経過し、時間が経過しました。 ▲ カタログに戻る 6. 使い方エディター: I²Cを使ってみる GPIOのサブI²C。温度は良好です。 6.1 このボードのI²Cの件 FRDM-MCXN947にはP3T1755という温度センサーがございます。 I²CとI3Cの両方に対応した、分解エネルギー12bit、精度±0.5℃のセンサーです。 ちなみに,これをMicroPythonからそのまま読むことはできません.その理由は次のとおりです。 MCXN947のI3C1は、デバイスツリー上にあります。 pinmux_i3c1: pinmux_i3c1 { group0 { pinmux = , ; ... }; }; つまりSDAがP1_16、SCLがP1_17です。 一方、MicroPython の Zephyr のポートにはI3C の意見がありません。 machine モジュールにあるのは I2C だけで、 I3C というクラスは存在しないのです。つまりMicroPythonからは、このセンサーには手が届きません。 しかしI3Cのターゲットデバイスは、I²CのカクテルからもI²Cデバイスとしてアクセスできるようになっています(レガシーI²Cモード)。 P3T1755もそうです。 I3C信号線 ここで、最初ほど config.py にあったMikroBusのDefinitionを思い出してください。 "MIKROBUS_RX": ("gpio1", 16), # GPIOとして使える.UARTのRXではない "MIKROBUS_TX": ("gpio1", 17), # GPIOとして使える.UARTのTXではない P1_16とP1_17です。 I3C1 の SDA/SCL はI3C1 と同じです。 FRDM-MCXN947では、このI3Cの信号線がMikroBusコネクタのRX/TXピンにもリードされています(devicetreeでは「GPIO, Not a RX」というコメント払いで、GPIOとして扱われる時期があります)。 コネクタに出ているのなら、ジャンパラインで彼のバスに回線げます。 6.2 ジャンパを2本つなぐ Arduino I²C( flexcomm2_lpi2c2 ) の学科です。セクション 4.2 では、このバスが出ているのはAREF のネイバーにある専用の SDA/SCL ピンであることを強調しています。 A4/A5ではありません。 配線は配線ハーネスによって行われます。 MikroBusコネクタ 信号 先頭に立って (Arduinoヘッダー) 信号 RX (P1_16) I3C1_SDA SDA (P4_0) LPI2C2 SDA TX (P1_17) I3C1_SCL SCL(P4_1) LPI2C2 SCL 表5:JB配線 図9:ジャンパラインの接続続行 留意すべき点 SDAとSCLを違反することは出来ませんのでご了承ください。逆系はもちろん通信系。 MikroBus 側には RX と SDA があり、TX には SCL があります。 1番目の名前は1番目の名前の画像であり、1番目の名前は2番目の名前と同じです。 プルアップ抵抗: I²C はオープンドレインなので、本来はプルアップ抵抗は必要ありません。ただし作者の環境ではあり、外部支払いはけの抵抗なしで通信できました。 I3C1 側のデバイスツリーは bias-pull-up として指定されており、内部デバイスは有効なので有効です。通信の場合、4.7kΩレベルの抵抗はSDA/SCL、3.3Vの抵抗は3.3V~3.3Vの間で4.7kΩとなります。 A4/A5系がベストです。このボードのA4/A5はI²Cバスではありません。 6.3 バスをスキャンする 配線が完了し、配線の確認と確認が行われます。 I2C.scan() は,7ビットアドレスの法囲(0x08~0x77)に久问い合わせを出して,濜答え(ACK)を回したアドレスの一覧を回します。 REPLは直接試すことはできません。 >>> from machine import I2C >>> from config import PINS >>> i2c = I2C(PINS["I2C"]) >>> [hex(a) for a in i2c.scan()] ['0x48'] 0x48 これがP3T1755です。 freq= は指定できません 彼のポートのMicroPythonでは I2C(id, freq=400_000) のようにクロックサイクリック波数を指定できますが、Zephyrポートでは例外になります。 >>> i2c = I2C(PINS["I2C"], freq=100_000) Traceback (most recent call last): File " ", line 1, in NotImplementedError: explicit choice of freq is not implemented scl / sda / timeout も同様に指定できません。これらはすべてdevicetreeで決定まる値だからです。 FRDM-MCXN947のI²Cは、devicetreeで clock-frequency = 、つまり100kHzに設定されています。速度を変えたい機会はdevicetree(またはoverlay)を书き変更して、暫定を構築し正すことになります。 何も见つからないときは そらのリスト [] その場に戻って時刻を確認します。 半分挿入 半分挿入 半分挿入 SDAとSCLがなくなったか ボードの電源が入っている(たり前ですが、USBがかけていることがあります) プルアップが効果があるか ロジックアナライザやオシロスコープがあれば、SC Lにクロックが出ますを见るの一時実です。 scan() は相手がいなくてもウェーブフォーム自分は出ているので、「クロックが出ていない」のか「クロックは出ているが応答えがない」のかを切り分けられます。 I²C の信号が見えない場合は、第 10 章に挙げた I²C 関連のブログを参考にしてください。 6.4 温度制御 P3T1755の構造は、旧型のLM75と同じで、互換性があります。温度も同じです。 ポイントレジスタに 0x00 (温度レジスタ)を书く 2バイト読む 読んだ2バイトは16ビットの値ですが、有効なのは上位12ビットです。下位は4ビットは长に0です。上位ビットの記号12ビットは2の補数で整数、1LSBは0.0625℃に対応します。 コードにしたらこうなります。 import time from machine import I2C from config import PINS ADDR = 0x48 # P3T1755のI2Cアドレス REG_TEMP = 0x00 # 温度レジスタ def read_temperature(i2c, addr=ADDR): """P3T1755から温度を読んで摂氏で返す.""" i2c.writeto(addr, bytes([REG_TEMP])) # ポインタレジスタを指定 data = i2c.readfrom(addr, 2) # 2バイト読む raw = (data[0] << 8) | data[1] # 16ビットに合成 raw >>= 4 # 有効なのは上位12ビット if raw & 0x800: # 12ビットの符号を展開 raw -= 0x1000 return raw * 0.0625 # 1LSB = 0.0625℃ i2c = I2C(PINS["I2C"]) print("found:", [hex(a) for a in i2c.scan()]) while True: print("{:.4f} degC".format(read_temperature(i2c))) time.sleep(1) 実行すると、1秒ごとに温度が与えられます。 found: ['0x48'] 25.5000 degC 25.5625 degC 25.5000 degC ... センサーにタッチできると、値が上がるのがわかります。 0.0625℃と刻まれているので、近くをづけるだけでもアニメーションが見られるはずです。 コードの補足 raw >>= 4 の一部です。 P3T1755がす2バイトは、時のようなビット構成になっています。 図10: 温度制御構成   12ビットのデータが左诘め(MSB側に公開して)がんなされているので、4ビット右にシフトして右诘めにストレートしています。 記号( if raw & 0x800 )の展開は氷点下で正である必要があります。 12ビットの2の補数、のビット11が1なら負の数の最大値です。 Python の整数は限られており、「12 個の負の数」と「Python の負の数」はストレートでストレートな 0x1000 です。 0℃以上の場合は試験を省略し、安全性試験に入ります。 MikroBus側I²Cを使用する場合 じセンサーをMikroBusのI²C( flexcomm3_lpi2c3 )から読むこともできます。その機会はジャンパの続きをMikroBusコネクタのSDA(P1_0)/SCL(P1_1)にして、コードの PINS["I2C"] を PINS["MIKROBUS_I2C"] に変えるだけです。 i2c = I2C(PINS["MIKROBUS_I2C"]) MikroBus、SCL/SDA、RX/TX、SCL/SDA、交差、配線、短絡配線と同様です。 ▲ カタログに戻る 7. 編集者:SPIってみる 最後はSPIです。 7.1 ループバックでトライアル I²C はルール違反であり、FRDM-MCXN947 は SPI の標準であり、システムはそれに基づいています。そこでループバックでテストします。 ループバックというのは、MOSI(送信)とMISO(受信)を直接接続してしまう方式です。自己分割発送、自己分割返送、社外部品できます。 Arduino SPI ( flexcomm1_lpspi1 )は、サブのピンに出ています。 信号 Arduinoヘッダー ピン タップル CS D10 P0_27 ("gpio0", 27) モシ D11 P0_24 ("gpio0", 24) 味噌 D12 P0_26 ("gpio0", 26) SCK D13 P0_25 ("gpio0", 25) 表6:Arduino SPIの切断機能 D11(MOSI)とD12(MISO)をジャンパラインでラインしてください。 図11:MOSIとMISOを正解してループバックにする   from machine import Pin, SPI from config import PINS spi = SPI(PINS["SPI"], baudrate=1_000_000, polarity=0, phase=0) tx = bytes([0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08]) rx = bytearray(len(tx)) spi.write_readinto(tx, rx) print("送信:", [hex(b) for b in tx]) print("受信:", [hex(b) for b in rx]) print("一致:", tx == bytes(rx)) 旅の結果はこうなります。 送信: ['0x0', '0xff', '0xaa', '0x55', '0x1', '0x2', '0x4', '0x8'] 受信: ['0x0', '0xff', '0xaa', '0x55', '0x1', '0x2', '0x4', '0x8'] 一致: True 送り返して送り返してください。 SPIが正しく動作しています。 ジャンパラインを外して実行すると、信頼できるデータが変わります。 MISOがどこにも组がっていない国(ハイ限界)になるので、 0x00 ばかりになったり。 お好きなギフトをお送りください 0x00 、 0xFF 、 0xAA 、 0x55 、そして 0x01 ~ 0x08 という与びには理由があります。 0x00 / 0xFF : すべてのビット 0 とすべてのビット 1。ラインは固定、ラインは固定 0xAA / 0x55 : 10101010 と 01010101 .ビットごとに成り上がるので、タイミングの窭炒见るのに向けて 0x01 , 0x02 , 0x04 , 0x08 ...:1のビットを1つずつずらしていく。ができる ロジックアナライザで波形を見るときにも、この与びはジャッジしやすくて便利です。 SPIのモード polarity と phase は SPI のモードを決定しますパラメータです。 モード 極性(CPOL) フェーズCPHA 0 0 0 1 0 1 2 1 0 3 1 1 表 7: SPI のモード ループバックでは自分が発信したものを自分で受け取っただけなので、どのモードでも満場一致でします。実记のデバイスに式ぐときは、そのデバイスのデータシートに合わせてください。 なお、I²Cと違反ってSPIでは baudrate が指定できます。 7.2 CS自動制御システム 今度こそ、実记のSPIデバイスを式ぐってCS(チップセレクト)が必要になります。 ここで、このポートならではのこだわりポイントがあります。 MicroPython Zephyr ポートの SPI には、CS を自動制御しません。 多くのMicroPythonのポートでは、 SPI オブジェクトにCSピンをたくさん待っていて、転刊のたびに自動でCSをLOWにして、最終的にわったらHIGHに戻ってきます。しかしZephyrポートの実装では、内部でZephyrに多すSPI設定のCS指定が空になっています。 したがって、 CS は machine.Pin 自分でコントロールする必要があります。 import time from machine import Pin, SPI from config import PINS cs = Pin(PINS["D10"], Pin.OUT, value=1) # アイドル時はHIGH spi = SPI(PINS["SPI"], baudrate=1_000_000, polarity=0, phase=0) data = bytes([0x9F]) # 例:何かのコマンド rx = bytearray(3) cs.value(0) # CSをアサート(LOW) spi.write(data) spi.readinto(rx) cs.value(1) # CSをデアサート(HIGH) print([hex(b) for b in rx]) CSはアクティブ・ローなのが全般です。 value(0) は選択されていません。 value(1) は選択されていません。 LEDは 0 と同じ「有効」です。 CSを戻せないようご注意ください。 LOW のままにすると、時の転送信でデバイスがカオスになります。転発信のたびに cs.value(0) と cs.value(1) を対で书く、そして忘れないのが真実です。 MikroBusのSPIをご利用ください MikroBus コネクタの SPI( flexcomm6_lpspi6 ) も同じように使えます。これが下の注のマージで新たに使えるようになったものです。 cs = Pin(PINS["MIKROBUS_CS"], Pin.OUT, value=1) spi = SPI(PINS["MIKROBUS_SPI"], baudrate=1_000_000, polarity=0, phase=0) MikroBusには豊富な種類のクリックボードが目的になっているので、そこをオンラインでテストするのも面白いと思います。 ▲ カタログに戻る 8. 編集者:イーサネットってみる 最後はイーサネットです。 8.1 有線LAN接続 ヘッドの外観は小さく、タッチも小さく、有線イーサネットは強力で強力です。ここで、その理由を具体的に考えておきます。 電波が使用され、無線は禁止および制限されており、場所が使用されます。 期間の安定性は安定しており、決定のサイクルはサイクルの目的であり、その目的はそれを使用することです。 配線と配線、通信と通信、通信と配線 工場設備、有線ケーブル設備、環境設備 MCXN947 のイーサネット コンソール(ENET QoS) は Zephyr の意見で行われていて、MicroPython からサポートされている socket モジュールは常に使用できます。 8.2 このポートのネットワークAPI まず第一に、できることとできないことをはっきりさせておきます。                  できるのは socket モジュールだけです。 >>> import socket >>> import network Traceback (most recent call last): File " ", line 1, in ImportError: no module named 'network' ここは、NXP のマイコンと同様にけであるi.MX RT の専用ポート( ports/mimxrt ) と比較的とわかりやすいと思います。あちらではイーサネットを時々のように扱えます。 import network lan = network.LAN(0) lan.active(True) DHCP サーバがあればアドレスはそこから一致され、無ければ lan.ipconfig(addr4="...") で実行時にSET できます。インターフェイスを有効にするもの無効にするもの lan.active() ひとつです。 ZephyrPortには、この network モジュールがありません。 network.LAN() も ifconfig() も存在せずに、 IPアドレスのSETや確認をするための専用APIが無い、ということです。アドレスはビルド時のKconfigで決定します(後述)。 socket オブジェクトがホールドするメソッドも、一般的なMicroPythonより小さいです。 作る 作る bind / listen / accept / connect getsockname() send / recv / recvfrom / sendto getpeername() read / write / readline / makefile settimeout() setsockopt / close   表8: Zephyrポートの socket ・    特殊効果は3点です。 getsockname() が無いので、自分のIPアドレスを直接は表現できません(セクション 8.4回避戦略を表示します) settimeout() が無いので、通信は通信の目的のために待機します(詳細についてはセクション8.8の詳細な説明を参照) accept() が回収开続元アドレスは长に None です.ポートのソースにコメントで // TODO と书かれている、の一部がアンインストールされています IPアドレスはビルド時に決定します このポートには、実行時に IP アドレスを設定するという意味がありません。 ports/zephyr/prj.conf の確立された価値は時代のようになっています。 CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0" CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" CONFIG_NET_DHCPV4=y DHCP は有効です、DHCP は有効ですワークに式げればそこからアドレスが开里道てられます。 DHCP サーバがいない環境では、の Quiet アドレス 192.0.2.1 が使われます。 なお 192.0.2.x は、RFC 5737 は文書の例です。 Zephyr のサンプルセットがそのまま入っているだけですので、実记のでは自分のネットワークに合わせた値に変更することになります。変更する機会はボードの .conf に上书きのセットを使って、ビルドしてください。 8.3 PC直接接続テスト DHCP LAN LAN システム LAN システム DHCP LAN システム DHCP LAN LAN システム DHCP LAN システム DHCP LAN システム DHCP LAN システム DHCP LAN システム DHCP LAN システム DHCP システムボードがどのアドレスを受け取ったのかを知るのが面恧す( getsockname() が無いため). ここでは、ボードとPCをLANケーブルでダイレクトノットしてテストします。これはボードのアドレスは静的設定の 192.0.2.1 に決定まるので真実です。 (下の写真では「ストレートノット」ですがコンピューターにイーサネットポートが無いのでUSB Type-C(イーサネット)   図12:ボードとPCを直接接続する(※このコンピュータの場合、デバイスの接続にはEthernetポートがないのでUSB Type-Cコンバータを使用します) PC側の設定 PCのイーサネットはPCのイーサネットと同じです。 プロジェクト 価値 IPアドレス 192.0.2.2 サブネットマスク 255.255.255.0 無事ゲートウェイ 空欄 表9:PC側設定 192.0.2.2 はボードがゲートウェイとしてSETしているアドレスなので、これに合わせて保存と都合がいいです。 最近のPC自動MDI / MDI - はたきで正かめる MicroPython はタッチの手前にあり、PC は ping ゾーンにあります。 Zephyr IP スタックはMicroPython とはbie のスレッドで動いているので、 REPL に何も入力しなくてもping には応答します。 ping 192.0.2.1 PING 192.0.2.1 (192.0.2.1): 56 data bytes 64 bytes from 192.0.2.1: icmp_seq=0 ttl=64 time=1.088 ms 64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.657 ms 64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=1.938 ms --- 192.0.2.1 ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss これが通れば、 PHYのリンク・イーサネットの意見・IPスタックまで動いていることになります。ここが通らないうちにMicroPythonのコードを书いても意味がないので、最初に確認してください。 通信に関しては、PC側のIP設定、PC側の電源、および電源供給の安定性を確認します。 8.4 自己分割IPアドレス getsockname() がないので、ボードに「あなたのIPアドレスは?」と直接は文けません。 代表してわりに使えるが bind() の成不了です。自己 bind() 支持と失敗なので、候補者を従属テストか、どれをホールドしているかがわかります。 import socket for ip in ("0.0.0.0", "192.0.2.1", "192.168.1.1"): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.bind((ip, 9999)) print(" bind OK ->", ip) except Exception as e: print(" bind NG ->", ip, type(e).__name__, e) s.close() 実行するとこうなります。 bind OK -> 0.0.0.0 bind OK -> 192.0.2.1 bind NG -> 192.168.1.1 OSError [Errno 2] ENOENT 0.0.0.0 ここでは 192.0.2.1 だけが成功したので、ボードは静かな設定のアドレスを使っているとわかります。 DHCPはDHCPと同じです。 DHCPは必要なときだけ使用するものであり、単体でスタンバイとして使用することは困難です。それは機会です、それはDHCP プログラムと同じです。 「どの机にどのアドレスを貸していますか」の一覧が見られるので、そこからボードのアドレスを拾ってください。 8.5 ボードをWebサーバにする ここまでで疎通は確認できました。最後に、ボードをWebサーバにしてみます。 PC側の目的は「するものはブラウザだけです」を使用することです。 import socket srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(("0.0.0.0", 8080)) srv.listen(1) print("listen 0.0.0.0:8080 接続待ち...") cl, addr = srv.accept() # addr は常に None print("接続あり:", addr) req = cl.recv(256) print("リクエスト先頭:", req.split(b"\r\n")[0]) body = " FRDM-MCXN947 MicroPython on Zephyr " cl.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" + body) cl.close() srv.close() bind() に "0.0.0.0" を多しているのは、「このボードがホールドしているすべてのアドレスで治療できる」という意味です。アドレスを決定めヒットちしなくても大丈夫ですので、DHCPでもストレートノットでもそのままアニメーションきます。 「するとボード横はこう」は「して」を表し、その後実行を待ちます。 listen 0.0.0.0:8080 接続待ち... このSTATEでPCのブラウザから http://192.0.2.1:8080/ を开いてください。 図13:ブラウザからボードにアクセスする   ボードラテラルにはリクエストがされます。 接続あり: None リクエスト先頭: b'GET / HTTP/1.1' 接続あり: None となっているのが、セクション 7.2 に触れられた accept() の非実装组です。身体と身体のつながりも同様で、コミュニケーションが障害となります。 Python の数十行、マイコンが Web サーバになりました。ここから、センサーの値を HTML に埋めて無視すれば、第 6 章温度テスター 温度計 温度計 になります。 8.6 LED照明制御操作 最初のセクションは最初のセクション、最後のセクションは最後のセクションです。今日はブラウザからボードのLEDを操作できますようにみます。 第 3 章: で光らせた LED を、 /on と /off という URL で切り代えます。 import socket from machine import Pin from config import PINS led = Pin(PINS["LED_RED"], Pin.OUT, value=1) # 1 = 消灯 srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(("0.0.0.0", 8080)) srv.listen(1) print("http://192.0.2.1:8080/ を開いてください") running = True while running: cl, _ = srv.accept() try: req = cl.recv(256) path = req.split(b" ")[1] if b" " in req else b"/" if path == b"/on": led.value(0) # アクティブ・ロー: 0で点灯 elif path == b"/off": led.value(1) elif path == b"/quit": running = False state = "ON" if led.value() == 0 else "OFF" cl.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n" "Connection: close\r\n\r\n" " FRDM-MCXN947 " " RED LED: %s " " ON / OFF " "" % state) except OSError as e: print("接続エラー(無視):", e) # 後述.握りつぶして継続する try: cl.close() except OSError: pass srv.close() print("サーバを終了しました") 最初のセクションには 14 行の「が」と 38 行の「ここが」が含まれています。 ブラウザで http://192.0.2.1:8080/ を开くと、「ON」「OFF」のリンクが与ったページが出ます。クリックするたびに、ボードの红LEDが実界に点々出てきました。 図14:ブラウザからボードのLEDを操作する http://192.0.2.1:8080/quit を开すればサーバが終わりになります、REPLに戻ります。 ここまで引っ越しなら成功です。コードの中の人、 try / except を入れてある理由については発行录にまとめました。 8.7 電源装置が電源装置に接続されています。 ここまでは,PCからスクリプトを実行していました。最後に、 PC ベースの電源装置には電源装置 40 によって電力が供給されます。 MicroPythonが起動すると、 /flash は起動時に自動的に使用されます。 _boot.py … ファイルシステムのマウントなど(ファームウェアに内蔵,変更不可) boot.py … あれば実行される(起動時の設定用) main.py … あれば実行される(アプリケーション用) つまり /flash/main.py として保存したスクリプトは、電源を入れるだけで動きます。 セクション 7.6 LED オペレーション システム main.py LED オペレーションを保存します。 Thonnyなら,エディタで開いたSTATUSで「ファイル」→「名前を払って保存」を選択して、最初に「MicroPythonデバイス」を選択して main.py という名前にします。 mpremote なら時の正論です。 mpremote cp led_server.py :/flash/main.py 保存したらUSBケーブルを除いて、ACアダプターやモバイルバッテリーなど、電源システムにおいでください。 LANケーブルは組み立ててあります。 しばらく出てから PC のブラウザで http://192.0.2.1:8080/ を开くと、 PC ベースの LED ディスプレイ、LED ディスプレイ オペレーション システム。 Python の数十行をブックいて main.py という名前の前で設定しただけで、ネッ トワーク クロスしにできるマシンになりました。 「抜け道」のつもりで保存しなければならない それに注意を払うことが重要です。 main.py はSTARTのたびに実行されます。もしその中文が accept() で出続けているんだったら, REPLは永久に戻ってきません。セクション 8.8 : べるとおり、このポートには settimeout() が無く、Ctrl-C でも抜けられないからです。 今後REPLに入れないということは,その main.py を抜くこともできないというSTATUSになります。 セクション 7.6 のコードに /quit を入れてあるのは、このためです。ブラウザで http://192.0.2.1:8080/quit を开ればスクリプトが終わり、REPL が来ます。ネットワーク経絡上のVERYKou というわけです。 main.py 仕事の順序は時間の順序であり、順序は時間の順序である。 まずは通常のスクリプトとして実行し、今後の行動を確認することを楽しみにしています 終わりは終わり、手段は終わり、終わりは確定した( /quit など) それから main.py として保存する いきなり main.py に书いて Try すのは避けてください。 8.8 ハマりやすいポイント settimeout() がないので、ブロックすると戻ってきません ご注意ください。 accept() や recv() は、手が来て待機が終わります。通常、MicroPython settimeout() 待機時間の上限は待機時間の上限です。 なお、これはC语のレベルで待っているのでCtrl-Cが効きません。状態が良くなるとREPLは力を入れて受けるのが得意です。 筆者も同様で、電源は必須です。リセットボタンでも戻らないことがあります。 対泽としては、 accept() を実行したら,すぐに与続しに行く(ブラウザのアドレスバーにURLを入れておき,実行後すぐ开けるようにしておく) 缲り回し受信けペイできるサーバには、 8.6の /quit のような抜け道を必ず覚悟しておく アクション main.py セクション8.7 . エラーで正に合ったあとは EADDRINUSE になります サーバーのプログラムが途中でエラーが終了しました、待って受信けに使っていたソケットが开じられないまま残っています。そのSTATEでもう一度実行するとこうなります。 Traceback (most recent call last): File " ", line 10, in __main__ OSError: [Errno 112] EADDRINUSE 「そのアドレスとポートはもう使われている」という意味です。 SO_REUSEADDR いても、以前のソケットが本道开いたままなら効果はありません。 Ctrl-D でソフトリセットすれば、MicroPython が再起動されてソケットがすべてliberate ます。サーバーを书いてテストしているときは、エラーが出たらまず Ctrl-D を取る、と覚えておくと楽です。 ネットワークはREPLが止まっていても動いています これは知っておくと切り分けが楽になります。 Zephyr IP スタックはMicroPython とはbie のスレッドで移動可能であるため、 MicroPython がしっかりしていてもping には応答します。 つまり、「pingは通るのにREPLが抜き濜」というSTATUSは、Ethernetの失敗ではなくMicroPythonがブロックしていることを表示しています。逆に「pingも通らない」ならケーブルやSETを怪しいう、という切り分けができます。 DNS環境シーケンス socket.getaddrinfo() 名前解決もできますが、DNS サーバーのアドレスは CONFIG_DNS_SERVER1 の確立された値が 192.0.2.2 になりました。 DHCP環境、DHCP、マッチング、DNSなど。 直接接続の構成は名前の前にソリューションがあり、IPは直接指定です。 ▲ カタログに戻る 9. まとめ FRDM-MCXN947でMicroPythonをアニメーションかすまでの一通りを見てきました。最後の重要なポイントは、それを整理することです。 今度はもう一度やってみます ホーム micropython/micropython の master に FRDM-MCXN947 の設定があったことで、パッチを当てずに本家のソースからそのままビルドできるようになりました。 /flash 有線イーサネット接続 MicroPython がアニメーションく安いボードの多くは無線でネットワークにシステムぎますが、このボードは有線のイーサネットをホールドしてます。電波は使われる場所であり、電波の目的は電波の安定性と目的です。このメモはウェブページで確認されました。バ見てブラウザから見たところを実機で確認しました。 ゼファーの弱点、その弱点 ピンを ("gpio0", 10) のようなタプルで指定しなければならない点が、このポートの一盘の使いにくさです。これは config.py に PINS 辞書を意にして /flash/lib/ に志してで、実用上ほぼ解出できます。本の最初の名前は本です、名前は本です、名前は本です、名前は本です KeyError で検出ようできるという子的な効果もあります。 ひきこもり ボード設定ファイルの名前は、ボード変更サブ組み込みの frdm_mcxn947_mcxn947_cpu0.conf で認められません クローンしたあとに git submodule update --init lib/micropython-lib が必要です RGB LEDはアクティブ・ロー。 value(0) で光る( off() を火ぶと光る) Pin に toggle() はない スイッチ入力は Pin.IN, Pin.PULL_UP で構成されます。大下 0 (LEDと同じアクティブ・ロー) Pin.irq() が使えます。 hard=False を設立しましたのでハンドラ内で print() してよい このボードのArduinoヘッダーのI²Cは、A4/A5ではなく専用のSDA/SCLピン(P4_0/P4_1) machine.I2C に freq= / scl= / sda= / timeout= は指定できない(devicetree で決定まる) SPIの自動制御システム、 machine.Pin 手動制御システム MicroPyth には I3C がないため、ジャンパで I²C バスに引用する必要がある os.uname() はこのポートでは组見受け入れられていない ネットワークは socket のみ. network モジュールはありません socket に getsockname() が無いので、自分の IP は bind() の成不でアニメーションべる socket に settimeout() が無い。 accept() や recv() でブロックするとCtrl-Cでも抜けられず、電源の入れストレートしが必要になることがある accept() が洗い合おう元アドレスは长に None accept() は失敗しても例外を投票げない。無効なソケットが返されました、回の recv() が EBADF になるので、 try / except OSError で囲む サーバがエラー終了するポートが洴まれたままになります。 Ctrl+D で解放します IPアドレスは実行時に変更できません。 Kconfigで決意まるのでビルドしましょう このビルドでは input() が使えません(関数レベルが BASIC_FEATURES のため。対言说ちが必要なときは time.sleep() (によるカウントダウンで代用します) MicroPython は非常に強力で強力です。 FRDM-MCXN947 高性能なマイコンでも、MicroPython でづかして感情をつかんでから本片の実装を C で书く、という入り方は十に见実的だと思います。 ぜひお試ししてみてください。 ▲ カタログに戻る 10.参考文献 MicroPython MicroPython公式サイト MicroPython ドキュメント MicroPython GitHub リポジトリ MicroPython Zephyrポートのreadme 今回はマージされたPull Request (#19573) ゼファー ゼファープロジェクト公式サイト Zephyr入門ガイド Zephyr FRDM-MCXN947 ボードドキュメント Zephyrシリーズ 第2章 はじめてのビルドと実機アニメーション(日本语ブログ) ツール ソニー公式サイト Thonnyのインストールとの基本操作(YouTube) mpremote ドキュメント ハードウェア FRDM-MCXN947製品 MCX Nシリーズ 製品ページ P3T1755 製品ページ バス NXPコミュニティ・ブログ:I²Cバスの概要 (日本语ブログ) NXPカメラ NXPコントローラ:I3Cプログラマの概要 NXPコミュニティ・ブログ:I²Cハードウェア・デバッグ (日本语ブログ) ▲ カタログに戻る 11. 補足事項:LED動作システムの説明 セクション 8.6のコードについて、中国語の说をここにまとめました。この記事の流れは 2 つの部分に分けられる唯一のものです。アニメーションかすだけなら考えなくても構築しない。 11.1 ここまでのコンテンツが1まとめている このコードは小さいわりに、この记事で読んだことをほとんど使っています。 from config import PINS — 第4章の定義 Pin(PINS["LED_RED"], ...) — LEDの3章。 value(0) でLighting Upセクション 3.5説明したアクティブ・ローだからです socket — 小説第7章 11.2コードの3つのしはんけ (1) while True セクション 8.5のサーバは 1 return で終了わりで一応、運用を続けるには缲り回しが要ります。 accept() 問題、セクション 8.8の問題のステータス、および問題のステータスを待っています。 そこ /quit しました。 elif path == b"/quit": running = False ブラウザで http://192.0.2.1:8080/quit を开くと、最後の応答答えしてからループをけ、REPLが来ます。たった2行ですが、これが無いとプログラムを止めるめる入れる手段が力のストレートししかなくなります。 (2) リクエストからパスをとり出す ブラウザは、続くときのような文字列を受信して、まいりますを送信します。 GET /on HTTP/1.1 Host: 192.0.2.1:8080 ... このうち必要はない真ん中の /on の部分だけです。空白部分がカットされ、2つのアイテムが切り取られます。 path = cl.recv(256).split(b" ")[1] b" " そうのように b が発行しているのは、コミュニケーションで受け取ったけたけるのが文字行ではなくバイト行だからです。比較する側も b"/on" と书く必要があります。 (3)現状の反映 led.value() 今の出力が読めます。アクティブ・ローなので 0 が軽いです。 state = "ON" if led.value() == 0 else "OFF" これで、ページを开きまっすぐたびに現在の状態がされます。 11.3 例外が必要な理由 ナオの著書『 try / except 』は、その地方の歴史についての物語です。 cl, _ = srv.accept() path = cl.recv(256).split(b" ")[1] # ← ここで落ちることがある 今度こう书くと、ブラウザで操作を缲りリターンすうちに必ずいつかのエラーで停止します。 Traceback (most recent call last): File " ", line 16, in OSError: [Errno 9] EBADF EBADF は「無なファイル记子」という意味です。 accept() が回ってきたソケットが、まともに使える状態にはなりません。 理由は、はこのポートの実装にあります。 ports/zephyr/modsocket.c の accept は、こうなっています。 int ctx = zsock_accept(socket->ctx, &sockaddr, &addrlen); socket_obj_t *socket2 = socket_new(); socket2->ctx = ctx; /* エラーチェックが無い */ じファイルの彼のオフ番号は RAISE_SOCK_ERRNO(res) で戻り値を検checkしているのと同じで、 accept だけが検checkをしていません。 zsock_accept() が失敗して -1 を返しても、それはそのままその中身としてホールドち戻ってしまいます。その結果、の recv() が EBADF になるとき、という流れです。 ではなぜ accept() が失敗するのか。 Zephyrに扱えるネットワーク开続の数に上限があるためです。 CONFIG_NET_MAX_CONTEXTS=6 CONFIG_NET_TCP_TIME_WAIT_DELAY=1500 同時に6チャンネルの通信が使用でき、通信終了時間は TIME_WAIT 秒です。ブラウザはページ本のほかに /favicon.ico なども取りに来るので、続けてクリックしていると、あっという間の6枚を作ります。 例外は例外です。これで. except OSError as e: print("接続エラー(無視):", e) cl.close() も try で囲んであるのは、壊れたソケットを閉じようとして、そこまた例外が出るのを防ぐためです。 実记にどのくらい失敗するのか 著者の環境ではテストが行われていません。 作戦のペース 成功/トライアル 間隔を置いて連続して打撃を行う 32 / 40 1秒間隔 15 / 15 2秒間隔 10/10 表 10: クリックの快さと応答 りこぼし 人がブラウザをクリックする程度のスピードさであれば、とりこぼしは起きません。継続して最初のものと戦い、最初のものは最初のもの、例外は最初のもの、例外は最初のものです。もう一度言いますが、昼も夜も普通です。 11.4 Connection: close について これは のです。急行に切れてもらうこで、枠の解放をはーいます。 11.5 その他気をつける点 ページの文字はASCIIにしてあります。日本語を入れる機会は Content-Type: text/html; charset=utf-8 としてください req.split(b" ")[1] if b" " in req else b"/" としているのは、 recv() が空を回ったとき IndexError で流さないようにするためです Connection: close 返却の理由は、記録の説明です。 11.6 未来の未来 accept() のエラーチェックが意味がありません、メインレポートの場合はされうる部分を修正しました。修正されれば accept() が正しく例外をげられるので、 try / except の书き方も素正になります。ここに书いたコンテンツは、2026 年 8 月時点で公開されました。 ここまで来れば、あは応用です。 led を 3 色 RGB 操作パネル、第 6 章: 温度、温度、温度、温度、温度、温度計、温度計 ▲ カタログに戻る 最終更新日:2026年9月2日:初版 ========================= この投稿の「コメント」欄は作成者によって書かれており、返信レターは現在作成者によって書かれています。 (当社は同社のNXP代理店、NXPのNXP販売店、NXPのパートナーであり、ご質問の直接の担当者はNXPです。) MicroPythonの本家R&D、ZephyrのZephyr、FRDM-MCXN947のFRDM-MCXN947の設定。 NXP NXP MicroPython MicroPython i.MX RT MCX Nシリーズが続いたことになります。 この记事では、増設のビルドと书き込みから开みて、REPLでの対線操作、Lチカ、スイッチ入力とカットり込み、I²C温度センサー、SPI、有線イーサネット、Webセンサー、LEDを操作するところまでを、フォローして説明します。機械の動作は機械の動作によって確認されます。 「MicroPythonをタッチするのは初めて」という方を考えて、途中でつまずきやすい点や、このポート固有の制限と回避戦略も有って书きました。 MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947MicroPython and FRDM-MCXN947MicroPythonとFRDM-MCXN947 イーサネット インタフェース 導入 MCX 日本語ブログ Re: FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) 有料級の記事ですね。非常に興味深いです。 Re: FRDM-MCXN947でMicroPythonを動かす (日本語ブログ) ありがとうございます
記事全体を表示
S32プラットフォーム用S32デザインスタジオ3.5ライセンス 私はノートパソコンとデスクトップパソコンをそれぞれ1台ずつ持っています。ノートパソコンでS32 Design Studioをアンインストールして再インストールするには、S32 Platform 3.5用のライセンスが2つ必要です。
記事全体を表示
S32K344/S32K388 MPU Setting Check I'm trying to create a generic, default MPU configuration for the S32K344 and S32K388. I have a basic proposal here, but I would love some confirmation that this looks like it covers everything - especially the register sections - correctly. The types here aren't super important - hopefully you can tell the matching types based on the names. The only odd one is "u4" which is just a wrapper for validating a unsigned 4-bit integer /// S32K344 core-local memories and peripheral windows, using regions 0 through 5. /// /// Geometry: S32K3xx_memory_map.xlsx, Memories sheet, S32K344 column. /// Attributes: S32K3xx RM rev. 12, sections 3.7, 3.9, and 5.2. pub const S32K344_BASE_REGIONS: [MpuRegionConfig; 6] = [ MpuRegionConfig { region: u4::new(0), base_addr: 0x0000_0000, // ITCM: 64 KiB size_log2: 16, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(1), base_addr: 0x2000_0000, // DTCM: 128 KiB size_log2: 17, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(2), base_addr: 0x2040_0000, // SRAM: 320 KiB size_log2: 19, // 512 KiB envelope; enable five 64 KiB subregions access: AccessPermission::ReadWrite, memory_type: MemoryType::WriteBackReadWriteAllocate, shareable: false, execute_never: true, subregion_disable: 0b1110_0000, }, MpuRegionConfig { region: u4::new(3), base_addr: 0x4000_0000, // AIPS0/1/2: 6 MiB size_log2: 23, // 8 MiB envelope; enable six 1 MiB subregions access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(4), base_addr: 0x0040_0000, // Program flash: 4 MiB size_log2: 22, access: AccessPermission::ReadOnly, memory_type: MemoryType::WriteThrough, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(5), base_addr: 0x1000_0000, // Data flash: 128 KiB size_log2: 17, access: AccessPermission::ReadOnly, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, ]; /// S32K388 core-local memories and peripheral windows, using regions 0 through 6 /// /// Geometry: S32K3xx_memory_map.xlsx /// Each core sees its own 32 KiB ITCM and 64 KiB DTCM at the same local addresses pub const S32K388_BASE_REGIONS: [MpuRegionConfig; 7] = [ MpuRegionConfig { region: u4::new(0), base_addr: 0x0000_0000, // ITCM: 32 KiB per core size_log2: 15, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(1), base_addr: 0x2000_0000, // DTCM: 64 KiB per core size_log2: 16, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(2), base_addr: 0x2040_0000, // SRAM: 768 KiB size_log2: 20, // 1 MiB envelope; enable six 128 KiB subregions. access: AccessPermission::ReadWrite, memory_type: MemoryType::WriteBackReadWriteAllocate, shareable: false, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(3), base_addr: 0x4000_0000, // AIPS0/1/2: 6 MiB size_log2: 23, // 8 MiB envelope; enable six 1 MiB subregions. access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(4), // Program flash: 8 MiB at 0x0040_0000 is not aligned to 8 MiB. // Enable subregions 2..=5 of a 16 MiB envelope, mapping exactly // 0x0040_0000..0x00C0_0000 (end exclusive). base_addr: 0x0000_0000, size_log2: 24, access: AccessPermission::ReadOnly, memory_type: MemoryType::WriteThrough, shareable: false, execute_never: false, subregion_disable: 0b1100_0011, }, MpuRegionConfig { region: u4::new(5), base_addr: 0x1000_0000, // Data flash: 128 KiB size_log2: 17, access: AccessPermission::ReadOnly, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(6), base_addr: 0x4400_0000, // AES_ACCEL: 1 KiB, outside AIPS0/1/2 size_log2: 10, access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0, }, ]; Thanks in advanced for the help! Re: S32K344/S32K388 MPU Setting Check Hi @kscz  The proposed MPU configuration looks good overall, including the region sizes, alignment, and subregion configuration. The main remaining point is to ensure that all required peripheral and PPB/system-register areas are properly covered with the appropriate Device, read/write, and execute-never attributes. If a default-deny region is used, it must have lower priority than the explicitly permitted regions. BR, VaneB Re: S32K344/S32K388 MPU Setting Check Thank you for the check! Re: S32K344/S32K388 MPU Setting Check Hi @kscz  Yes, you are correct. The AIPS regions you have configured look appropriate for covering the address space, and I do not see another peripheral region that would need to be added. Your understanding of the PPB/system-register area is also correct. Since accesses to the PPB use the default system address map, you do not need to add a separate MPU region for it. My previous comment was intended more as a general note to use the appropriate Device, read/write, and execute-never attributes for peripheral regions. I did not mean to imply that I had identified a missing region in your configuration. From this perspective, your current configuration looks good. Re: S32K344/S32K388 MPU Setting Check I'm a little perplexed by your response! "The main remaining point is to ensure that all required peripheral and PPB/system-register areas are properly covered with the appropriate Device, read/write, and execute-never attributes." Am I missing any regions for peripherals? I was hoping for confirmation that the 3 AIPS regions I covered in this configuration was enough that I had correctly covered *all* the peripherals! In a similar vein, I was hoping that you could confirm there were no other regions I'd missed in general. Things like the PPB/system-register areas are exempted from the MPU configuration, no? At least that's my understanding of B3.5.1 of the ARMv7-M architecture reference: > Accesses to the Private Peripheral Bus (PPB) always use the default system address map. > Exception vector reads from the Vector Address Table always use the default system address map. Let me know I've misunderstood something or if this configuration actually looks incomplete!
記事全体を表示
S32K344/S32K388 MPU設定チェック S32K344とS32K388用の汎用的なデフォルトMPU構成を作成しようとしています。ここに基本的な提案がありますが、これがすべて、特に登録セクションを正しく網羅しているように見えるかどうか、確認していただけると幸いです。 ここでの種類はそれほど重要ではありませんが、名前から一致するタイプが分かるはずです。唯一異質なのは「u4」で、これは符号なし4ビット整数を検証するためのラッパーにすぎない。 /// S32K344 core-local memories and peripheral windows, using regions 0 through 5. /// /// Geometry: S32K3xx_memory_map.xlsx, Memories sheet, S32K344 column. /// Attributes: S32K3xx RM rev. 12, sections 3.7, 3.9, and 5.2. pub const S32K344_BASE_REGIONS: [MpuRegionConfig; 6] = [ MpuRegionConfig { region: u4::new(0), base_addr: 0x0000_0000, // ITCM: 64 KiB size_log2: 16, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(1), base_addr: 0x2000_0000, // DTCM: 128 KiB size_log2: 17, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(2), base_addr: 0x2040_0000, // SRAM: 320 KiB size_log2: 19, // 512 KiB envelope; enable five 64 KiB subregions access: AccessPermission::ReadWrite, memory_type: MemoryType::WriteBackReadWriteAllocate, shareable: false, execute_never: true, subregion_disable: 0b1110_0000, }, MpuRegionConfig { region: u4::new(3), base_addr: 0x4000_0000, // AIPS0/1/2: 6 MiB size_log2: 23, // 8 MiB envelope; enable six 1 MiB subregions access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(4), base_addr: 0x0040_0000, // Program flash: 4 MiB size_log2: 22, access: AccessPermission::ReadOnly, memory_type: MemoryType::WriteThrough, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(5), base_addr: 0x1000_0000, // Data flash: 128 KiB size_log2: 17, access: AccessPermission::ReadOnly, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, ]; /// S32K388 core-local memories and peripheral windows, using regions 0 through 6 /// /// Geometry: S32K3xx_memory_map.xlsx /// Each core sees its own 32 KiB ITCM and 64 KiB DTCM at the same local addresses pub const S32K388_BASE_REGIONS: [MpuRegionConfig; 7] = [ MpuRegionConfig { region: u4::new(0), base_addr: 0x0000_0000, // ITCM: 32 KiB per core size_log2: 15, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(1), base_addr: 0x2000_0000, // DTCM: 64 KiB per core size_log2: 16, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(2), base_addr: 0x2040_0000, // SRAM: 768 KiB size_log2: 20, // 1 MiB envelope; enable six 128 KiB subregions. access: AccessPermission::ReadWrite, memory_type: MemoryType::WriteBackReadWriteAllocate, shareable: false, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(3), base_addr: 0x4000_0000, // AIPS0/1/2: 6 MiB size_log2: 23, // 8 MiB envelope; enable six 1 MiB subregions. access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(4), // Program flash: 8 MiB at 0x0040_0000 is not aligned to 8 MiB. // Enable subregions 2..=5 of a 16 MiB envelope, mapping exactly // 0x0040_0000..0x00C0_0000 (end exclusive). base_addr: 0x0000_0000, size_log2: 24, access: AccessPermission::ReadOnly, memory_type: MemoryType::WriteThrough, shareable: false, execute_never: false, subregion_disable: 0b1100_0011, }, MpuRegionConfig { region: u4::new(5), base_addr: 0x1000_0000, // Data flash: 128 KiB size_log2: 17, access: AccessPermission::ReadOnly, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(6), base_addr: 0x4400_0000, // AES_ACCEL: 1 KiB, outside AIPS0/1/2 size_log2: 10, access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0, }, ]; ご協力ありがとうございます! Re: S32K344/S32K388 MPU Setting Check お会計ありがとうございます! Re: S32K344/S32K388 MPU Setting Check あなたの返答には少し戸惑っています! 「残る主なポイントは、必要なペリフェラルおよびPPB/システムレジスタ領域が、適切なデバイス、読み書き、実行-決まり属性で適切にカバーされていることを確認することです。」 ペリフェラルの領域を見落としているのでしょうか?この構成でカバーした3つのAIPS地域が、すべてのペリフェラルを正しくカバーできているかどうかの確認を期待していました! 同様に、他に見落とした地域がないか確認してもらいたいと思っていました。PPB/システムレジスタ領域などは、MPU構成の対象外ですよね?少なくとも、ARMv7-Mアーキテクチャの参照のB3.5.1について私の理解はそうです: > プライベートペリフェラルバス(PPB)へのアクセスは常にデフォルトのシステムアドレスマップを使用します。 > Exception ベクトルはベクトルアドレステーブルから読み取る際には常にデフォルトのシステムアドレスマップを使用します。 私が何か誤解している点や、この設定が実際には不完全な点があれば教えてください! Re: S32K344/S32K388 MPU Setting Check こんにちは、 @ksczさん はい、おっしゃる通りです。あなたが設定したAIPSリージョンはアドレス空間をカバーするのに適しているように見え、追加が必要な周辺領域は見当たりません。 PPB/システムレジスタ領域に関するあなたの理解も正しいです。PPBへのアクセスはデフォルトのシステムアドレスマップを使用するため、別途MPUリージョンを追加する必要はありません。 私の前のコメントは、ペリフェラル領域に対して適切なDevice、read/write、execute-never属性を使うという一般的な注意書きを意図していました。設定ファイルに欠落している領域を見つけたという意味で言ったのではありません。 この観点からすると、現在の構成は良好に見えます。 Re: S32K344/S32K388 MPU Setting Check こんにちは、 @ksczさん 提案されたMPU構成は、領域サイズ、配置、サブ領域構成を含め、全体的に良好に見える。 残る主なポイントは、必要なペリフェラルおよびPPB/システムレジスタ領域が、適切なDevice、read/write、execute-never属性で適切にカバーされていることを確認することです。デフォルト拒否領域を使用する場合、明示的に許可された領域よりも優先順位を低く設定する必要があります。 BR、VaneB
記事全体を表示
S32K344/S32K388 MPU 设置检查 我正在尝试为 S32K344 和 S32K388 创建一个通用的默认 MPU 配置。我这里有一个基本方案,但我希望得到确认,这个方案是否涵盖了所有内容——尤其是注册部分——并且是正确的。 这里的类型并不是特别重要——希望你能根据名称判断出匹配的类型。唯一比较特殊的是“u4”,它只是一个用于验证无符号 4 位整数的包装器。 /// S32K344 core-local memories and peripheral windows, using regions 0 through 5. /// /// Geometry: S32K3xx_memory_map.xlsx, Memories sheet, S32K344 column. /// Attributes: S32K3xx RM rev. 12, sections 3.7, 3.9, and 5.2. pub const S32K344_BASE_REGIONS: [MpuRegionConfig; 6] = [ MpuRegionConfig { region: u4::new(0), base_addr: 0x0000_0000, // ITCM: 64 KiB size_log2: 16, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(1), base_addr: 0x2000_0000, // DTCM: 128 KiB size_log2: 17, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(2), base_addr: 0x2040_0000, // SRAM: 320 KiB size_log2: 19, // 512 KiB envelope; enable five 64 KiB subregions access: AccessPermission::ReadWrite, memory_type: MemoryType::WriteBackReadWriteAllocate, shareable: false, execute_never: true, subregion_disable: 0b1110_0000, }, MpuRegionConfig { region: u4::new(3), base_addr: 0x4000_0000, // AIPS0/1/2: 6 MiB size_log2: 23, // 8 MiB envelope; enable six 1 MiB subregions access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(4), base_addr: 0x0040_0000, // Program flash: 4 MiB size_log2: 22, access: AccessPermission::ReadOnly, memory_type: MemoryType::WriteThrough, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(5), base_addr: 0x1000_0000, // Data flash: 128 KiB size_log2: 17, access: AccessPermission::ReadOnly, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, ]; /// S32K388 core-local memories and peripheral windows, using regions 0 through 6 /// /// Geometry: S32K3xx_memory_map.xlsx /// Each core sees its own 32 KiB ITCM and 64 KiB DTCM at the same local addresses pub const S32K388_BASE_REGIONS: [MpuRegionConfig; 7] = [ MpuRegionConfig { region: u4::new(0), base_addr: 0x0000_0000, // ITCM: 32 KiB per core size_log2: 15, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: false, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(1), base_addr: 0x2000_0000, // DTCM: 64 KiB per core size_log2: 16, access: AccessPermission::ReadWrite, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(2), base_addr: 0x2040_0000, // SRAM: 768 KiB size_log2: 20, // 1 MiB envelope; enable six 128 KiB subregions. access: AccessPermission::ReadWrite, memory_type: MemoryType::WriteBackReadWriteAllocate, shareable: false, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(3), base_addr: 0x4000_0000, // AIPS0/1/2: 6 MiB size_log2: 23, // 8 MiB envelope; enable six 1 MiB subregions. access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0b1100_0000, }, MpuRegionConfig { region: u4::new(4), // Program flash: 8 MiB at 0x0040_0000 is not aligned to 8 MiB. // Enable subregions 2..=5 of a 16 MiB envelope, mapping exactly // 0x0040_0000..0x00C0_0000 (end exclusive). base_addr: 0x0000_0000, size_log2: 24, access: AccessPermission::ReadOnly, memory_type: MemoryType::WriteThrough, shareable: false, execute_never: false, subregion_disable: 0b1100_0011, }, MpuRegionConfig { region: u4::new(5), base_addr: 0x1000_0000, // Data flash: 128 KiB size_log2: 17, access: AccessPermission::ReadOnly, memory_type: MemoryType::NonCacheable, shareable: false, execute_never: true, subregion_disable: 0, }, MpuRegionConfig { region: u4::new(6), base_addr: 0x4400_0000, // AES_ACCEL: 1 KiB, outside AIPS0/1/2 size_log2: 10, access: AccessPermission::ReadWrite, memory_type: MemoryType::SharedDevice, shareable: true, execute_never: true, subregion_disable: 0, }, ]; 提前感谢您的帮助! Re: S32K344/S32K388 MPU Setting Check 谢谢你的支票! Re: S32K344/S32K388 MPU Setting Check 你的回复让我有点困惑! “剩下的主要一点是确保所有必需的外围设备和 PPB/系统寄存器区域都已正确覆盖适当的设备、读/写和永不执行属性。” 我是否遗漏了外设方面的信息?我希望得到确认,我在此配置中覆盖的 3 个 AIPS 区域是否足以正确覆盖*所有*外围设备! 同样地,我希望您能确认一下,我是否遗漏了其他地区。像 PPB/系统寄存器区域这样的部分不属于 MPU 配置的范畴,对吗?至少这是我对 ARMv7-M 架构参考,引用 B3.5.1 节的理解: 对专用外设总线 (PPB) 的访问始终使用默认系统地址映射。 > 从向量地址表读取异常向量时,始终使用默认系统地址映射。 如果我的理解有误,或者这个配置看起来不完整,请告诉我! Re: S32K344/S32K388 MPU Setting Check 嗨@kscz 所提出的 MPU 配置总体上看起来不错,包括区域大小、对齐方式和子区域配置。 剩下的主要一点是确保所有必需的外围设备和 PPB/系统寄存器区域都已正确覆盖适当的设备、读/写和永不执行属性。如果使用默认拒绝区域,则其优先级必须低于明确允许的区域。 BR,VaneB Re: S32K344/S32K388 MPU Setting Check 嗨@kscz 是的,你说得对。您配置的 AIPS 区域看起来足以覆盖地址空间,我没有看到还需要添加其他外围区域。 您对 PPB/系统寄存器区域的理解也是正确的。由于对 PPB 的访问使用默认的系统地址映射,因此无需为其添加单独的 MPU 区域。 我之前的评论更多的是想提醒大家,要为外围区域使用适当的设备、读/写和执行-永不属性。我并非暗示我已经发现了您配置中缺失的区域。 从这个角度来看,你目前的配置看起来不错。
記事全体を表示
S32 Design Studio for S32 Platform 3.5 License I have one laptop and one desktop computer. Uninstalling and reinstalling on the laptop requires two licenses for S32 Design Studio for S32 Platform 3.5.
記事全体を表示
S32 Design Studio for S32 Platform 3.5 License 本人一个笔记本,一个台式机,笔记本卸载重装,需要2个S32 Design Studio for S32 Platform 3.5 的License
記事全体を表示
imx95-evk: NETC on cortex M7 Hi list, According to AN15047 'i.MX 95 Dual-Ethernet on M7 and A55 - Rev. 1.0 — 19 May 2026', i'm trying to use NETC0 on cortex-m7. The chapter '5 Implementation' section 1.b describes how you can affect NETC2 to A55 non-secure cores and NETC0 to cortex-m7. I downloaded the repository https://github.com/nxp-imx/imx-sm.git (hash:eec2328, tag: lf-6.18.37-2.1.0) and take a to *configs/mx95evk.cfg* to update it according to the former chapter. But there are inconsistencies especially concerning the items 'NETC_ECAM0' and 'NETC_ECAM2' which are available in the documentation but *not* in the repository. The file's *configs/mx95evk.cfg* history doesn't provide any reference to NETC_ECAM0 or NETC_ECAM2 i.e 'git log -S NETC_ECAM2' or 'git log -S NETC_ECAM0' return nothin... Do you know where i can find consistent information to define NETC0 to A55 and NETC2 to cortex-m7 please? Can you provide a file *configs/mx95evk.cfg* which is correct for this configuration please? I'm supposed to include the generated build/mx95evk/m33_image.bin to a yocto build with the manifest imx-6.12.49-2.2.0.xml. Is the tag lf-6.18.37-2.1.0 the right one for imx-sm? Thanks. Re: imx95-evk: NETC on cortex M7 Hi, Thank you for your interest in NXP Semiconductor products, You should refer to the following code that defines ECAM https://github.com/nxp-imx/imx-sm/blob/eec232878ab7dd460f5a8f3767d39dc7e9412efa/devices/MIMX95/configtool/netcmix.cfg#L45 In the appnote is stated that the following changes should be made: # modified split definition NETC_ECAM1: PD_NETC, MBC_E0=1.0-3 NETC_ECAM2: PD_NETC, MBC_E0=1.4-7 So, including netcmix.cfg should make it possible. For Yocto and branch of SM, you should select the SM branch of the BSP you are trying it on, if it's the latest BSP or the one where the appnote was tested with. You could modify the code in Yocto source code, create a patch or build it standalone and use imx-mkimage to generate it. make config=mx95evk cfg make config=mx95evk all Regards Re: imx95-evk: NETC on cortex M7 Hello Joseph, Thanks for your answer. After reading carefully the documentation, i reach your conclusion concerning the file netcmix.cfg and i build successfully the binary. So thanks for your confirmation. Now i'm trying to follow "6.2 Setting up Yocto and building the Linux image", especially the step 5. When i try to update the layer i get: build-imx95-19x19-lpddr5-evk$ bitbake-layers add-layer ../sources/meta-imx-dual-eth-m7-a55 NOTE: Starting bitbake server... WARNING: Layer meta-imx-dual-eth-m7-a55 should set LAYERSERIES_COMPAT_meta-imx-dual-eth-m7-a55 in its conf/layer.conf file to list the core layer names it is compatible with. ERROR: BBFILE_PATTERN_meta-imx-dual-eth-m7-a55 not defined ERROR: Parse failure with the specified layer added, exiting. where imx95-yocto-bsp$ ls sources/meta-imx-dual-eth-m7-a55/ conf LICENSE.txt patch-mcuxsdk README.md recipes-bsp recipes-kernel SBOM.spdx.json sources/meta-imx-dual-eth-m7-a55$ git show commit bd42e153e1f39c06ca148dff90362978567a8449 (HEAD -> lf-6.12.49-2.2.0_25.12, origin/lf-6.12.49-2.2.0_25.12, origin/HEAD) [..] Any hint concerning this issue please? Regards
記事全体を表示
imx95-evk:皮层 M7 上的 NETC 大家好, 根据AN15047 “i.MX 95 双以太网在 M7 和 A55 上 - 修订版 1.0 — 2026 年 5 月 19 日”,我正在尝试在 cortex-m7 上使用 NETC0 。 “5 实现”章节 1.b 节描述了如何将 NETC2 应用于 A55 非安全内核,以及如何将 NETC0 应用于 cortex-m7。 我下载了仓库https://github.com/nxp-imx/imx-sm.git (hash:eec2328, tag: lf-6.18.37-2.1.0)然后打开*configs/mx95evk.cfg*文件,根据前一章的内容进行更新。 但存在一些不一致之处,特别是关于“NETC_ECAM0”和“NETC_ECAM2”这两个项目,它们在文档中可用,但在存储库中*不可用* 。 文件*configs/mx95evk.cfg*历史记录中没有提供任何关于 NETC_ECAM0 或 NETC_ECAM2 的引用,即“git log -S NETC_ECAM2”或“git log -S NETC_ECAM0”没有任何返回结果…… 请问您知道哪里可以找到关于NETC0对应A55以及NETC2对应cortex-m7的统一信息吗? 请提供文件 *configs/mx95evk.cfg*请问哪种配置才是正确的? 我应该将生成的 build/mx95evk/m33_image.bin 添加到带有清单 imx-6.12.49-2.2.0.xml的yocto 版本中。 标签lf-6.18.37-2.1.0哪个型号适合 imx-sm? 谢谢。 Re: imx95-evk: NETC on cortex M7 您好, 感谢您对恩智浦半导体产品的关注, 您应该参考以下定义 ECAM 的代码:https://github.com/nxp-imx/imx-sm/blob/eec232878ab7dd460f5a8f3767d39dc7e9412efa/devices/MIMX95/configtool/netcmix.cfg#L45 应用说明中指出,应进行以下更改: # modified split definition NETC_ECAM1: PD_NETC, MBC_E0=1.0-3 NETC_ECAM2: PD_NETC, MBC_E0=1.4-7 因此,包含 netcmix.cfg 文件应该可以实现这一点。 对于 Yocto 和 SM 分支,您应该选择您正在尝试的电路板支持包的 SM 分支,如果它是最新的电路板支持包或应用笔记中测试的电路板支持包。您可以修改 Yocto 源代码中的代码,创建补丁,或者将其独立构建并使用 imx-mkimage 生成独立组网 \(SA\)。 make config=mx95evk cfg make config=mx95evk all 此致 Re: imx95-evk: NETC on cortex M7 你好,约瑟夫, 谢谢你的回答。 仔细阅读文档后,我认同您关于netcmix.cfg文件的结论,并成功构建了二进制文件。 谢谢你的确认。 现在我正在尝试遵循“6.2设置 Yocto 并构建 Linux 镜像”,特别是第 5 步。 当我尝试更新层时,出现以下错误: build-imx95-19x19-lpddr5-evk$ bitbake-layers add-layer ../sources/meta-imx-dual-eth-m7-a55 注意:Bitbake 服务器正在启动…… 警告:层 meta-imx-dual-eth-m7-a55 应在其 conf/layer.conf 文件中设置 LAYERSERIES_COMPAT_meta-imx-dual-eth-m7-a55,以列出与其兼容的核心层名称。 错误:未定义 BBFILE_PATTERN_meta-imx-dual-eth-m7-a55 错误:添加指定层时解析失败,程序退出。 其中: imx95-yocto-bsp$ ls sources/meta-imx-dual-eth-m7-a55/ conf LICENSE.txt patch-mcuxsdk README.md 配方-电路板支持包。 配方-kernel SBOM.spdx.json sources/meta-imx-dual-eth-m7-a55$ git show 提交 bd42e153e1f39c06ca148dff90362978567a8449 (HEAD -> lf-6.12.49-2.2.0_25.12,origin/lf-6.12.49-2.2.0_25.12,起源/HEAD) [...] 请问关于这个问题有什么线索吗? 此致
記事全体を表示
IMX95-EVK:Cortex M7上のNETC こんにちは、 AN15047『i.MX 95 Dual-イーサネット on M7 and A55 - Rev. 1.0 — 2026年5月19日』によると、Cortex-m7でNETC0を使おうとしています。 第5章「実装」セクション1.bでは、NETC2からA55非セキュアコア、NETC0からcortex-m7への影響方法が説明されています。 リポジトリhttps://github.com/nxp-imx/imx-sm.git (ハッシュ: eec2328、タグ: lf-6.18.37-2.1.0) をダウンロードしました。そして、 *configs/mx95evk.cfg*に移動して、前の章に従って更新します。 しかし、特にドキュメントにはあるもののリポジトリ には存在しない「NETC_ECAM0」と「NETC_ECAM2」という項目に関して矛盾があります。 ファイルの内容は*configs/mx95evk.cfg* です。履歴には NETC_ECAM0 または NETC_ECAM2 への参照が一切ありません。つまり、「git log -S NETC_ECAM2」または「git log -S NETC_ECAM0」を実行しても何も返されません。 NETC0からA55、NETC2からcortex-m7までを定義するための一貫した情報をどこで見つけられますか? ファイルを提供できますか *configs/mx95evk.cfg*この構成の場合、どちらが正しいでしょうか? 生成されたビルド/mx95evk/m33_image.binを 、マニフェストimx-6.12.49-2.2.0.xml付きのYoctoビルドに含めるべきです。 タグはlf-6.18.37-2.1.0ですか?imx-smに最適なのはどれですか? ありがとうございます。 Re: imx95-evk: NETC on cortex M7 こんにちは、 NXP Semiconductors製品にご関心いただきありがとうございます。 ECAMを定義する以下のコードを参照してください。https://github.com/nxp-imx/imx-sm/blob/eec232878ab7dd460f5a8f3767d39dc7e9412efa/devices/MIMX95/configtool/netcmix.cfg#L45 アプリケーションノートには、以下の変更を行う必要があると記載されています。 # modified split definition NETC_ECAM1: PD_NETC, MBC_E0=1.0-3 NETC_ECAM2: PD_NETC, MBC_E0=1.4-7 ですので、netcmix.cfgを含めることで可能になるはずです。 YoctoとSMのブランチの場合は、試しているBSPのSMブランチを選ぶべきです。最新のBSPか、Appnoteがテストされたものであれば。Yoctoのソースコードでコードを修正したり、パッチを作成したり、単体で構築してimx-mkimageで生成することもできます。 make config=mx95evk cfg make config=mx95evk all よろしくお願いします。 Re: imx95-evk: NETC on cortex M7 こんにちは、ジョセフさん。 ご回答ありがとうございます。 ドキュメントを注意深く読んだ結果、 netcmix.cfg ファイルに関する結論に達し、バイナリを成功裏に構築しました。 SO、ご確認ありがとうございます。 今は「6.2」に従おうとしていますYoctoの設定とLinuxイメージのビルディング」、特にステップ5について。 レイヤーを更新しようとすると、次のような結果が出ます: build-imx95-19x19-lpddr5-evk$ bitbake-layers add-layer ../sources/meta-imx-dual-eth-m7-a55 注:bitbakeサーバーを起動しています... 警告: レイヤー meta-imx-dual-eth-m7-a55 は、互換性のあるコア レイヤー名をリストするために、conf/layer.conf ファイルで LAYERSERIES_COMPAT_meta-imx-dual-eth-m7-a55 を設定する必要があります。 エラー: BBFILE_PATTERN_meta-imx-dual-eth-m7-a55 が定義されていません エラー: 指定されたレイヤーを追加した状態で解析に失敗しました。終了します。 ここで、 IMX95-yocto-bsp$ LS ソース/meta-imx-dual-eth-m7-a55/ conf LICENSE.txt patch-mcuxsdk README.md recipes-bsp recipes-kernel SBOM.spdx.json sources/meta-imx-dual-eth-m7-a55$ git show コミット bd42e153e1f39c06ca148dff90362978567a8449 (HEAD -> lf-6.12.49-2.2.0_25.12、origin/lf-6.12.49-2.2.0_25.12、起源/HEAD) [..] この件に関して何かヒントがあれば教えてください。 よろしくお願いします。
記事全体を表示
i.MX 93 – 预构建的 Ubuntu/Debian Linux 镜像和定制载板支持 您好,NXP支持团队, 我正在评估 i.MX 93 平台在 EVSE 应用方面的性能,并发现了EVSE-IMX93 开发套件。 我想澄清一下可用的 Linux 镜像及其与潜在的定制载板设计的兼容性。 我们的目标是使用 MCIMX93-SOM,并基于 NXP 原有的载板设计开发一款简化的定制载板。我们将保留相同的SOM连接器和引脚分配,同时移除未使用的外围设备和电路。 由于我对 i.MX 处理器平台和基于 Yocto 的开发还比较陌生,我正在寻找一个简单易用的 Linux 解决方案来入门,然后再进行自定义。 请问您能否澄清以下问题? 是否有适用于 i.MX 93 的现成 Ubuntu 或 Debian 13 (Trixie) 镜像?最好是通用服务器/最小 Linux 镜像。 这个镜像可以直接下载并刷入microSD卡来启动板,而无需Yocto构建吗? 提供的镜像是否支持标准的 Linux 功能,例如apt 、Python 3、SSH、systemd 和网络功能? 它是否支持CAN/CAN-FD (SocketCAN)、Wi-Fi、以太网和 MQTT ?是否可以使用apt安装 Mosquitto 等软件包? 在我们保留原有SOM连接器和相关硬件连接的前提下,能否将相同的预构建镜像用于我们提出的定制载板?是否只需要更改设备树或配置? 如果有这样的镜像文件,能否分享一下直接下载链接、支持的板信息和安装说明? 我们的目标是将 i.MX 93 用作运行 EVerest 框架和其他 EVSE 应用软件的通用 Linux 平台,同时避免最初维护 Yocto 构建的需要。 谢谢你的帮助。 此致敬礼 加内什·巴格瓦特 Re: i.MX 93 – Prebuilt Ubuntu/Debian Linux Image and Custom Carrier Board Support 你好, 是的,有一个与 i.mx93 平台兼容的 Debian Linux SDK,您可以通过“Flexbuild”的实现来构建镜像,而不是使用 Yocto,然后使用 flexinstaller 工具刷写镜像。有关该发行版支持的软件包的更多信息,请参阅此处: DEBIAN-SDK Debian 软件版本说明 LDLSDK_26.06
記事全体を表示