tag 标签: iMX8MP

相关博文
  • 2025-1-7 14:52
    320 次阅读|
    0 个评论
    B y Toradex 秦海 1). 简介 嵌入式平台设备基于 Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。 本文所 示例 的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台 。 2. 准备 a). Verdin i.MX8MP ARM 核心版配合 Dahlia 载板 并连接 Debug Console 和 HDMI 显示器进行测试。 3). 测试流程 a). 参考 这里 说明下载 Toradex Yocto Linux BSP7 对应 U-Boot 源码,根据如下 patch 文件修改编译配置后重新编译 U-Boot Image 。 ------------------------------- --- a / . config2024-12-27 14:52:26.151705541 +0800 +++ . b/. config2025-01-03 17:41:42.779299312 +0800 @@ -535,9 +535,13 @@ # CONFIG_DISABLE_CONSOLE is not set CONFIG_LOGLEVEL=4 CONFIG_SPL_LOGLEVEL=4 -# CONFIG_SILENT_CONSOLE is not set -# CONFIG_SPL_SILENT_CONSOLE is not set +CONFIG_SILENT_CONSOLE=y +CONFIG_SPL_SILENT_CONSOLE=y # CONFIG_TPL_SILENT_CONSOLE is not set +# CONFIG_SILENT_U_BOOT_ONLY is not set +CONFIG_SILENT_CONSOLE_UPDATE_ON_SET=y +CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC=y +# CONFIG_SILENT_CONSOLE_UNTIL_ENV is not set # CONFIG_PRE_CONSOLE_BUFFER is not set CONFIG_CONSOLE_FLUSH_SUPPORT=y # CONFIG_CONSOLE_FLUSH_ON_NEWLINE is not set @@ -644,7 +648,7 @@ CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x42200000 CONFIG_SPL_SYS_MALLOC_SIZE=0x80000 -CONFIG_SPL_BANNER_PRINT=y +# CONFIG_SPL_BANNER_PRINT is not set # CONFIG_SPL_DISPLAY_PRINT is not set CONFIG_SPL_SYS_MMCSD_RAW_MODE=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y ------------------------------- b). 参考 这里 说明重新组装 Verdin i.MX8MP Boot Container ,在编译 ATF Image 的时候参考如下命令来关闭 log 输出。 ------------------------------- $ make PLAT=imx8mp IMX_BOOT_UART_BASE=0x30880000 LOG_LEVEL=0 DEBUG=0 bl31 ------------------------------- c). 从下面地址下载 Yocto linux BSP7 Minimal/Multimedia Image 并解压。 https://developer.toradex.cn/software/toradex-embedded-software/toradex-download-links-torizon-linux-bsp-wince-and-partner-demos/#bsp-quarterly-releases d). 用上述步骤 b 生成的 flash.bin binary 文件重命名为 “ imx-boot ” 并替换 BSP Image 里面的 “ imx-boot ” 文件。 ------------------------------- $ tar xvf / Verdin-iMX8MP_Reference-Multimedia-Image-Tezi_7.0.0+build.1.tar $ $ cd /Verdin-iMX8MP_Reference-Multimedia-Image-Tezi_7.0.0+build.1/ $ cp /imx-mkimage/iMX8M/flash.bin /Verdin-iMX8MP_Reference-Multimedia-Image-Tezi_7.0.0+build.1/imx-boot ------------------------------- e). 参考如下 patch 修改编译 BSP Image 中的环境变量定义文件。 ------------------------------- --- a/u-boot-initial-env-sd 2024-10-01 21:50:32.000000000 +0800 +++ b/u-boot-initial-env-sd 2024-12-27 16:28:20.000000000 +0800 @@ -19,7 +19,7 @@ bootcmd_mmc1=devnum=1; run mmc_boot bootcmd_mmc2=devnum=2; run mmc_boot bootdelay=1 -console=ttymxc2 +console=null cpu=armv8 distro_bootcmd=setenv nvme_need_init; for target in ${boot_targets}; do run bootcmd_${target}; done efi_dtb_prefixes=/ /dtb/ /dtb/current/ @@ -45,6 +45,7 @@ scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done scriptaddr=0x50280000 soc=imx8m +silent=1 update_uboot=askenv confirm Did you load flash.bin (y/N)?; if test "$confirm" = "y"; then setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200; mmc dev 2 1; mmc write ${loadaddr} 0x0 ${blkcnt}; fi usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi usb_ignorelist=0x1050:*, ------------------------------- // 当然, U-Boot 环境变量的修改也可以通过修改 U-boot 源代码中 include/configs/verdin-imx8mp.h 文件来修改,本文不做赘述。 // 如果只需要不显示部分 Kernel log 信息,则可以只设置增加如下环境变量即可,无需重新修改编译 U-Boot ------------------------------- # setenv tdxargs '${tdxargs} quiet' # saveenv ------------------------------- f). 参考 这里 说明将修改的 BSP Image 重新更新到 Verdin i.MX8MP 模块,启动后 Debug Console 输出如下,仅剩下 SPL 配合 ARM 处理器 BootRoM 启动的简单 log 信息输出,其他 U-Boot 以及 Linux Kernel/Rootfs 等输出均已经不显示。同时此时测试在不进行任何其他优化的前提下,从按下载板 “ Power ON ” 按键开机,到连接的 HDMI 屏幕出现 Qt Cinama Demo 应用显示,一共是 14s 时间。而正常不做任何修改的 Yocto Linux Multimedia BSP 同样情况启动时间在 17s - 18s 。 ------------------------------- DDRINFO: start DRAM init DDRINFO: DRAM rate 4000MTS Training FAILED DDRINFO: start DRAM init DDRINFO: DRAM rate 4000MTS DDRINFO:ddrphy calibration done DDRINFO: ddrmix config done DDR configured as single rank SEC0: RNG instantiated Normal Boot WDT: Started watchdog@30280000 with servicing every 1000ms (60s timeout) Boot Stage: Primary boot Find img info 0x4802d200, size 888 Need continue download 1024 Failed to find node!, err: -1! Failed to find node!, err: -1! ------------------------------- g). 通常情况上面保留 SPL BootROM 启动相关 log 打印即可满足需求,如果一定要完全去掉,就需要逐项查看对应的源代码,当前打印信息对应( BSP 版本变更可能导致变化)以及修改 patch 请见如下,在对应源码中注释掉相关的 “ printf()/puts() ” 打印 log 输出代码重新编译即可,测试下来这样可以将启动时间缩短到 13.8s 左右。 ./ ddr_init.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/ddr/imx/imx8m/ddr_init.c?h=toradex_imx_lf_v2024.04 ------------------------------- DDRINFO: start DRAM init DDRINFO: DRAM rate 4000MTS DDRINFO: start DRAM init DDRINFO: DRAM rate 4000MTS DDRINFO:ddrphy calibration done DDRINFO: ddrmix config done ------------------------------- ./ ddrphy_utils.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/ddr/imx/phy/ddrphy_utils.c?h=toradex_imx_lf_v2024.04#n101 ------------------------------- Training FAILED ------------------------------- ./ spl.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/board/toradex/verdin-imx8mp/spl.c?h=toradex_imx_lf_v2024.04 ------------------------------- DDR configured as single rank Normal Boot ------------------------------- ./ jr.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/crypto/fsl/jr.c?h=toradex_imx_lf_v2024.04#n937 ------------------------------- SEC0: RNG instantiated ------------------------------- ./ wdt-uclass.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/drivers/watchdog/wdt-uclass.c?h=toradex_imx_lf_v2024.04#n143 ------------------------------- WDT: Started watchdog@30280000 with servicing every 1000ms (60s timeout) ------------------------------- ./ spl_imx_romapi.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/arch/arm/mach-imx/spl_imx_romapi.c?h=toradex_imx_lf_v2024.04 ------------------------------- Boot Stage: Primary boot Find img info 0x4802d200, size 888 Need continue download 1024 ------------------------------- ./ spl.c - https://git1.toradex.com/cgit/u-boot-toradex.git/tree/arch/arm/mach-imx/spl.c?h=toradex_imx_lf_v2024.04#n459 ------------------------------- Failed to find node!, err: -1! Failed to find node!, err: -1! ------------------------------- // 完整修改 patch 请见如下 ------------------------------- diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index d6664bf9103..a8ef680593b 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -456,7 +456,7 @@ int board_handle_rdc_config(void *fdt_addr, const char *config_name, void *dst_a node = fdt_node_offset_by_compatible(fdt_addr, -1, "imx8m,mcu_rdc"); if (node < 0) { -printf("Failed to find node!, err: %d!\n", node); +//printf("Failed to find node!, err: %d!\n", node); ret = -1; goto exit; } diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index 8b8d16d911f..fea293cb9ca 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -387,7 +387,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, } imagesize = img_info_size(phdr); -printf("Find img info 0x%p, size %d\n", phdr, imagesize); +//printf("Find img info 0x%p, size %d\n", phdr, imagesize); if (p - phdr < imagesize) { imagesize -= p - phdr; @@ -463,11 +463,11 @@ int board_return_to_bootrom(struct spl_image_info *spl_image, if (ret != ROM_API_OKAY) goto err; -printf("Boot Stage: "); +//printf("Boot Stage: "); switch (bstage) { case BT_STAGE_PRIMARY: -printf("Primary boot\n"); +//printf("Primary boot\n"); break; case BT_STAGE_SECONDARY: printf("Secondary boot\n"); diff --git a/board/toradex/verdin-imx8mp/spl.c b/board/toradex/verdin-imx8mp/spl.c index 73729a42b45..f6bf9260527 100644 --- a/board/toradex/verdin-imx8mp/spl.c +++ b/board/toradex/verdin-imx8mp/spl.c @@ -42,7 +42,7 @@ void spl_dram_init(void) lpddr4_single_rank_training_patch(); if (!ddr_init(&dram_timing)) { -puts("DDR configured as single rank\n"); +//puts("DDR configured as single rank\n"); return; } puts("DDR configuration failed\n"); @@ -69,7 +69,7 @@ void spl_board_init(void) clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5)); clock_enable(CCGR_GIC, 1); -puts("Normal Boot\n"); +//puts("Normal Boot\n"); } #define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PE) diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index 97b0cf83ae7..efb2544de02 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -934,7 +934,7 @@ init: return -1; } -printf("SEC%u: RNG instantiated\n", sec_idx); +//printf("SEC%u: RNG instantiated\n", sec_idx); } #if CONFIG_IS_ENABLED(OF_CONTROL) if (CONFIG_IS_ENABLED(DM_RNG)) { diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index 91d963419d6..06ff6feaa09 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -316,7 +316,7 @@ int ddr_init(struct dram_timing_info *dram_timing) unsigned int tmp, initial_drate, target_freq; int ret; -printf("DDRINFO: start DRAM init\n"); +//printf("DDRINFO: start DRAM init\n"); /* Step1: Follow the power up procedure */ if (is_imx8mq()) { @@ -339,7 +339,7 @@ int ddr_init(struct dram_timing_info *dram_timing) fsp_msg .drate; /* default to the frequency point 0 clock */ -printf("DDRINFO: DRAM rate %dMTS\n", initial_drate); +//printf("DDRINFO: DRAM rate %dMTS\n", initial_drate); ddrphy_init_set_dfi_clk(initial_drate); /* D-aasert the presetn */ @@ -409,7 +409,7 @@ int ddr_init(struct dram_timing_info *dram_timing) tmp = reg32_read(DDRPHY_CalBusy(0)); } while ((tmp & 0x1)); -printf("DDRINFO:ddrphy calibration done\n"); +//printf("DDRINFO:ddrphy calibration done\n"); /* Step15: Set SWCTL.sw_done to 0 */ reg32_write(DDRC_SWCTL(0), 0x00000000); @@ -462,7 +462,7 @@ int ddr_init(struct dram_timing_info *dram_timing) /* enable port 0 */ reg32_write(DDRC_PCTRL_0(0), 0x00000001); -printf("DDRINFO: ddrmix config done\n"); +//printf("DDRINFO: ddrmix config done\n"); board_dram_ecc_scrub(); diff --git a/drivers/ddr/imx/phy/ddrphy_utils.c b/drivers/ddr/imx/phy/ddrphy_utils.c index 59a15764526..cddf270e594 100644 --- a/drivers/ddr/imx/phy/ddrphy_utils.c +++ b/drivers/ddr/imx/phy/ddrphy_utils.c @@ -98,7 +98,7 @@ int wait_ddrphy_training_complete(void) debug("Training PASS\n"); return 0; } else if (mail == 0xff) { -printf("Training FAILED\n"); +//printf("Training FAILED\n"); return -1; } } diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index 417e8d7eef9..7e4213858b8 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -140,9 +140,9 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) } } -printf("WDT: Started %s with%s servicing %s (%ds timeout)\n", +/*printf("WDT: Started %s with%s servicing %s (%ds timeout)\n", name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", -str, (u32)lldiv(timeout_ms, 1000)); +str, (u32)lldiv(timeout_ms, 1000));*/ } return ret; ------------------------------- h). 另外, U-Boot 默认的 countdown 功能虽然没有打印 log 了,但是还是依然存在,可以通过如下修改 u-boot-initial-env-sd 环境变量配置来忽略这个功能。设置后可以将启动时间缩短为 12s - 13s 。 ------------------------------- bootdelay=-2 // bootdelay variable description from U-Boot documentation bootdelay: After reset, U-Boot will wait this number of seconds before it executes the contents of the bootcmd variable. During this time a countdown is printed, which can be interrupted by pressing any key. Set this variable to 0 boot without delay. Be careful: depending on the contents of your bootcmd variable, this can prevent you from entering interactive commands again forever! Set this variable to -1 to disable autoboot. Set this variable to -2 to boot without delay and not check for abort. ------------------------------- 4 ). 总结 本文 基于 NXP i.MX8MP ARM 处理器平台测试了关闭 Debug Console 来增强安全和提高启动时间的流程。 参考文档 https://developer.toradex.com/software/development-resources/configuring-serial-port-debug-console-linuxu-boot/
  • 2024-12-24 09:26
    0 个评论
    为了切实满足更多客户的基础应用及项目降本需求,飞凌嵌入式现推出FETMX8MPL-C核心板。相较于先前已成功推向市场的FETMX8MP-C核心板,FETMX8MPL-C核心板在硬件配置上进行了巧妙的精简。 众所周知,并非所有应用场景都需要用到高性能的硬件配置,如音视频处理单元(VPU)、神经网络处理单元(NPU)、图像信号处理单元(ISP)以及高性能数字信号处理器(HiFi-4 DSP)等。因此,为了切实满足更多客户的基础应用及项目降本需求,FETMX8MPL-C在保留核心处理能力以及主流功能接口的基础上,精简了这些芯片单元,从而实现了成本的有效控制。 同时,FETMX8MPL-C核心板与已经上市的FETMX8MP-C核心板软硬件兼容,不仅确保了FETMX8MPL-C核心板能够轻松融入客户的现有系统中,还大大提升了产品在使用过程中的稳定性和可靠性。不过需要注意的是,FETMX8MPL-C核心板目前仅支持Linux5.4.70系统。 飞凌嵌入式FE TMX8MPL-C核心板2GB+16GB配置将于12月13日现货发售,1GB+8GB配置将于2025年1月15日发售,敬请期待。
  • 热度 3
    2024-3-8 11:37
    858 次阅读|
    1 个评论
    B y Toradex 胡珊逢 简介 Verdin iMX8M Plus 具有四个串口,其中 UART3 是用于 A53 核心上的系统如 Linux 的默认调试串口,出于设计需要可能需要将调试口换到其他串口,文章将介绍如何使用 UART1 作调试串口。 硬件介绍 Verdin iMX8M Plus 的四个串口 UART1 ~ UART4 中, UART3 为默认的 A53 调试串口, UART4 为 M7 调试串口,其余两个作为通用 UART 使用。 Verdin 系列的模块均使用 1.8V TTL 电平,在连接外部设备时请先检查电压。本次测试使用的是 Dahlia 底板,在 X20 扩展接口 Pin12 和 Pin13 分别将模块的 UART1_RXD 和 UART1_TXD 引出。四个串口的物理地址如下: UART 起始地址 结束地址 UART1 0x3086_0000 0x3086_FFFF UART2 0x3089_0000 0x3089_FFFF UART3 0x3088_0000 0x3088_FFFF UART4 0x30A6_0000 0x30A6_FFFF 软件修改 调试串口更改的软件涉及到三个部分, ATF 、 U-Boot 和 Linux 。 ATF 会和 U-Boot 等其他文件如 DDR 固件一起打包成用于 NXP i.MX 8M Plus 处理器的启动文件。这些文件的下载和编译请参考 该网页 。文章使用到的完整补丁请从 这里下载 。 ATF ATF 代码的 imx8mp_bl31_setup.c 中,把 RDC_PDAP_UART1 划分到 A53 所在的 D0 域。 --------------------------- --- a/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c +++ b/plat/imx/imx8m/imx8mp/imx8mp_bl31_setup.c @@ -53,7 +53,7 @@ static const struct imx_rdc_cfg rdc = { - MX8MP_PAD_UART3_RXD__UART3_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), - MX8MP_PAD_UART3_TXD__UART3_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX8MP_PAD_UART1_RXD__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + MX8MP_PAD_UART1_TXD__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); - init_uart_clk(2); + init_uart_clk(0); return 0; } --------------------------- 在 include/configs/verdin-imx8mp.h 将 CONFIG_MXC_UART_BASE 的地址也设置为 UART1 。同时修改 console 。 --------------------------- --- a/include/configs/verdin-imx8mp.h +++ b/include/configs/verdin-imx8mp.h "boot_script_dhcp=" BOOT_SCRIPT "\0" \ - "console=ttymxc2\0" \ + "console=ttymxc0\0" \ "fdt_board=dev\0" \ @@ -111,7 +111,7 @@ #define PHYS_SDRAM_2_SIZE (SZ_4G + SZ_1G) /* UART */ -#define CONFIG_MXC_UART_BASE UART3_BASE_ADDR +#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR /* Monitor Command Prompt */ #define CONFIG_SYS_CBSIZE SZ_2K --------------------------- Linux Linux 的 device tree 同样也需要做修改。在 freescale/imx8mp-verdin-dev.dtsi 中取消 UART1 默认配置下的 RS485 功能。 --------------------------- --- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi /* Verdin UART_1, connector X50 through RS485 transceiver */ &uart1 { + /* linux,rs485-enabled-at-boot-time; rs485-rts-active-low; rs485-rx-during-tx; + */ status = "okay"; }; --------------------------- imx8mp-verdin.dtsi 中更改 stdout-path 调试串口输出至 UART1 ,并删除 RTS 和 CTS 功能引脚。 --------------------------- --- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi @@ -8,7 +8,7 @@ / { chosen { - stdout-path = &uart3; + stdout-path = &uart1; }; aliases { @@ -891,7 +891,7 @@ &snvs_pwrkey { &uart1 { pinctrl-names = "default"; pinctrl-0 = ; - uart-has-rtscts; + /* uart-has-rtscts; */ }; /* Verdin UART_2 */ @@ -1331,8 +1331,8 @@ pinctrl_sai3: sai3grp { pinctrl_uart1: uart1grp { fsl,pins = - , /* SODIMM 135 */ - , /* SODIMM 133 */ + /* , SODIMM 135 */ + /* , SODIMM 133 */ --------------------------- 修改完毕上述文件后重新编译 flash.bin ( imx-boot )和 device tree 文件,并将其放入支持 Toradex Easy Installer 烧录的镜像文件中。同时也需要修改镜像文件中的 u-boot-initial-env-sd ,将 console 改为 console=ttymxc0 。该文件会在烧录系统时配置 U-Boot 环境变量。安装完镜像后,在 UART1 即可看到启动日志。 总结 通过上述几个文件的修改,可以切换 A53 调试串口。对于 Linux 系统通常建议保留一个调试串口,这将有利于调试和后期其他问题排查。
  • 热度 5
    2024-1-19 14:39
    1946 次阅读|
    0 个评论
    B y Toradex 胡珊逢 简介 在嵌入式Linux设备上常使用Qt作为开发图形界面应用的框架,随着web和移动端图形框架技术快速发展,嵌入式Linux也可以从这些技术中受益。由Google开发的Flutter最初用于Android和iOS应用开发,后期加入web、Windwos桌面和Linux桌面的支持。配合适当的渲染引擎,Flutter也可以运行在嵌入式Linux设备上。文章将介绍如何在使用Linux BSP的Verdin iMX8M Plus上运行Flutter应用。 硬件介绍 本次演示使用基于NXP iMX8M Plus SoC 的计算机模块 Verdin iMX8M Plus 。底板为 Dahlia ,该底板可以直接使用Verdin iMX8M Plus 的 HDMI 显示输出。屏幕则使用支持电容屏的 HDMI 显示器,用于测试 Flutter 应用的交互性。 Flutter介绍 Flutter使用Dart语言开发,可以跨平台运行,支持AOT(Ahead of time)预编译,使应用在设备上更高效地运行。对于Flutter应用,用户通常只需要开发apps代码,Framework、Engine和Embedder都油Flutter SDK提供。使用不同的embedder,Flutter app可以运行在不同的平台上。目前官方支持embedder包括Android,iOS,MacOS、Windwos桌面、Linux桌面、Web浏览器 Linux桌面需要依赖GTK和X11,现在的嵌入式Linux系统已经普遍使用Wayland,例如NXP的iMX处理器在新的BSP已经不再支持X11。对于嵌入式Linux系统,可以使用下面两个非官方的embedder。 Flutter-elinux ,这是由Sony 维护的项目,支持 Arm64 和 X64 处理器。可以使用 Wayland 或者 X11 后台,或者直接基于 DRM。 Flutter-pi 是针对树莓派开发和优化的embbeder,其不依赖于 X11 和 GTK 的任何组件。支持 KMS 和 DRI,3D 硬件加速。可以运行在 ARMv7、ARMv8、x86 处理器上。Flutter-pi 拥有更活跃的社区和开发者。结合 flutterpi_tool 工具可以非常容易地开发flutter 应用。 Verdin iMX8M Plus 的 Linux BSP 支持 KMS,其 CPU 也是 Armv8 架构。因此,我们本次选用 Flutter-pi 作为 embedder。关于 Flutter-elinux 在 Toradex 模块上的应用,可以参考 该文章 。 添加meta-flutter meta-flutter 提供了编译flutter-pi 以及 flutter demo 的文件。meta-flutter 依赖 meta-clang layer。Toradex Linux BSP v6 基于 Yocto Project 的 kirkstone 分支。首先,参考 这里 创建Yocto Project 编译环境。然后进入 layers 文件夹,下载 meta-flutter 和 meta-clang。 $ git clone --branch kirkstone https://github.com/meta-flutter/meta-flutter.git $ git clone --branch kirkstone https://github.com/kraj/meta-clang.git 然后在build/conf/bblayers.conf 文件的 BBLAYERS 中添加 meta-flutter 和 meta-clang 的路径。 BBLAYERS ?= " \ ${BBLAYERS_NXP} \ ... ${TOPDIR}/../layers/meta-clang \ ${TOPDIR}/../layerss/meta-flutter \ " 在build/conf/local.conf 文件的结尾添加以下内容。 DEFAULT_TIMEZONE = "Asia/Shanghai" ENABLE_BINARY_LOCALE_GENERATION = "1" IMAGE_LINGUAS:append = " en-us en-gb es-us zh-cn" GLIBC_GENERATE_LOCALES:append = " en_US.UTF-8 es_US.UTF-8 en_GB.UTF-8 zh_CN.UTF-8" IMAGE_INSTALL:append = " tzdata-core tzdata-asia" DISTRO_FEATURES:append = " opengl wayland pam" PACKAGECONFIG:append:pn-weston = " remoting" PACKAGECONFIG:append:pn-flutter-engine = " profile debug" IMAGE_INSTALL:append = " flutter-auto packagegroup-flutter-test-apps \ flutter-pi flutter-gallery" IMAGE_INSTALL:remove = " packagegroup-tdx-qt5" 删除meta-flutter/recipes-platform/packagegroups/ packagegroup-flutter-test-apps.bb 中的 flutter-test-texture-egl。最后编译 tdx-reference-multimedia-image 镜像文件。 $ bitbake tdx-reference-multimedia-image 测试Flutter 应用 禁用自启动的weston 服务。 root@verdin-imx8mp:~# systemctl stop weston.service root@verdin-imx8mp:~# systemctl disable weston.service 镜像中的/usr/share/flutter/gallery/3.16.5/release 中已经包含一个 flutter gallery 应用,现在可以使用 flutter-pi 直接运行。 root@verdin-imx8mp:# cd /usr/share/flutter/gallery/3.16.5/release root@verdin-imx8mp:# flutter-pi --release ./ 在HDMI 显示器上可以看到 gallery 应用的界面。 安装Flutter SDK 和 flutterpi_tool 在Linux 电脑(例如 Ubuntu 23.04)上,首先安装 Flutter SDK。由于 Flutter 和 flutter-pi 两个项目更新都比较活跃,在安装前需求确认 Flutter 版本。在 这里 查看flutter-pi 目前使用的 Flutter 版本。例如撰写文章时其为 3.16.7。在 Flutter SDK 手动安装页面 选择对应的版本进行安装,如flutter_linux_3.16.7-stable.tar.xz。 $ sudo apt-get install clang cmake git ninja-build \ pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev $ cd FLUTTER_SDK_INSTALL_PATH $ tar vxf flutter_linux_3.16.7-stable.tar.xz $ export PATH="$PATH:`pwd`/flutter/bin" $ flutter doctor -v 上面的flutter 环境诊断工具如果提示缺少 chrome 浏览器,可以安装后再运行。 $ sudo dpkg -i google-chrome-stable_current_amd64.deb $ flutter doctor -v 检查flutter 和 dart 命令是否都来自同一个的 SDK 安装目录。 $ which flutter dart /home/ben/flutter-sdk/flutter/bin/flutter /home/ben/flutter-sdk/flutter/bin/dart 安装完Flutter SDK 后使用下面命令安装 flutterpi_tool $ flutter pub global activate flutterpi_tool $ export PATH="$PATH":"$HOME/.pub-cache/bin" 使用下面命令测试 $ flutterpi_tool --help 如果已经安装好Flutter SDK 和 flutterpi_tool,需要编译其他 flutter 应用时,只需要进入之前 Flutter SDK 的安装目录后执行下面命令,重新配置编译环境即可。 $ cd FLUTTER_SDK_INSTALL_PATH $ export PATH="$PATH:`pwd`/flutter/bin" $ export PATH="$PATH":"$HOME/.pub-cache/bin" 使用flutterpi_tool 编译应用 借助flutterpi_tool 可以非常简单的编译 flutter 应用,例如针对 64 位 Arm CPU 的编译命令 flutterpi_tool build --arch=arm64 --cpu=pi4 --release ,参数说明如下: 参数 说明 Runtime mode --debug Build for debug mode. --profile Build for profile mode. --release Build for release mode. --debug-unoptimized Build for debug mode and use unoptimized engine. (For stepping throughengine code) Target,--arch= arm Build for 32-bit ARM. (armv7-linux-gnueabihf) arm64 Build for 64-bit ARM. (aarch64-linux-gnu) x64 Build for x86-64. (x86_64-linux-gnu) Target,--cpu= generic (default) Don’t use a tuned engine. The generic engine will work on all CPUs of the specified architecture. pi3 Use a Raspberry Pi 3 tuned engine. Compatible with arm and arm64. (-mcpu=cortex-a53+nocrypto -mtune=cortex-a53) pi4 Use a Raspberry Pi 4 tuned engine. Compatible with arm and arm64. (-mcpu=cortex-a72+nocrypto -mtune=cortex-a72) 下面是在Linux电脑上编译flutter gallery应用。由于Verdin iMX8M Plus是基于arm64的Cortex-A53 CPU,因此选择--arch=arm64和--cpu=pi3两个参数。 $ git clone https://github.com/flutter/gallery.git flutter_gallery $ cd flutter_gallery/ $ git checkout 6a8d738c94d0710e229d726729c09fdb5ccaf7ed $ flutter pub get $ flutterpi_tool build --arch=arm64 --cpu=pi3 --release 编译结束后,在build/flutter_assets 目录下可以看到如下文件。 build/flutter_assets/ ├── app.so ├── AssetManifest.bin ├── AssetManifest.json ├── FontManifest.json ├── fonts ├── icudtl.dat ├── libflutter_engine.so ├── NOTICES.Z ├── packages └── shaders flutteri_tool 目前使用新的编译方法生成的文件结构尚不能直接使用 flutter_pi 在设备上直接运行,需要重新调整文件位置,参考 Verdin iMX8M Plus 上的 /usr/share/flutter/gallery/3.16.5/release 的内容。 release/ ├── data │ ├── flutter_assets │ └── icudtl.dat └── lib ├── libapp.so └── libflutter_engine.so 在flutter_gallery/build/flutter_assets/ 目录创建 data 和 lib 两个文件夹,app.so 重命名为 libapp.so 后和 libflutter_engine.so 一起移动到 lib 目录。icudtl.dat 移动到 data 目录下。在 data 目录下创建 flutter_assets 文件夹后,将 build/flutter_assets/ 中剩余的 AssetManifest.bin,AssetManifest.json,FontManifest.json,fonts,NOTICES.Z,packages 和 shaders 均移动到 data/flutter_assets 中。完场后将 data 和 lib 两个目录复制到 Verdin iMX8M Plus 上的 /home/root/flutter_gallery 目录中,例如使用 scp 命令。 $ scp -r build/flutter_assets/ root@imx8mp_ip:/home/root/flutter_gallery 复制好文件后可以在Verdin iMX8M Plus 上的 /home/root/flutter_gallery 看到以下内容。 root@verdin-imx8mp-07320826:~/flutter_gallery# ls * data: flutter_assets icudtl.dat lib: libapp.so libflutter_engine.so 运行下面命令即可启动在电脑上编译的flutter 应用。 root@verdin-imx8mp:~# flutter-pi --release /home/root/flutter_gallery/ 总结 使用Flutter 可以开发跨平台应用,并获得流畅的本地运行体验,在移动端和 Web 端都有广泛的应用。但是针对嵌入式 Linux 的 embedder 目前是第三方维护的,所以在实际应用时需要做详尽的测试。 ​
  • 热度 4
    2023-9-14 09:09
    433 次阅读|
    0 个评论
    飞凌嵌入式OKMX8MP-C开发板 有两路原生CAN总线,但用户在开发产品时可能需要用到更多的CAN,这该如何解决呢?今天小编将为大家介绍一种SPI转CAN的方法,供各位工程师小伙伴参考。 说明 OKMX8MP-C核心板有两路原生的SPI总线,目前是将SPI1的引脚用作了LED和UART3的功能,SPI2做成了正常的SPI2接口。此处以SPI2转CAN为例,移植SPI转CAN芯片; SPI转CAN芯片型号为:MCP2518,这款芯片可转出CAN-FD,若只需要CAN功能,可参照该方式移植MCP2515或其他芯片; 本次移植的MCP2518芯片驱动来源是i.MX8MQ的源码(处理器中默认移植MCP2518芯片)。 0 1 移植MC2518芯片驱动 在 OK8MP-linux-kernel/drivers/net/can/spi/ 路径下创建一个文件夹—— mcp25xxfd ,将相关文件(包含.c文件、.h文件、Makefile、Kconfig等)放置到此文件夹中。 0 2 补全对can_rx_offload_add_manual函数的定义 vi OK8MQ-linux-kernel/include/linux/can/rx-offload.h 添加: int can_rx_offload_add_manual ( struct net_device*dev, struct can_rx_offload *offload, unsigned int weight ) vi OK8MQ-linux-kernel/drivers/net/can/rx-offload.c 添加: int can_rx_offload_add_manual ( struct net_device*dev, struct can_rx_offload *offload, unsigned int weight ) { if mailbox_read) return -EINVAL; return can_rx_offload_init_queue(dev, offload, weight); } EXPORT_SYMBOL_GPL(can_rx_offload_add_manual); 0 3 修改上一级目录spi/下的Makefile和Kconfig vi OK8MP-linux-kernel/drivers/net/can/spi/Makefile 添加: obj-y += mcp25xxfd/ vi OK8MP-linux-kernel/drivers/net/can/spi/Kconfig 添加: source "drivers/net/can/spi/mcp25xxfd/Kconfig" 0 4 修改驱动配置文件,将MCP2518编译进内核 vi OK8MP-linux-kernel/arch/arm64/configs/OK8MP-C_defconfig 找到: CONFIG_CAN_MCP251X=y 改为: # CONFIG_CAN_MCP251X is not set 添加: CONFIG_CAN_MCP25XXFD=y 0 5 在设备树中配置时钟 vi OK8MP-linux-kernel/arch/arm64/boot/dts/freescale/OK8MP-C.dts 添加: clocks{ mcp2518fd_clock : mcp2518fd_clock{ compatible = "fixed-clock"; #clock-cells = ; clock-frequency = ; }; }; 0 6 找一个引脚用作芯片的中断引脚 此处是将 GPIO4_IO21用作了中断引脚。 vi OK8MP-linux-kernel/arch/arm64/boot/dts/freescale/OK8MP-C.dts 添加: pinctrl_ecspi2_can : ecspi2can{ fsl,pins = < MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x40000 ; }; 0 7 在设备树的ecspi2节点中进行修改 vi OK8MP-linux-kernel/arch/arm64/boot/dts/freescale/OK8MP-C.dts 从: &ecspi2{ #address-cells= < 1 ; #size-cells= < 0 ; fsl,spi-num-chipselects= < 1 ; pinctrl-names="default"; pinctrl-0= < &pinctrl_ecspi2 & pinctrl_ecspi2_cs ; cs-gpios= < &gpio5 13 GPIO_ACTIVE_LOW ; status="okay"; spidev1:spi@0{ reg= < 0 ; compatible="rohm,dh2228fv"; spi-max-frequency= < 500000 ; }; }; 改为: &ecspi2{ #address-cells= < 1 ; #size-cells= < 0 ; fsl,spi-num-chipselects= < 1 ; pinctrl-names="default"; pinctrl-0= < &pinctrl_ecspi2 & pinctrl_ecspi2_cs & pinctrl_ecspi2_can ; cs-gpios= < &gpio5 13 GPIO_ACTIVE_LOW ; status="okay"; mcp1:mcp2518fd@0{ compatible="microchip,mcp2518fd"; reg= < 0 ; spi-max-frequency= < 20000000 ; clocks= < &mcp2518fd_clock2 ; interrupts-extended= < &gpio4 21 IRQ_TYPE_LEVEL_LOW ; }; }; 完成上述修改后即可进行编译,并用新生成的镜像烧写 OKMX8MP-C 开发板。 0 8 开发板验证 将MCP2518芯片接到SPI2的接口上,启动OKMX8MP-C开发板,启动后使用ifconfig -a命令查看,即可看到多出了1个CAN节点。 节点生成后,即可按照用户使用手册 【 4.18 FlexCAN测试】 章节进行测试,验证功能是否正常。 用户使用手册下载链接: https://pan.baidu.com/s/1TY4R5BrAnjAuTTJj9fNGWw 提取码: 7qc8