tag 标签: linux

相关帖子
相关博文
  • 2025-6-17 09:29
    0 个评论
    在工业自动化领域,控制系统一直面临着“性能与成本难以兼得”的困境。传统方案中,高性能多核处理器成本居高不下,而低端MCU又难以满足实时性与扩展性需求。瑞芯微 RK3506J凭借多核异构架构设计与国产化供应链整合,以轻量级硬件资源实现工业级性能输出,重新定义了控制芯片的性价比边界,为工业控制芯片领域带来了全新的解决方案与发展方向。 一、轻量级设计的性能突围 RK3506J采用3×Cortex - A7多核架构,实现了资源的精准分配与效能最大化。3×A7核主频1.5GHz,运行Linux系统(自主适配QT),能够高效处理人机交互、协议栈等非实时任务,确保了任务的高效执行与响应速度。 RK3506J依托AMP架构,各核心可独立运行不同操作系统或任务,实现资源合理划分与精准分配。在复杂外设协同工作场景下,AMP 架构能将两套系统合二为一,一套板卡即可同时独立运行 Linux 系统和实时系统。 飞凌嵌入式的FET3506J-S核心板基于此架构提供了AP+AP模式实时方案,在此模式下,可以选择任意CPU作为实时核,如CPU0和CPU1作为实时核,CPU2运行Linux系统。Cortex-A7的1.5GHz高主频及硬浮点单元加速特性,使其在处理高精度采样、实时计算、故障检测等严苛实时任务时,能降低任务响应延迟,提升系统实时处理效能,确保系统快速响应与稳定运行,为工业环境中复杂任务的高效处理提供了有力支持。 二、硬件精简:接口复用与资源集约化 RK3506J通过高密度接口复用与灵活矩阵配置,大幅降低了硬件开发复杂度与外围器件成本。丰富的通信接口 ,具备双百兆以太网(支持IEEE1588协议)、2×CAN FD(5Mbps)、6×UART、12×PWM,满足了工业场景中多样化的通信需求,实现了设备间的高效互联与数据传输。 高性能DSMC接口,支持FPGA高速协同,支持主/从模式,为复杂工业系统的高速数据交互与协同工作提供了强大的硬件支持。 灵活的FlexBUS接口,可扩展高速ADC/DAC,能够根据实际应用场景灵活扩展功能,增强了芯片的通用性与适应性。 IOMUX矩阵技术,98个功能信号可自由映射至32个物理引脚,支持UART TX/RX 极性反转、PWM信号重定向,简化了PCB布线层数,降低了硬件设计成本与开发难度,提高了设计的灵活性与效率。 三、场景适配:轻量化内核的高效落地 在典型工业场景下,RK3506通过定制化系统裁剪与轻量级框架适配,实现了“小内核、高产出”的显著效果。它凭借卓越的兼容性与灵活的架构,支持Linux 6.1(自主适配 QT)和Linux RT操作系统,同时可搭载LVGL9.2图形界面库,支持AMP 架构,能够充分满足多样化应用场景的需求。 基于Buildroot定制的Linux系统,融合UBoot加速技术,实现3秒开机,大幅缩短启动时间。同时,采用LVGL图形框架,支持1280×800分辨率HMI界面渲染,为工业设备提供清晰流畅的人机交互界面,提升操作便捷性与用户体验。 四、成本重构:国产化供应链的价值释放 FET3506J-S核心板基于Rockchip RK3506J处理器开发设计。通过 100% 国产化元器件选型与长周期供货承诺,满足电力、交通、工控等行业对国产化的要求。同时进行了充分的可靠性测试,确保在工业环境的可靠运行。 核心板物料100%国产化,含税价格仅88元,为设备厂商提供了更具性价比的国产替代方案,降低了对进口芯片的依赖,保障了供应链的安全与稳定。采用飞凌嵌入式基于瑞芯微RK3506J处理器设计核心板,可缩短2~3个月开发周期,降低开发门槛与研发成本,提高设备厂商的产品开发效率与市场竞争力。 结语: RK3506J以“轻量级架构+硬核性能”的组合,证明了工业芯片无需依赖“堆料”也能实现高效能。其通过多核异构资源分配、接口复用设计与国产化成本控制,不仅为设备厂商提供了高性价比选择,更推动了工业控制芯片从“性能竞赛”向“精准适配” 的范式转变。
  • 热度 1
    2025-6-16 17:21
    2179 次阅读|
    0 个评论
    概要 尽管大多数嵌入式软件应用针对单一微处理器或微控制器开发,但在某些特定场景下需要采用分布式架构。以汽车行业为例,不同子系统可能作为独立应用程序部署在分离的处理器上,例如负责发动机控制系统的嵌入式软件与防抱死制动系统应用就分别运行在不同的微控制器上。 医疗器械行业是嵌入式软件分布于多个微处理器的另一典型案例。例如,用户界面由一个微处理器实现,而负责患者交互的控制系统则位于另一个微控制器上。 可以看出,职责是根据功能划分的,而处理器则根据职责进行选择。例如,用户界面通常在基于 Linux 的系统上实现,这类系统专为类似 ARM Cortex-A 内核的处理器设计;而关键的嵌入式软件应用则采用实时操作系统(RTOS),这种系统最适合类似 ARM Cortex-R 或 Cortex-M 内核的处理器。 然而,若采用多处理器架构,处理器间的通信便至关重要。例如汽车行业就通过 CAN 总线实现这一功能。在医疗设备领域,各处理器可采用 UART、SPI 或 I2C 等通信协议进行交互,如下图所示: 然而,多个处理器分布在不同的芯片上会增加底层硬件、软件和固件的复杂性。这进而可能导致额外的开发和调试工作,从而影响产品的时间线和成本。 为了应对这种额外的复杂性,我们可以将多个处理器集成到同一块芯片上,如下图所示: 在上图中,ARM Cortex-A 和 ARM Cortex-M 内核被集成在同一块芯片上,称为系统级芯片(SoC)。SoC 将 CPU 内核与其他必要的控制器相结合,形成一个功能全面且强大的处理器。如图中显示,嵌入式软件的功能安全(FuSa)部分通过 Zephyr Project 实时操作系统在 ARM Cortex-M 内核上实现,而图形用户界面(GUI)则在 ARM Cortex-A 内核的 Linux 系统中运行。 该设计大幅缩短了硬件开发与调试时间。无需再管理多个独立处理器及电气和机械硬件互联,问题简化为围绕单个处理器的硬件设计。挑战也就主要转移到固件和软件层面,因为每个内核的嵌入式软件需要与其他内核的嵌入式软件建立通信机制。 在这篇博客文章中,我们将学习如何从运行于 ARM Cortex-A 核心的 Linux 内核加载运行于 ARM Cortex-M 核心上的固件。我们将以 Toradex Verdin iMX95 模块为例演示具体实现方法。 OpenAMP项目 Open Asymmetric Multi-Processing(OpenAMP)项目的设立旨在实现同一片上系统内不同核心之间的高效通信。该项目基于德州仪器早期将 Remoteproc 和 RPMsg 纳入 Linux 内核的工作成果发展而来:Remoteproc 使 Linux 内核能够管理远端处理器(remote processor)上的嵌入式软件生命周期,而 RPMsg 则实现了 Linux 内核与远端处理器固件间的通信。OpenAMP 项目将德州仪器的专有实现方法扩展为适用于各类系统的通用框架,标准化了 Linux 内核与基于实时操作系统(RTOS)的嵌入式应用间通信协议,并为希望利用其功能特性(如 RPMsg)的 RTOS 及裸机嵌入式应用提供了参考实现方案。 如前所述,Remoteproc 和 RPMsg 是 OpenAMP 项目的两大核心功能,它们使我们能够管理运行在同一 SoC 不同内核上的嵌入式软件。Remoteproc 负责将固件加载到远程处理器上,并启动和停止远程处理器的执行。在 Linux 系统中,Remoteproc 通常用于管理运行在 Cortex-M 等类似内核上的嵌入式软件生命周期。而 RPMsg 则负责支持运行在 Cortex-M 内核的嵌入式软件与运行 Cortex-A 内核的 Linux 系统之间的消息交换。 Toradex Verdin iMX95 Toradex Verdin iMX95 是一款基于 NXP iMX95 SoC 的高性能模块(SoM)。如下图所示,iMX95 SoC 包含三种不同类型的 ARM 核心架构: ARM Cortex-A55 运行 Linux 操作系统,ARM Cortex-M7 负责执行实时固件,而 ARM Cortex-M33 则管理 Cortex-A55 和 Cortex-M7 的运行。 Zephyr Project RTOS 尽管“实时操作系统”是 Zephyr 项目 RTOS 的官方名称,但 “Zephyr” 远不止是一个 RTOS。它是一个完整的生态系统。虽然它确实包含了 RTOS 的典型功能和数据结构,如任务、信号量、互斥锁和消息队列,但它还拥有负责嵌入式系统其他重要功能的软件栈。例如,它包括: 用于控制和操作厂商特定硬件的驱动程序 实现完整通信协议栈的软件,例如蓝牙低功耗(BLE)和WiFi 实现整个子系统的模块,例如文件系统和引导加载程序 Zephyr 还支持来自众多厂商的 750 多款开发板,包括 Toradex Verdin iMX95。如果我们下载 Zephyr 代码库,可以看到在 boards/nxp/imx95_evk 目录下提供了对 iMX95 EVK 的支持,如下图所示: Zephyr 借鉴了 Linux 内核的 Kconfig 和 Devicetree 功能,我们可以在上图中看到这一点。上图所示的 iMX95 EVK “device driver” 包含: “board.c”, 负责初始板卡启动的C源代码 “imx95_evk_mimx9596_m7.dts”, 用于告知 Zephyr 该板卡上存在哪些外设的 Devicetree 文件 “Kconfig.imx95_evk”, 需要启用支持该板卡关键功能的 Kconfig 的选项集合 例如,如果我们打开“Kconfig.imx95_evk”文件(如下图所示),可以看到它启用了 iMX95 SoC 的 Kconfig 选项。该 Kconfg 选项随后会启用 SoC 所需的其他功能: 例如,Verdin iMX95的“device driver”位于 soc/nxp/imx/imx9/imx95 目录下,如下图所示: 同样的,“soc.c” 是负责初始 SoC 启动的 C 源代码,通过分析设备树中的相应节点,我们可以发现该 SoC 的 Kconfig 文件定义了 Flash 大小。 整合所有步骤 让我们演示如何为 iMX95 编译 Zephyr 应用程序,并从同一开发板上运行的 Cortex-A 内核加载 Zephyr 应用程序到 Cortex-M 内核。首先,我们可以按照 Zephyr入门指南( https://docs.zephyrproject.org/latest/develop/getting_started/index.html )中的步骤确保环境配置正确。 然后执行以下命令使用 West 工具获取 Zephyr 源代码: $ west init -m https://github.com/mabembedded/zephyr.git $ west update 之后,我们可以执行以下命令为 Verdin iMX95 编译一个简单的“Hello World”应用程序: $ west build -p -b imx95_evk/mimx9596/m7 samples/hello_world 然后,我们可以通过执行以下命令(确保将下方列出的 IP 地址替换为我们开发板的实际地址),将编译好的 ELF 格式二进制文件传输至运行在 iMX95 Cortex-A 内核上的 Linux 系统: $ scp build/zephyr/zephyr.elf root@10.10.2.22:~/ 随后,如果我们登录到 iMX95 设备,可以运行以下命令来指示 Linux 将 Zephyr ELF 二进制文件加载至 Verdin iMX95 的 Cortex-M7 核心上: root@imx95-19x19-verdin:~# cd /sys/devices/platform/imx95-cm7/remoteproc/remoteproc1/ root@imx95-19x19-verdin:~# echo ~/zephyr.elf firmware 最后,我们可以在 iMX95 Linux 控制台中输入以下命令来启动 Cortex-M7 核心: root@imx95-19x19-verdin:~# echo start state 我们可以在 iMX95 的 Cortex-M7 控制台上看到以下内容: 上述示例展示了 Linux 内核中 OpenAMP 项目的 Remoteproc 功能。 我们还可以通过如下所示的 openamp_rsc_table 示例应用程序,了解 Zephyr 中的 RPMsg 功能: 如上图所示,“ imx95_evk_mimx9596_m7.conf ” 包含了该应用启用的 Kconfig 选项。下图可见,此文件已启用相关的 OpenAmp 和 Mbox Kconfig 配置项: 该目录还包含一个 Devicetree “overlay”,用于为此特定应用定制开发板的 Devicetree。如下图所示,此覆盖层定义了 RPMsg 应用所需的功能,并引用了特定的硬件组件: 这些特性包括: 各个核心间用于交换数据的共享内存 Linux内核通过资源表来识别远程处理器及固件支持的功能 双核通信使用的邮箱机制 接下来演示如何编译并运行 RPMsg Zephyr 应用程序。首先执行以下命令进行编译: $ west build -p -b imx95_evk/mimx9596/m7 samples/subsys/ipc/openamp_rsc_table 随后,我们可以按照之前概述的步骤将生成的 ELF 二进制文件从 Cortex-A55 上的 Linux 系统传输并加载到 Cortex-M7 中。在从 Linux 端启动 Cortex-M7 后,我们将在 Cortex-M7 的控制台上看到以下内容,这展示了从 Linux 端接收到的消息: 同样,如果观察 Cortex-A55 端的 Linux 内核日志,我们也能看到它通过 RPMsg 接收到了来自 Cortex-M7 上 Zephyr 应用程序的消息,如下所示: 总结 在本篇博客中,我们了解了利用 OpenAMP 项目特性简化嵌入式系统硬件设计的优势。探讨了 Toradex Verdin iMX95 开发板如何通过 SoC 上不同的 ARM 内核实现创新应用场景。实践演示了使用 Zephyr 实时操作系统快速构建 "Hello World" 示例程序,并从运行于 Cortex-A55 的 Linux 系统加载至 Verdin iMX95 的Cortex-M7 核心的全过程。最后,我们还完成了基于 RPMsg 协议的 Zephyr 应用程序编译、从 Linux 环境加载以及验证 Zephyr 与 Linux 之间消息交互的实验。
  • 热度 2
    2025-6-9 14:59
    166 次阅读|
    0 个评论
    B y Toradex 秦海 1). 简介 在前述文章中,我们介绍了如何基于 Weston Composito 实现多屏幕分别显示不同的应用,而进一步延申出的一个应用场景,就是多屏幕之一的 HDMI 屏幕需要进行热插拔,而在热插拔的同时其对应的显示应用也同时启动或者停止,以便不影响其他屏幕的显示。本文就基于前述文章同样的 NXP i.MX8MP 平台来测试如何实现这个功能场景。 本文所演示的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台 。 2. 准备 a). Verdin i.MX8MP ARM 核心版配合 Dahlia 载板, 并连接调试串口用于测试 。 b). Dahlia 载板分别由 DSI-HDMI 转接卡和 native HDMI 两个接口连接两台 HDMI 显示器以便于进行多屏显示测试。 3). 部署流程 a). 为了实现对于 native HDMI 接口连接的 HDMI-2 显示器热插拔动作的响应,需要通过 udev rule 来捕获相应触发模块并进行动作。 ./ 首先通过执行如下命令,然后操作硬件热插拔,获取被触发的 udev “ KERNEL ” 组件是 “ card1 ” , ” SUBSYSTEM ” 是 “ drm ” , ” Action ” 是 “ change ” --------------------------------------- root@verdin-imx8mp-06849028:~# udevadm monitor monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent KERNEL change /devices/platform/display-subsystem/drm/card1 (drm) UDEV change /devices/platform/display-subsystem/drm/card1 (drm) KERNEL change /devices/platform/display-subsystem/drm/card1 (drm) UDEV change /devices/platform/display-subsystem/drm/card1 (drm) --------------------------------------- ./ 基于上述信息生成如下 udev rules 文件 - /etc/udev/rules.d/99-hdmi-hotplug.rules ,这样无论当 HDMI 显示器连接还是断开的时候都会触发这个规则,并执行 hdmi- hotplug .sh 脚本代码。 --------------------------------------- # When HDMI is attached or unattached ACTION=="change", KERNEL=="card1", SUBSYSTEM=="drm", RUN+="/home/root/hdmi- hotplug .sh" --------------------------------------- b). hdmi- hotplug .sh 脚本代码实现 ./ native HDMI 对应系统 “/sys/class/drm/card1-HDMI-A-2” 设备,设备节点中有 “ status ” 项目对应当前 HDMI hotplug 状态 --------------------------------------- ### HDMI attached ### root@verdin-imx8mp-06849028:~# cat /sys/class/drm/card1-HDMI-A-2/status c onnected ### HDMI unattached ### root@verdin-imx8mp-06849028:~# cat /sys/class/drm/card1-HDMI-A-2/status disconnected --------------------------------------- ./ 基于上述判断生成 hdmi-hotplug.sh 脚本来启动或者停止 smarthome Qt 应用(可以见章节 1 提到的前述双屏显示文章)。在这里需要通过 systemd service 来启动应用,不能直接执行 smarthome 应用,否则在 hdmi-hotplug.sh 退出后应用也会同时退出。 --------------------------------------- #!/bin/bash tty=/dev/ttymxc2 hdmistatus=$(cat /sys/class/drm/card1-HDMI-A-2/status) if ; then echo "HDMI connected..." $tty systemctl start smarthome-app-launch else echo "HDMI disconnected..." $tty systemctl stop smarthome-app-launch fi --------------------------------------- ./ 赋予 hdmi-hotplug.sh 脚本可执行属性 --------------------------------------- root@verdin-imx8mp-06849028:~# chmod +x hdmi-hotplug.sh --------------------------------------- c). 部署 smarthome-app-launch service 文件 ./ smarthome-app-launch service 文件 - /lib/systemd/system/smarthome-app-launch.service --------------------------------------- Description=Start a wayland application After=weston.service Requires=weston.service Type=simple User=root PAMName=login Environment=WAYLAND_DISPLAY=/run/wayland-0 Environment=QT_QPA_PLATFORM=wayland-egl WorkingDirectory=/usr/share/qtsmarthome-1.0/ ExecStart=/usr/share/qtsmarthome-1.0/smarthome Restart=on-failure RestartSec=1 WantedBy=graphical.target --------------------------------------- ./ 更新 systemd service 文件 --------------------------------------- root@verdin-imx8mp-06849028:~# systemctl daemon-reload --------------------------------------- d). 参考章节 1 前述双屏显示文章同样内容,修改 /etc/xdg/weston/weston.ini 文件。 --------------------------------------- --- a/etc/xdg/weston/weston.ini +++ b/etc/xdg/weston/weston.ini @@ -4,6 +4,7 @@ idle-time=0 xwayland=true #enable-overlay-view=1 +shell=kiosk-shell.so @@ -12,13 +13,16 @@ touchscreen_calibrator=true calibration_helper=/usr/bin/toradex-save-touchscreen-calibration -# -#name=HDMI-A-1 -#mode=1920x1080@60 + +name=HDMI-A-1 +app-ids=Qt5_CinematicExperience +mode=1920x1080@60 #transform=rotate-90 -# -#name=HDMI-A-2 + +name=HDMI-A-2 +app-ids=smarthome +mode=1920x1080 #mode=off # WIDTHxHEIGHT Resolution size width and height in pixels # off Disables the output --------------------------------------- e). 另外, wayland-app-launch.service 是 Toradex Yocto Multimedia BSP 默认使能用于 Qt5_CinematicExperience 应用启动的 systemd service 文件,如果之前关闭了,可以通过下面命令使能。 --------------------------------------- root@verdin-imx8mp-06849028:~# systemctl enable wayland-app-launch --------------------------------------- f). 最后所有上述修改完成后重新启动。 4 ). 测试 a). 重新启动后,当两个 HDMI 显示器都连接,可以通过屏幕观察以及如下进程查询确认两个 Qt 应用都分别显示在相应的显示器上面。 ------------------------------- root@verdin-imx8mp-06849028:~# ps -aux |grep Qt5_CinematicExperience root 522 38.3 3.8 1085948 153664 ? Ssl 06:20 0:41 /usr/share/cinematicexperienc e-1.0/Qt5_CinematicExperience --fullscreen root 569 0.0 0.0 2944 1280 ttymxc2 S+ 06:22 0:00 grep Qt5_CinematicExperience root@verdin-imx8mp-06849028:~# ps -aux |grep smarthome root 520 31.8 1.9 1007248 77160 ? Ssl 06:20 0:37 /usr/share/qtsmarthome-1.0/sm arthome root 571 0.0 0.0 2944 1152 ttymxc2 S+ 06:22 0:00 grep smarthome ------------------------------- b ). 当将 native HDMI 连接的 HDMI-2 屏幕断开后,对应的 smarthome 应用也同时退出 ------------------------------- root@verdin-imx8mp-06849028:~# HDMI disconnected... root@verdin-imx8mp-06849028:~# ps -aux |grep smarthome root 645 0.0 0.0 2944 1152 ttymxc2 S+ 06:28 0:00 grep smarthome ------------------------------- c ). 当 native HDMI 连接的 HDMI-2 屏幕重新连接后,对应的 smarthome 应用也同时启动 ------------------------------- root@verdin-imx8mp-06849028:~# HDMI connected... root@verdin-imx8mp-06849028:~# ps -aux |grep smarthome root 650 72.3 1.8 1007248 74052 ? Ssl 06:28 0:04 /usr/share/qtsmarthome-1.0/sm arthome root 662 0.0 0.0 2944 1280 ttymxc2 S+ 06:28 0:00 grep smarthome ------------------------------- 5 ). 总结 本文 基于 NXP i.MX8MP 处理器平台测试了 Yocto Linux 下 HDMI 显示器热插拔情况下对应显示应用同步启动和停止。 参考文档 https://blog.csdn.net/qq_17292655/article/details/134670878
  • 2025-6-6 15:33
    0 个评论
    AM62x处理器作为TI新一代高性能、低功耗处理器,在工业控制、人机交互、边缘计算等领域有着广泛应用。飞凌嵌入式基于AM62x处理器设计开发的OK62xx-C开发板为开发者提供了丰富的硬件接口资源。本文将针对开发过程中可能遇到的各类接口问题,提供系统化的排查思路和解决方案,帮助开发者快速定位并解决问题。 一、通用排查思路 在硬件调试过程中,系统化的排查方法能够显著提高效率。以下是针对飞凌嵌入式AM62x开发板的通用排查流程: 1.芯片一致性验证: 首先确保所用功能芯片与参考设计原理图完全一致。若芯片型号不同,可能需要进行驱动移植工作,包括修改设备树配置和驱动程序。 2.基础信号检查: 对于功能验证失败的模块,应依次检查: 电源电压是否在允许范围内; 复位信号时序是否符合要求; 时钟信号频率和幅值是否正常。 3.交叉测试: 通过替换核心板或底板的方式,快速定位问题所在位置,判断是核心板的问题还是底板的问题。 4.信号完整性检查: 测量引脚电平是否符合预期; 检查数据信号是否有正常输出; 确认信号空闲状态是否正常。 5.焊接质量检查: 排查焊接问题,阻容器件是否存在虚焊、连焊、漏焊、错焊等问题; 排查器件焊接的方向,是否存在如焊接的器件1脚和底板的1脚标识不对应问题。 6.引脚复用确认: 通过查阅AM62x技术参考手册,确认所用引脚的功能复用配置是否正确,特别要注意启动相关引脚的默认功能。 二、系统不启动问题排查 当OK62xx-C开发板无法正常启动时,可按照以下步骤排查: 1.关键信号检查: 测量VCC_3V3_SYS_PG(RD60)信号,确保电源正常; 检查所有电源轨电压是否在允许范围内; 验证复位信号时序是否符合处理器要求。 2.启动配置检查: 确认底板设计中对GPMC总线相关启动项引脚做了正确的上下拉处理; 特别注意连接FPGA等外设时,不能影响启动配置电平; 核对boot模式选择引脚的电平状态。 3.I2C总线冲突排查: RU50、RU52为I2C0总线,核心板可能已挂载多个设备; 确保底板不悬空这些引脚,同时其他功能不重复使用I2C0; 检查I2C总线上拉电阻是否正常。 4.交叉测试: 更换核心板或底板,确认是否是个例问题。 三、I2C接口问题排查 I2C总线常见问题及解决方法: 1.基础配置检查: 确认SCL和SDA线均有上拉电阻; 检查同组I2C总线下挂载设备的地址是否有冲突。 2.信号质量分析: 测量空闲状态是否为高电平; 观察数据传输时波形是否完整,是否存在过冲或振铃; 使用逻辑分析仪捕获完整通信过程。 3.阻抗匹配调整: 若波形上升沿缓慢,可减小上拉电阻值; 若低电平过高,可增大上拉电阻值。 4.诊断工具使用: 可通过I2Ctool工具查看总线上是否挂载设备: i2cdetect-l //检测系统上有几组I2C i2cdetect- r -y2 //检测I2C第二组总线上的挂载的设备 四、SPI接口问题排查 SPI通信故障排查要点: 1.硬件连接确认: MOSI和MISO必须交叉连接; 确认片选信号连接正确且未被其他功能复用; 检查SPI时钟线是否连通。 2.模式配置验证: 确认主从设备的CPOL和CPHA设置一致; 检查时钟频率是否在设备支持范围内; 验证数据位宽设置是否正确。 3.信号测量: 使用示波器测量时钟信号质量; 观察数据线在片选有效期间的信号变化; 检查空闲状态下各信号线的电平状态。 五、USB接口问题排查 USB接口(2.0/4G/5G)常见问题: 1.电源检查: 测量USB_VBUS_3V3信号是否为稳定的1.8V; 确认VBUS电流供给能力满足设备需求。 2.信号连接确认: 确认USB的发送信号串联了AC耦合电容。 3.USB特殊注意事项: 一般USB设备端的发送信号已经添加了AC耦合电容,因此接收端不需要再次添加耦合电容; 建议使用差分探头测量高速信号完整性。 六、SDIO问题排查 1.电平配置检查: SDIO接口的引脚电平与传输速度有关,默认工作电压为3.3V,高速模式需切换至1.8V; SDIO信号不可通过电平转换芯片,必须直接连接。 2.信号完整性优化: 确认SDIO总线做了等长处理。 3.上拉电阻配置: 根据规范配置适当的上拉电阻; 检查卡检测引脚的电平状态。 以上就是小编为大家整理的OK62xx-C开发板在开发过程中常见的问题类型以及排查思路。由于篇幅有限,本文先为大家介绍通用思路、不启动问题、I2C接口问题、SPI接口问题、USB问题 和 SDIO问题共6大类型, 后续还将介绍LVDS、PCIe、UART、CAN等等接口的问题以及解决思路,希望大家持续关注。
  • 2025-5-23 16:02
    0 个评论
    米尔电子发布的基于瑞芯微 RK3576 核心板和开发板,具备高性能数据处理能力、领先的AI智能分析功能、多样化的显示与操作体验以及强大的扩展性与兼容性,适用于多种应用场景。目前米尔电子为 RK3576 核心板提供了 Linux、Debian、Android 多种系统镜像,为工程师提供了多样化的选择,助力各行业产品开发落地。 一、系统介绍 系统 概述 myir-image-lr3576-buildroot 基于buildroot 构建的包含 QT 的 Linux 镜像,包含完整的硬件驱动,常用的系统工具,调试工具等。支持使用 Shel.C/C++.Python 进行开发。 myir-image-lr3576-debian 包涵XFCE 桌面的 Debian12 镜像,包含完整的硬件驱动,常用的系统工具,调试工具等。支持使用 Shell,C/C++,Python 进行开发。 myir-image-lr3576-android 基于 Android 14 构建的镜像,包含完整的硬件驱动,支持通用功能 米尔基于瑞芯微 RK3576 开发板 Linux 系统展示: 基于 buildroot 构建的带有 Qt 的 Linux 镜像,包含完整的硬件驱动,常用的系统工具,调试工具等,包含 Qt 运行时库和基于 Qt 开发的 HMI 界面。支持使用 Shell, C/C++, QML, Python 进行应用开发。Qt 是一种跨平台 C++ 图形用户界面应用程序开发框架。它既可以开发 GUI 程序,也可用于开发非 GUI 程序,比如控制台工具和服务器。客户可以在 MYD-LR3576 平台上运行自己的 Qt 程序。 米尔基于瑞芯微 RK3576 开发板 Debian 系统 XFCE 桌面展示: Debian 作为一种广受欢迎的 Linux 发行版,凭借其稳定性和安全性,成为众多用户的首选。MYD-LR3576 的 Debian 系统中已经配置了各种功能外设,比如 USB,SSD,音视频等,用户可直接进行使用。此外,系统还带轻量级的 Xfce 桌面环境,为用户提供高效、稳定和易用的桌面体验。 米尔基于瑞芯微 RK3576 开发板 Android 系统展示: 基于 Android 系统构建的镜像,专为 MYD-LR3576开发板定制,具备良好的硬件兼容性和优化性能。此镜像集成了 Android 系统的核心功能和常用应用程序,为用户提供一个熟悉且功能丰富的移动操作系统环境。它包含完整的硬件驱动,确保了与 MYD-LR3576 开发板的完美适配,实现了对各种硬件资源的高效利用。 二、多系统适配,满足多样化应用场景 依托米尔所提供的多种系统镜像,工程师能够根据自身应用需求,灵活选择相对应的系统环境,进而高效地开发出契合自身业务逻辑的程序。 商业显示 在商业显示领域,米尔提供的的多种软件系统各展所长,助力客户打造吸引顾客、提升品牌价值的展示方案。米尔 MYC-LR3576 核心板搭配安卓系统,凭借其出色的图形处理能力和丰富的多媒体应用生态,能够以精美的界面展示广告和产品信息,吸引顾客的目光。若企业注重数据精准分析,可选择 Debian 系统,其提供稳定的后端支持,通过丰富的软件包资源,帮助企业精准把握顾客需求,实现精准营销和个性化推荐,提高销售转化率。而针对追求快速启动与流畅运行的展示场景,Linux 系统则是理想之选,工程师可以利用 C/C++ 等编程语言,结合 Qt 开发框架,快速构建出高性能的展示程序,确保在商业展示过程中始终保持良好的性能表现,为顾客带来优质的视觉体验。 工业控制 在工业控制领域,米尔 MYC-LR3576 核心板支持的多种的软件系统,满足不同工业场景需求。对于需要轻量化、高效解决方案的场景,米尔的 Linux 系统是不二之选,它为工程师提供了基础的开发环境和工具链,帮助工程师快速开发高效、可靠的工业控制程序,实现设备的精准操控与实时监测,确保生产过程的稳定性与高效性。在对软件资源丰富度和系统稳定性有较高要求的工业应用中,米尔的 Debian 系统则展现出独特优势,其提供丰富的软件包资源和稳定的运行环境,工程师可以安装各种工业控制软件包、数据库管理系统以及数据安全工具,确保工业控制程序在长时间运行过程中的可靠性,减少系统故障与停机时间,保障工业生产的连续性。而在需要开发便于操作人员使用的工业控制终端的场景下,安卓系统则能发挥其图形化界面和丰富交互功能的优势,工程师可以开发出触摸屏操作的设备监控应用,使操作人员能够直观地查看设备运行状态、参数设置,并进行远程控制与调整,提升工业控制的人性化与智能化水平。 三、丰富开发资源:省时省力,高效推进项目 米尔提供适用于 MYD-LR3576 开发板的 SDK 文件,涵盖 BSP 开发、文件系统开发和各类测试工具,帮助开发者构建出可运行在 MYD-LR3576 开发板上的系统镜像,从底层驱动适配到上层应用开发,一应俱全,大幅缩短开发周期,让您的项目快速推进。 米尔基于瑞芯微RK3576核心板及开发板 瑞芯微RK3576处理器,8核6T高算力赋能工业AI智能化 AI边缘应用:搭载6 TOPS的NPU加速器,3D GPU; 多种外设:双千兆以太网、PCIE2.1、USB3.2、SATA3、DSMC/Flexbus、CANFD、UART等; 8K@30fps/4K@120fps 解码(H.265、VP9、AVS2、AV1),4K@60fps编码(H.265、H.264); 多种多媒体接口HDMI/eDP/DP/MIPI-DSI/Parallel RGB/MIPI CSI/16M Pixel ISP; LGA381 PIN、商业级:0℃ ~ +70℃、工业级:-40℃~+85℃; 适用于工业、AIoT、边缘计算、智能移动终端以及其他多种数字多媒体等场景。 米尔基于瑞芯微 RK3576 开发板 总结: 米尔的多种系统方案为不同领域提供了多样化的解决方案,工程师可以根据自身需求灵活选择,快速构建出契合业务逻辑的应用程序,实现高效开发与精准适配。 RK3576、RK3576核心板、RK3576开发板、国产核心板
相关资源
  • 所需E币: 2
    时间: 2025-6-6 15:15
    大小: 951.13KB
    上传者: 电子阔少
    Linux中有很多编程思想可以学习,很多大佬把这些思想、机制运用到单片机的编程上,STM32模拟Linuxkernel自动初始化流程。通常我们写程序都是按照这个套路,一个函数一个函数按照顺序逻辑一个一个的执行下去。
  • 所需E币: 0
    时间: 2025-6-6 11:38
    大小: 980.59KB
    上传者: 电子阔少
    国内的Linux就两个主流桌面环境!.pdf国内目前主流社区个人Linux桌面发行版一个是Deepin,一个是OpenKylin。
  • 所需E币: 2
    时间: 2025-4-26 16:19
    大小: 160.06MB
    上传者: wuliangu
    本书内容是服务器的架设,由所需的基础技能,基础知识,到复杂的架设过程,内容丰富较全面,很值得一看。
  • 所需E币: 0
    时间: 2023-12-25 10:31
    大小: 2.57KB
    上传者: 开心就很好了
    今天我将给大家讲解基于C++的Linux高性能事件驱动网络编程框架的设计方法及技巧,我在文中采取渐进迭代的方式,配合C++11新特性的使用,以及网络编程理论的深度讲解,并手把手带着大家落地实现,助力在网络编程领域有更大的技术提升!Linux系统的性能是指操作系统完成任务的有效性、稳定性和响应速度。Linux系统管理员可能经常会遇到系统不稳定、响应速度慢等问题,例如在Linux上搭建了一个web服务,经常出现网页无法打开、打开速度慢等现象,而遇到这些问题,就有人会抱怨Linux系统不好,其实这些都是表面现象。Linux提供三个「点分十进制字符串表示的IPv4地址和用网络字节序整数表示的IPv4地址之间转换」的接口 publicGraceJSONResultdoLogin(HttpServletRequestrequest,                  HttpServletResponseresponse,                  RegisterLoginBOregisterLoginBO,                  BindingResultresult){  //判断BindingResult是否保存错误的验证信息,如果有,则直接return  if(result.hasErrors()){    Map<String,String>errorMap=getErrors(result);    returnGraceJSONResult.errorMap(errorMap);  }  //获得前端传来的基本信息  StringsmsCode=registerLoginBO.getSmsCode();  Stringmobile=registerLoginBO.getMobile();  //0.校验验证码是否匹配  StringredisSMSCode=redis.get(MOBILE_SMSCODE+mobile);  if(StringUtils.isBlank(redisSMSCode)||!redisSMSCode.equalsIgnoreCase(smsCode)){    returnGraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);  }  returnGraceJSONResult.ok();}用户信息其实并不会经常发生变动,所以这块内容完全可以放入缓存,这么一来可以大大减少对数据库的压力。privateAppUsergetUser(StringuserId){  //1.查询redis中是否包含用户信息,如果包含则查询redis返回,如果不包含则查询数据库  StringuserJson=redis.get(REDIS_USER_INFO+":"+userId);  AppUseruser=null;  if(StringUtils.isNotBlank(userJson)){    user=JsonUtils.jsonToPojo(userJson,AppUser.class);  }else{    user=userService.getUser(userId);    //2.由于用户信息不怎么会变动,对于千万级别的网站,这类信息数据不会去查询数据库,完全可以把用户信息存入redis    //哪怕修改信息,也不会立马体现,这也是弱一致性,在这里有过期时间,比如1天以后,用户信息会更新到页面显示,或者缩短到1小时,都可以    //基本信息在新闻媒体类网站是属于数据一致性优先级比较低的,用户眼里看的主要以文章为主,至于文章是谁发的,一般来说不会过多关注    redis.set(REDIS_USER_INFO+":"+userId,JsonUtils.objectToJson(user),1);  }  returnuser;}虽然在表设计的时候把文章阅读数字段进行了设计,但是在大数据量下,文章阅读的累计并发是很高的,在这里我们也是采用redis的计数功能来进行实现。@OverridepublicGraceJSONResultlist(StringarticleId,Integerpage,IntegerpageSize){  if(page==null){    page=COMMON_START_PAGE;  }  if(pageSize==null){    pageSize=COMMON_PAGE_SIZE;  }  PagedGridResultgridResult=         commentPortalService.queryArticleComments(articleId,                           page,                           pageSize);  returnGraceJSONResult.ok(gridResult);}生成html的步骤分为以下几步:定义freemarker生成的html位置配置freemarker基本环境获得ftl模板获得动态数据融合ftl和动态数据,并输出到html@Value("${freemarker.html.target}")privateStringhtmlTarget;@GetMapping("/createHTML")@ResponseBodypublicStringcreateHTML(Modelmodel)throwsException{  //0.配置freemarker基本环境  Configurationcfg=newConfiguration(Configuration.getVersion());  //声明freemarker模板所需要加载的目录的位置  Stringclasspath=this.getClass().getResource("/").getPath();  cfg.setDirectoryForTemplateLoading(newFile(classpath+"templates"));//    System.out.println(htmlTarget);//    System.out.println(classpath+"templates");  //1.获得现有的模板ftl文件  Templatetemplate=cfg.getTemplate("stu.ftl","utf-8");  //2.获得动态数据  Stringstranger=;  model.addAttribute("there",stranger);  model=makeModel(model);  //3.融合动态数据和ftl,生成html  FiletempDic=newFile(htmlTarget);  if(!tempDic.exists()){    tempDic.mkdirs();  }  Writerout=newFileWriter(htmlTarget+File.separator+"10010"+".html");  template.process(model,out);  out.close();  return"ok";}
  • 所需E币: 0
    时间: 2023-12-25 11:06
    大小: 3.48KB
    LinuxSocket网络编程框架主要由3大模块组成:BSDSocketAPIsSocketAbstractionLayerVFSLayerTCP/IP协议在设计和实现上并没有客户端和服务器的概念,在通信过程中所有机器都是对等的。但由于资源(视频、新闻、软件等)都被数据提供者所垄断,所以几乎所有的网络应用程序都很自然地用了客户端/服务器模型,即所有客户端都通过访问服务器来获取所需的资源。BS和CS服务器架构(1)CS架构介绍(clientserver,客户端服务器架构)(2)BS架构介绍(broswerserver,浏览器服务器架构)TCP协议(1)建立连接需要三次握手(2)建立连接的条件:服务器listen时客户端主动发起connect(3)关闭连接需要四次握手(4)服务器或者客户端都可以主动发起关闭packagecom.example.emos.wx.controller.form;importio.swagger.annotations.ApiModel;importlombok.Data;importjavax.validation.constraints.NotBlank;importjavax.validation.constraints.Pattern;@Data@ApiModelpublicclassRegisterForm{  @NotBlank(message="注册码不能为空")  @Pattern(regexp="^[0-9]{6}$",message="注册码必须是6位数字")  privateStringregisterCode;  @NotBlank(message="微信临时授权不能为空")  privateStringcode;  @NotBlank(message="昵称不能为空")  privateStringnickname;  @NotBlank(message="头像不能为空")  privateStringphoto;}在UserController.java中创建login()方法。@PostMapping("/login")@ApiOperation("登陆系统")publicRlogin(@Valid@RequestBodyLoginFormform){intid=userService.login(form.getCode());  Stringtoken=jwtUtil.createToken(id);  Set<String>permsSet=userService.searchUserPermissions(id);  saveCacheToken(token,id);  returnR.ok("登陆成功").put("token",token).put("permission",permsSet);}在CheckinServiceImpl类中,实现抽象方法……publicclassCheckinServiceImplimplementsCheckinService{……publicvoidcreateFaceModel(intuserId,Stringpath){    HttpRequestrequest=HttpUtil.createPost(createFaceModelUrl);    request.form("photo",FileUtil.file(path));    HttpResponseresponse=request.execute();    Stringbody=response.body();    if("无法识别出人脸".equals(body)||"照片中存在多张人脸".equals(body)){      thrownewEmosException(body);    }else{      TbFaceModelentity=newTbFaceModel();      entity.setUserId(userId);      entity.setFaceModel(body);      faceModelDao.insert(entity);    }  }}在CheckinServiceImpl.java类中,实现三个抽象方法。publicclassCheckinServiceImplimplementsCheckinService{……@Override  publicHashMapsearchTodayCheckin(intuserId){    HashMapmap=checkinDao.searchTodayCheckin(userId);    returnmap;  }  @Override  publiclongsearchCheckinDays(intuserId){    longdays=checkinDao.searchCheckinDays(userId);    returndays;  }  @Override  publicArrayList<HashMap>searchWeekCheckin(HashMapparam){    ArrayList<HashMap>checkinList=checkinDao.searchWeekCheckin(param);    ArrayList<String>holidaysList=holidaysDao.searchHolidaysInRange(param);    ArrayList<String>workdayList=workdayDao.searchWorkdayInRange(param);    DateTimestartDate=DateUtil.parseDate(param.get("startDate").toString());    DateTimeendDate=DateUtil.parseDate(param.get("endDate").toString());    DateRangerange=DateUtil.range(startDate,endDate,DateField.DAY_OF_MONTH);    ArrayListlist=newArrayList();    range.forEach(one->{      Stringdate=one.toString("yyyy-MM-dd");      //查看今天是不是假期或者工作日      Stringtype="工作日";      if(one.isWeekend()){        type="节假日";      }      if(holidaysList!=null&&holidaysList.contains(date)){        type="节假日";      }elseif(workdayList!=null&&workdayList.contains(date)){        type="工作日";      }      Stringstatus="";      if(type.equals("工作日")&&DateUtil.compare(one,DateUtil.date())<=0){        status="缺勤";booleanflag=false;        for(HashMap<String,String>map:checkinList){          if(map.containsValue(date)){            status=map.get("status");flag=true;            break;          }        }DateTimeendTime=DateUtil.parse(DateUtil.today()+""+constants.attendanceEndTime);Stringtoday=DateUtil.today();if(date.equals(today)&&DateUtil.date().isBefore(endTime)&&flag==false){          status="";        }      }      HashMapmap=newHashMap();      map.put("date",date);      map.put("status",status);      map.put("type",type);      map.put("day",one.dayOfWeekEnum().toChinese("周"));      list.add(map);    });    returnlist;  }}在EmosWxApiApplicationTests.java类中提供了contextLoads()测试用例方法,我们把生成大量系统消息记录的代码写在其中,程序运行的时候这些消息记录就会写入到MongoDB里面。@SpringBootTestclassEmosWxApiApplicationTests{  @Autowired  privateMessageServicemessageService;  @Test  voidcontextLoads(){    for(inti=1;i<=100;i++){      MessageEntitymessage=newMessageEntity();      message.setUuid(IdUtil.simpleUUID());      message.setSenderId(0);      message.setSenderName("系统消息");      message.setMsg("这是第"+i+"条测试消息");      message.setSendTime(newDate());      Stringid=messageService.insertMessage(message);      MessageRefEntityref=newMessageRefEntity();      ref.setMessageId(id);      ref.setReceiverId(11);//注意:这是接收人ID      ref.setLastFlag(true);      ref.setReadFlag(false);      messageService.insertRef(ref);    }  }}在该页面的模型层里面声明静态数据。list数组保存的是后端Java返回的成员数据,内容上按照部门进行分组。members数组保存的是页面上选择的成员id。#include<stdio.h>#include<sys/socket.h>#include<sys/types.h>#include<stdlib.h>#include<arpa/inet.h>#include<unistd.h>#include<string.h> #defineBACKLOG5 intmain(intargc,char*argv[]){  intfd;  structsockaddr_inaddr;  charbuf[BUFSIZ]={};   if(argc<3){    fprintf(stderr,"%s<addr><port>\n",argv[0]);    exit(0);  }   /*创建套接字*/  fd=socket(AF_INET,SOCK_STREAM,0);  if(fd<0){    perror("socket");    exit(0);  }   addr.sin_family=AF_INET;  addr.sin_port=htons(atoi(argv[2]));  if(inet_aton(argv[1],&addr.sin_addr)==0){    fprintf(stderr,"Invalidaddress\n");    exit(EXIT_FAILURE);  }   /*向服务端发起连接请求*/  if(connect(fd,(structsockaddr*)&addr,sizeof(addr))==-1){    perror("connect");    exit(0);  }  while(1){    printf("Input->");    fgets(buf,BUFSIZ,stdin);    write(fd,buf,strlen(buf));  }  close(fd);  return0;}
  • 所需E币: 0
    时间: 2023-12-19 21:14
    大小: 19.01MB
    上传者: xxxml
    Linux基础知识,非常全面
  • 所需E币: 3
    时间: 2023-12-15 09:34
    大小: 10.67MB
    上传者: 二月半
    Linux命令行与shell脚本编程大全(第4版)(RichardBlum、ChristineBresnahan) 
  • 所需E币: 0
    时间: 2023-12-6 15:17
    大小: 3.8KB
    网络编程概述管道(父子进程)、消息队列(内核经营消息队列)、共享内存(创建一个空间)、信号(通过pid号通信)、信号量(对临界资源,共享内存做P、V控制)。特点:依赖于Linux内核AB两个通信基于内核。缺陷:无法多机通信(不适用与两台不同的电脑)TCP和UDP对比:TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信TCP首部开销20字节;UDP的首部开销小,只有8个字节TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道传统的进程间通信借助内核提供的IPC机制进行,但是只能限于本机通信。若要跨机通信,就必须使用网络通信,这就需要用到内核提供给用户的socketAPI函数库。2.1网络字节序大端字节序:也叫高端字节序(网络字节序),是高端地址存放低位数据,低端地址存放高位数据小端字节序:也叫低端字节序,是低地址存放低位数据,高地址存放高位数据。在application.yml文件中,填入SaToken的配置信息,如下:sa-token: #HTTP请求头中哪个属性用来上传令牌 token-name:token #过期时间(秒),设置为30天 timeout:2592000 #临时有效期,设置为3天 activity-timeout:259200 #不允许相同账号同时在线,新登陆的账号会挤掉原来登陆的账号 allow-concurrent-login:false #在多人登陆相同账号的时候,是否使用相同的Token is-share:false token-style:uuid #是否读取Cookie中的令牌 isReadCookie:false #同端互斥 isConcurrent:false #SaToken缓存令牌用其他的逻辑库,避免业务数据和令牌数据共用相同的Redis逻辑库 alone-redis:  database:1  host:localhost  port:6379  password:abc123456  timeout:10s  lettuce:   pool:    #连接池最大连接数    max-active:200    #连接池最大阻塞等待时间(使用负值表示没有限制)    max-wait:10s    #连接池中的最大空闲连接    max-idle:16    #连接池中的最小空闲连接    min-idle:8Java语言允许我们自己封装异常类,我们可以自定义各种异常类,比如每种业务一个异常类,或者每个模块一个异常类。我这里不想做的那么复杂,不如我们创建一个通用的异常类,用来封装与业务有关的异常信息。在com.example.his.api.exception包中,创建HisException.java类。packagecom.example.his.api.exception;importlombok.Data;@DatapublicclassHisExceptionextendsRuntimeException{  privateStringmsg;  privateintcode=500;  publicHisException(Exceptione){    super(e);    this.msg="执行异常";  }  publicHisException(Stringmsg){    super(msg);    this.msg=msg;  }  publicHisException(Stringmsg,Throwablee){    super(msg,e);    this.msg=msg;  }  publicHisException(Stringmsg,intcode){    super(msg);    this.msg=msg;    this.code=code;  }  publicHisException(Stringmsg,intcode,Throwablee){    super(msg,e);    this.msg=msg;    this.code=code;  }}SpringBoot提供了全局处理异常的技术,只要我们给某个Java类用上@RestControllerAdvice注解,这个类就能捕获SpringBoot项目中所有的异常,然后统一处理(精简异常信息)再返回给前端项目。在com.example.his.api.config包中,创建ExceptionAdvice.java类。packagecom.example.his.api.config;importcn.dev33.satoken.exception.NotLoginException;importcn.felord.payment.PayException;importcn.hutool.json.JSONObject;importcom.example.his.api.exception.HisException;importlombok.extern.slf4j.Slf4j;importorg.springframework.validation.BindException;importorg.springframework.http.HttpStatus;importorg.springframework.http.converter.HttpMessageNotReadableException;importorg.springframework.web.HttpRequestMethodNotSupportedException;importorg.springframework.web.bind.MethodArgumentNotValidException;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.ResponseStatus;importorg.springframework.web.bind.annotation.RestControllerAdvice;importorg.springframework.web.multipart.support.MissingServletRequestPartException;@Slf4j@RestControllerAdvicepublicclassExceptionAdvice{  /*   *捕获异常,并且返回500状态码   */  @ResponseBody  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)  @ExceptionHandler(Exception.class)  publicStringexceptionHandler(Exceptione){    JSONObjectjson=newJSONObject();    if(einstanceofHttpMessageNotReadableException){      HttpMessageNotReadableExceptionexception=(HttpMessageNotReadableException)e;      log.error("error",exception);      json.set("error","请求未提交数据或者数据有误");    }     elseif(einstanceofMissingServletRequestPartException){      MissingServletRequestPartExceptionexception=(MissingServletRequestPartException)e;      log.error("error",exception);      json.set("error","请求提交数据错误");    }     elseif(einstanceofHttpRequestMethodNotSupportedException){      HttpRequestMethodNotSupportedExceptionexception=(HttpRequestMethodNotSupportedException)e;      log.error("error",exception);      json.set("error","HTTP请求方法类型错误");    }     //Web方法参数数据类型转换异常,比如String[]数组类型的参数,你上传的数据却是String类型    elseif(einstanceofBindException){      BindExceptionexception=(BindException)e;      StringdefaultMessage=exception.getFieldError().getDefaultMessage();      log.error(defaultMessage,exception);      json.set("error",defaultMessage);    }    //没有通过后端验证产生的异常    elseif(einstanceofMethodArgumentNotValidException){      MethodArgumentNotValidExceptionexception=(MethodArgumentNotValidException)e;      json.set("error",exception.getBindingResult().getFieldError().getDefaultMessage());    }    //处理业务异常    elseif(einstanceofHisException){      log.error("执行异常",e);      HisExceptionexception=(HisException)e;      json.set("error",exception.getMsg());    }     //微信支付异常    elseif(einstanceofPayException){      PayExceptionexception=(PayException)e;      log.error("微信支付异常",exception);      json.set("error","微信支付异常");    }    //处理其余的异常    else{      log.error("执行异常",e);      json.set("error","执行异常");    }    returnjson.toString();  }  /*   *捕获异常,并且返回401状态码   */  @ResponseBody  @ResponseStatus(HttpStatus.UNAUTHORIZED)  @ExceptionHandler(NotLoginException.class)  publicStringunLoginHandler(Exceptione){    JSONObjectjson=newJSONObject();    json.set("error",e.getMessage());    returnjson.toString();  }}因为Controller类用上@RestController注解之后,Web方法返回的对象会被自动转换成JSON对象,所以我们只需要声明一个封装类,让所有Web方法返回这个封装类的对象即可。除了公共属性之外,不同的Web方法要返回的业务数据也不尽相同,所以选择动态的结构才是最佳的方案,恰好HashMap允许我们随便添加数据,那就选择HashMap作为父类吧。在com.example.his.api.common包中,创建R.java类。packagecom.example.his.api.common;importorg.apache.http.HttpStatus;importjava.util.HashMap;importjava.util.Map;publicclassRextendsHashMap<String,Object>{  publicR(){    //默认创建的R对象中包含了公共的属性    put("code",HttpStatus.SC_OK);    put("msg","success");  }  /*   *覆盖继承的put函数,添加Key-Value数据   */  publicRput(Stringkey,Objectvalue){    super.put(key,value);    //把自己返回,用于链式调用    returnthis;  }  publicstaticRok(){    returnnewR();  }  publicstaticRok(Stringmsg){    Rr=newR();    r.put("msg",msg);    returnr;  }  publicstaticRok(Map<String,Object>map){    Rr=newR();    r.putAll(map);    returnr;  }  publicstaticRerror(intcode,Stringmsg){    Rr=newR();    r.put("code",code);    r.put("msg",msg);    returnr;  }  publicstaticRerror(Stringmsg){    returnerror(HttpStatus.SC_INTERNAL_SERVER_ERROR,msg);  }  publicstaticRerror(){    returnerror(HttpStatus.SC_INTERNAL_SERVER_ERROR,"未知异常,请联系管理员");  }}
  • 所需E币: 5
    时间: 2023-11-14 17:51
    大小: 21.11MB
    上传者: 浩瀚星蓝
    这是一本学习linux的经典书籍,详细介绍了shell的使用方法
  • 所需E币: 2
    时间: 2023-11-14 18:00
    大小: 85.65MB
    上传者: 浩瀚星蓝
    这本是是Linux典藏大系的其中一本,详细讲述了ARM嵌入式相关知识
  • 所需E币: 0
    时间: 2023-11-10 15:46
    大小: 1021KB
    上传者: Argent
    第11讲Linux内核顶层Makefile分析
  • 所需E币: 0
    时间: 2023-11-10 15:48
    大小: 1011KB
    上传者: Argent
    第17讲Linux内核移植(NAND版本)-补录
  • 所需E币: 0
    时间: 2023-11-10 15:46
    大小: 1005.5KB
    上传者: Argent
    第10讲Linux内核源码目录分析
  • 所需E币: 0
    时间: 2023-11-10 15:47
    大小: 1014KB
    上传者: Argent
    第13讲Linux内核移植.ppt
  • 所需E币: 0
    时间: 2023-11-10 15:47
    大小: 1MB
    上传者: Argent
    第12讲Linux内核启动流程简介
  • 所需E币: 0
    时间: 2023-11-10 15:46
    大小: 1006KB
    上传者: Argent
    第9讲正点原子官方Linux内核编译与体验
  • 所需E币: 0
    时间: 2023-11-10 16:41
    大小: 1018.5KB
    上传者: Argent
    第15讲LinuxC编程
  • 所需E币: 0
    时间: 2023-11-10 16:41
    大小: 1011KB
    上传者: Argent
    第13讲Linux连接文件
  • 所需E币: 1
    时间: 2023-11-10 11:47
    大小: 28.75KB
    上传者: Argent
    第22讲LinuxIIC驱动实验_笔记
  • 所需E币: 1
    时间: 2023-11-10 11:51
    大小: 27.83KB
    上传者: Argent
    第37讲LinuxADC驱动实验