OpenHarmony子系统开发 - DFX(三)

OpenHarmony子系统开发 - DFX(三)

五、HiTraceMeter开发指导

HiTraceMeter概述

简介

HiTraceMeter在OpenHarmony中,为开发者提供业务流程调用链跟踪的维测接口。通过使用该接口所提供的功能,可以帮助开发者迅速获取指定业务流程调用链的运行日志、定位跨设备/跨进程/跨线程的故障问题。HiTraceMeter用来支持用户态的打点,采集用户态和内核态的trace数据,从而进行性能跟踪与分析的系统。

基本概念

HiTraceMeter系统主要分为三部分:

  • JS/C++应用打点API;
  • Trace数据采集命令行工具;
  • Trace数据图形分析工具。

其中,前两者运行在设备端侧,图形工具运行在PC主机侧。打点API部分提供了C++和JS接口,供开发过程中打点使用,打点用于产生Trace数据流,是抓Trace数据的基础条件。

命令行工具用于采集Trace数据,用来抓取Trace数据流并保存到文本文件。

Trace数据分析可以在图形工具中人工分析,也可以使用分析脚本自动化分析,Trace分析工具以Trace命令行工具的采集结果数据文件为输入。

HiTraceMeter跟踪数据使用类别分类,类别分类称作Trace Tag或Trace Category,一般一个端侧软件子系统对应一个Tag。该Tag在打点API中以类别Tag参数传入。Trace命令行工具采集跟踪数据时,只采集Tag类别选项指定的跟踪数据。应用程序跟踪数据标签都是属于APP Tag,从而JS接口不需要输入tag参数。目前HiTraceMeter支持的Trace Tag表如下(可在hitrace_meter.h hitrace_meter.h 中查看):

constexpr uint64_t HITRACE_TAG_NEVER = 0; // This tag is never enabled.
constexpr uint64_t HITRACE_TAG_ALWAYS = (1ULL << 0); // This tag is always enabled.
constexpr uint64_t HITRACE_TAG_DLP_CREDENTIAL = (1ULL << 21); // This tag is dlp credential service.
constexpr uint64_t HITRACE_TAG_ACCESS_CONTROL = (1ULL << 22); // This tag is access control tag.
constexpr uint64_t HITRACE_TAG_NET = (1ULL << 23); // Net tag.
constexpr uint64_t HITRACE_TAG_NWEB = (1ULL << 24); // NWeb tag.
constexpr uint64_t HITRACE_TAG_HUKS = (1ULL << 25); // This tag is huks.
constexpr uint64_t HITRACE_TAG_USERIAM = (1ULL << 26); // This tag is useriam.
constexpr uint64_t HITRACE_TAG_DISTRIBUTED_AUDIO = (1ULL << 27); // Distributed audio tag.
constexpr uint64_t HITRACE_TAG_DLSM = (1ULL << 28); // device security level tag.
constexpr uint64_t HITRACE_TAG_FILEMANAGEMENT = (1ULL << 29); // filemanagement tag.
constexpr uint64_t HITRACE_TAG_OHOS = (1ULL << 30); // OHOS generic tag.
constexpr uint64_t HITRACE_TAG_ABILITY_MANAGER = (1ULL << 31); // Ability Manager tag.
constexpr uint64_t HITRACE_TAG_ZCAMERA = (1ULL << 32); // Camera module tag.
constexpr uint64_t HITRACE_TAG_ZMEDIA = (1ULL << 33); // Media module tag.
constexpr uint64_t HITRACE_TAG_ZIMAGE = (1ULL << 34); // Image module tag.
constexpr uint64_t HITRACE_TAG_ZAUDIO = (1ULL << 35); // Audio module tag.
constexpr uint64_t HITRACE_TAG_DISTRIBUTEDDATA = (1ULL << 36); // Distributeddata manager module tag.
constexpr uint64_t HITRACE_TAG_MDFS = (1ULL << 37); // Mobile distributed file system tag.
constexpr uint64_t HITRACE_TAG_GRAPHIC_AGP = (1ULL << 38); // Graphic module tag.
constexpr uint64_t HITRACE_TAG_ACE = (1ULL << 39); // ACE development framework tag.
constexpr uint64_t HITRACE_TAG_NOTIFICATION = (1ULL << 40); // Notification module tag.
constexpr uint64_t HITRACE_TAG_MISC = (1ULL << 41); // Notification module tag.
constexpr uint64_t HITRACE_TAG_MULTIMODALINPUT = (1ULL << 42); // Multi modal module tag.
constexpr uint64_t HITRACE_TAG_SENSORS = (1ULL << 43); // Sensors mudule tag.
constexpr uint64_t HITRACE_TAG_MSDP = (1ULL << 44); // Multimodal Sensor Data Platform module tag.
constexpr uint64_t HITRACE_TAG_DSOFTBUS = (1ULL << 45); // Distributed Softbus tag.
constexpr uint64_t HITRACE_TAG_RPC = (1ULL << 46); // RPC and IPC tag.
constexpr uint64_t HITRACE_TAG_ARK = (1ULL << 47); // ARK tag.
constexpr uint64_t HITRACE_TAG_WINDOW_MANAGER = (1ULL << 48); // window manager tag.
constexpr uint64_t HITRACE_TAG_ACCOUNT_MANAGER = (1ULL << 49); // account manager tag.
constexpr uint64_t HITRACE_TAG_DISTRIBUTED_SCREEN = (1ULL << 50); // Distributed screen tag.
constexpr uint64_t HITRACE_TAG_DISTRIBUTED_CAMERA = (1ULL << 51); // Distributed camera tag.
constexpr uint64_t HITRACE_TAG_DISTRIBUTED_HARDWARE_FWK = (1ULL << 52); // Distributed hardware fwk tag.
constexpr uint64_t HITRACE_TAG_GLOBAL_RESMGR = (1ULL << 53); // Global resource manager tag.
constexpr uint64_t HITRACE_TAG_DEVICE_MANAGER = (1ULL << 54); // Distributed hardware devicemanager tag.
constexpr uint64_t HITRACE_TAG_SAMGR = (1ULL << 55); // SA tag.
constexpr uint64_t HITRACE_TAG_POWER = (1ULL << 56); // power manager tag.
constexpr uint64_t HITRACE_TAG_DISTRIBUTED_SCHEDULE = (1ULL << 57); // Distributed schedule tag.
constexpr uint64_t HITRACE_TAG_DEVICE_PROFILE = (1ULL << 58); // device profile tag.
constexpr uint64_t HITRACE_TAG_DISTRIBUTED_INPUT = (1ULL << 59); // Distributed input tag.
constexpr uint64_t HITRACE_TAG_BLUETOOTH = (1ULL << 60); // bluetooth tag.
constexpr uint64_t HITRACE_TAG_ACCESSIBILITY_MANAGER = (1ULL << 61); // accessibility manager tag.
constexpr uint64_t HITRACE_TAG_APP = (1ULL << 62); // App tag.constexpr uint64_t HITRACE_TAG_LAST = HITRACE_TAG_APP;
constexpr uint64_t HITRACE_TAG_NOT_READY = (1ULL << 63); // Reserved for initialization.
constexpr uint64_t HITRACE_TAG_VALID_MASK = ((HITRACE_TAG_LAST - 1) | HITRACE_TAG_LAST);

实现原理

HiTraceMeter主要提供抓取用户态和内核态Trace数据的命令行工具,提供用户态打点的innerkits接口(c++)和kits接口(js),HiTraceMeter基于内核ftrace提供的用户态打点的扩展,利用ftrace的trace_marker节点,将用户空间通过打点接口写入的数据写进内核循环buffer缓冲区。其基本架构图如下:

输入图片说明

约束与限制

  • HiTraceMeter所有功能与接口的实现都依赖于内核提供的ftrace功能,ftrace 是内核提供的一个 framework,采用 plugin 的方式支持开发人员添加更多种类的 trace 功能,因此使用HiTraceMeter之前要使能 ftrace,否则HiTraceMeter的功能无法使用(目前大部分Linux内核默认使能了ftrace,关于ftrace的详细介绍可查看内核ftrace相关资料 ftrace相关资料 )。
  • HiTraceMeter仅限小型系统、标准系统下使用。

HiTraceMeter开发指导

HiTraceMeter分为JS/C++应用打点API与数据采集命令行工具hitrace,下面分别介绍接口和命令行工具。

场景介绍

在实际开发过程中,开发者可能会遇到app卡顿或者在代码调试过程中需要查看代码调用流程,HiTraceMeter接口提供了相应的接口来跟踪程序延时和代码调用流程,分析性能问题。

接口说明

C++接口仅系统开发者使用,JS(目前暂未开放js接口)应用开发者可以略过本节。标准系统上接口描述如下(hitrace_meter.h hitrace_meter.h ):

表 1 同步接口

Sync trace功能描述参数说明
void StartTrace(uint64_t label, const std::string& value, float limit = -1);启动同步tracelabel: Trace category。
value: Trace携带的信息,表明当前的某种状态,例如内存大小,队列长短等。
void FinishTrace(uint64_t label);关闭同步tracelabel: Trace category。

同步接口StartTrace和FinishTrace必须配对使用,FinishTrace和前面最近的StartTrace进行匹配。StartTrace和FinishTrace函数对可以嵌套模式使用,跟踪数据解析时使用栈式数据结构进行匹配。接口中的limit参数用于限流,使用默认值即可。

表 2 异步接口

Async trace功能描述参数说明
void StartAsyncTrace(uint64_t label, const std::string& value, int32_t taskId, float limit = -1);开启异步tracelabel: Trace category。
value: Trace携带的信息,表明当前的某种状态,例如内存大小,队列长短等。
taskId:异步Trace中用来表示关联的ID。
void FinishAsyncTrace(uint64_t label, const std::string& value, int32_t taskId);关闭异步tracelabel: Trace category。
value: Trace携带的信息,表明当前的某种状态,例如内存大小,队列长短等。
taskId:异步Trace中用来表示关联的ID。

异步接口StartAsyncTrace和FinishAsyncTrace的跟踪数据匹配时,使用参数中的value和taskId配对匹配,可以不按顺序使用,主要用于异步场景。在C++程序中,使用异步跟踪的场景很少。

表 3 计数器接口

Counter Trace功能描述参数说明
void CountTrace(uint64_t label, const std::string& name, int64_t);计数tracelabel: Trace category。
name: Trace的名称,IDE中会以此字段展示这段Trace。

开发步骤

  1. 编译依赖添加,需要修改的编译配置文件base\hiviewdfx\hitrace\cmd\BUILD.gn 。

    external_deps = [ "hitrace:hitrace_meter"]
    
  2. 头文件依赖添加。

    #include "hitrace_meter.h"//接口函数定义头文件
    
  3. 接口调用,将需要跟踪的Trace value传入参数,目前HiTraceMeter支持的Trace Tag在基本概念hitrace_meter.h中都已列出,我们以OHOS这个Tag为例,假设我们需要获取func1,func2函数的Trace数据,参考下面实例,在shell中执行hitrace命令后会自动抓取Trace数据,抓到的Trace数据中包括了函数调用过程以及调用过程消耗的内存和时间,可用于分析代码调用流程,代码性能问题。

    #include "hitrace_meter.h" // 包含hitrace_meter.h
    using namespace std;int main()
    {uint64_t label = BYTRACE_TAG_OHOS;sleep(1);CountTrace(label, "count number", 2000);  // 整数跟踪StartTrace(label, "func1Trace", -1); // func1Start的跟踪起始点sleep(1);StartTrace(label, "func2Trace", -1);   // func2Start的跟踪起始点sleep(2);FinishTrace(label);   // func2Trace的结束点sleep(1);FinishTrace(label);   // func1Trace的结束点StartAsyncTrace(label, "asyncTrace1", 1234); // 异步asyncTrace1的开始点   FinishAsyncTrace(label, "asyncTrace1", 1234); // 异步asyncTrace1的结束点return 0;
    } 
    
  4. 使用方法,打点编译部署完成后,运行下面命令行来抓取Trace。然后在端侧shell里运行应用,可以抓取到Trace数据。

    hdc_std shell hitrace -t 10 ohos > .\myapp_demo.ftrace
    

    抓取之后的数据可以在smartperf中"Open trace file"或者直接拖入图形区打开,关于smartperf的详细介绍可查看 smartperf 。

调测验证

以下为一个demo调试过程,该demo使用了同步接口中的StartTrace和FinishTrace。

  1. 编写测试代码hitrace_example.cpp( hitrace_example.cpp ),将使用到的接口加入代码:

    int main()
    {thread t1(ThreadFunc1);t1.join();StartTrace(LABEL, "testStart");sleep(SLEEP_ONE_SECOND);StartTrace(LABEL, "funcAStart", SLEEP_ONE_SECOND); // 打印起始点FuncA();FinishTrace(LABEL);sleep(SLEEP_TWO_SECOND);thread t2(ThreadFunc2);t2.join();StartTrace(LABEL, "funcBStart", SLEEP_TWO_SECOND);FuncB();FinishTrace(LABEL);// 打印结束点sleep(SLEEP_TWO_SECOND);sleep(SLEEP_ONE_SECOND);FinishTrace(LABEL);FuncC();return 0;
    }
    
  2. 修改gn编译文件并编译,编译配置文件路径base\hiviewdfx\hitrace\cmd\BUILD.gn 。

    ohos_executable("hitrace_example") {sources = [ "example/hitrace_example.cpp" ]external_deps = [ "hitrace:hitrace_meter" ]subsystem_name = "hiviewdfx"part_name = "hitrace_native"
    }group("hitrace_target") {deps = [":hitrace",":hitrace_example",]
    }
    
  3. 将编译出来的hitrace_example可执行文件放到设备中的/system/bin目录下,在shell中执行依次执行如下命令:

    hitrace --trace_begin ohos
    hitrace_exampe
    hitrace --trace_dump
    

    当我们看到Trace数据中有我们需要的Trace value时,说明成功抓取Trace,成功的数据如下所示:

    <...>-1651    (-------) [002] ....   327.194136: tracing_mark_write: S|1650|H:testAsync 111
    <...>-1650    (-------) [001] ....   332.197640: tracing_mark_write: B|1650|H:testStart
    <...>-1650    (-------) [001] ....   333.198018: tracing_mark_write: B|1650|H:funcAStart
    <...>-1650    (-------) [001] ....   334.198507: tracing_mark_write: E|1650|
    <...>-1654    (-------) [003] ....   341.201673: tracing_mark_write: F|1650|H:testAsync 111
    <...>-1650    (-------) [001] ....   341.202168: tracing_mark_write: B|1650|H:funcBStart
    <...>-1650    (-------) [001] ....   343.202557: tracing_mark_write: E|1650|
    <...>-1650    (-------) [001] ....   346.203178: tracing_mark_write: E|1650|
    <...>-1650    (-------) [001] ....   346.203457: tracing_mark_write: C|1650|H:count number 1
    <...>-1650    (-------) [001] ....   347.203818: tracing_mark_write: C|1650|H:count number 2
    <...>-1650    (-------) [001] ....   348.204207: tracing_mark_write: C|1650|H:count number 3
    <...>-1650    (-------) [001] ....   349.204473: tracing_mark_write: C|1650|H:count number 4
    <...>-1650    (-------) [001] ....   350.204851: tracing_mark_write: C|1650|H:count number 5
    <...>-1655    (-------) [001] ....   365.944658: tracing_mark_write: trace_event_clock_sync: realtime_ts=1502021460925
    <...>-1655    (-------) [001] ....   365.944686: tracing_mark_write: trace_event_clock_sync: parent_ts=365.944641
    

HiTraceMeter命令行工具使用指导

HiTraceMeter提供了可执行的二进制程序hitrace,设备刷openharmony后直接在shell中运行以下命令,抓取内核运行的数据,当前支持的操作如下:

表 4 命令行列表

OptionDescription
-h,--help查看option帮助
-b n,--buffer_size n指定n(KB)内存大小用于存取trace日志,默认2048KB
-t n,--time n用来指定trace运行的时间(单位:s),取决于需要分析过程的时间
--trace_clock clocktrace输出的时钟类型,一般设备支持boot、global、mono、uptime、perf等,默认为boot
--trace_begin启动抓trace
--trace_dump将数据输出到指定位置(默认控制台)
--trace_finish停止抓trace,并将数据输出到指定位置(默认控制台)
--trace_finish_nodump停止抓trace,不输出trace信息
-l,--list_categories输出手机能支持的trace模块
--overwrite当缓冲区满的时候,将丢弃最新的信息(默认丢弃最老的日志)
-o filename,--output filename指定输出的目标文件名称
-z抓取trace后进行压缩

以下是常用hitrace命令示例,供开发者参考:

  • 查询支持的label。

    
    hitrace -l

    或者

    
    hitrace --list_categories
  • 设置4M缓存,抓取10秒,抓取label为ability的trace信息。

    
    hitrace -b 4096 -t 10 --overwrite ability > /data/log/mytrace.ftrace
  • 设置trace的输出时钟为mono。

    
    hitrace --trace_clock mono  -b 4096 -t 10 --overwrite ability > /data/log/mytrace.ftrace
  • 抓取trace后进行压缩。

    
    hitrace -z  -b 4096 -t 10 --overwrite ability > /data/log/mytrace.ftrace

常见问题

hitrace抓数据不全或者没抓到数据
现象描述

执行hitrace命令抓数据不全或者没抓到数据。

根因分析

参数-t 时间设置过小或者-b缓冲区buffer设置过小导致数据丢失。

解决方法

可设置-t 60,-b 204800扩大抓trace时间和缓冲区buffer解决。

参考

更多关于HiTraceMeter的详细内容请参考:轻量级的分布式调用链跟踪 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/75727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年 能够有效提升AI的生成质量和逻辑严谨性 的通用型系统提示

以下是三个经过精心设计的通用型系统提示&#xff08;System Prompt&#xff09;&#xff0c;能够有效提升AI的生成质量和逻辑严谨性&#xff0c;适用于各类对话、分析和创作场景&#xff1a; Prompt 1 - 专家级分步验证模式 你是一个具备跨领域知识整合能力的超级AI&#xff…

python爬虫:小程序逆向实战教程

根据我之前发表的文章&#xff0c;我们进行延伸实战https://blog.csdn.net/weixin_64809364/article/details/146981598?spm1001.2014.3001.5501 1. 想要爬取什么小程序&#xff0c;我们进行搜索 2. 找到我们vx小程序的文件地址&#xff0c;我们就可以进行破解 破解步骤强看…

C语言变长数组(VLA)详解:灵活处理动态数据的利器

引言 在C语言中&#xff0c;传统的数组大小必须在编译时确定&#xff0c;这限制了程序处理动态数据的灵活性。C99标准引入的变长数组&#xff08;Variable-Length Array, VLA&#xff09; 打破了这一限制&#xff0c;允许数组长度在运行时动态确定。本文将深入解析VLA的语法、…

串口数据转换为IP数据

串口数据转换为IP数据是一种常见的通信技术,用于将传统的串行设备(如传感器、控制器等)接入现代的IP网络。以下是详细介绍: 1. 转换原理 串口数据转换为IP数据的过程涉及硬件和软件的结合,核心是将串行数据封装为TCP/IP或UDP/IP数据包,通过网络传输。具体步骤如下: 硬…

client-go如何监听自定义资源

如何使用 client-go 监听自定义资源 在 Kubernetes 中使用 client-go 监听自定义资源&#xff08;Custom Resource&#xff0c;简称 CR&#xff09;需要借助 Dynamic Client 或 Custom Informer&#xff0c;因为 client-go 的标准 Clientset 只支持内置资源&#xff08;如 Pod…

C++软件开发架构

文章目录 1.全局消息通信MsgHandler.h单元测试(QTest)MsgHandlerUnitTest.hMsgHandlerUnitTest.cpp 2.实例间通信InstMsgHandler.h单元测试InstMsgHandlerUnitTest.hInstMsgHandlerUnitTest.cpp 1.全局消息通信 1. 适用于类与类单个对象实例之间的通信&#xff0c;多个对象需要…

AI Agent设计模式一:Chain

概念 &#xff1a;线性任务流设计 ✅ 优点&#xff1a;逻辑清晰易调试&#xff0c;适合线性处理流程❌ 缺点&#xff1a;缺乏动态分支能力 from typing import TypedDictfrom langgraph.graph import StateGraph, END# 定义后续用到的一些变量 class CustomState(TypedDict):p…

Git三剑客:工作区、暂存区、版本库深度解析

一、引言&#xff1a;为什么需要理解Git的核心区域&#xff1f; 作为开发者&#xff0c;Git是日常必备的版本控制工具。但你是否曾因以下问题感到困惑&#xff1f; 修改了文件&#xff0c;但 git status 显示一片混乱&#xff1f; git add 和 git commit 到底做了什么&#x…

Python数据类型-list

列表(List)是Python中最常用的数据类型之一&#xff0c;它是一个有序、可变的元素集合。 1. 列表基础 创建列表 empty_list [] # 空列表 numbers [1, 2, 3, 4, 5] # 数字列表 fruits [apple, banana, orange] # 字符串列表 mixed [1, hello, 3.14, True] # 混合类型…

Keepalive+LVS+Nginx+NFS高可用项目

项目架构 分析 主机规划 主机系统安装应用网络IPclientredhat 9.5无NAT172.25.250.115/24lvs-masterrocky 9.5ipvsadm&#xff0c;keepalivedNAT172.25.250.116/24 VIP 172.25.250.100/32lvs-backuprocky 9.5ipvsadm&#xff0c;keepalivedNAT172.25.250.117/24 VIP 172.25.2…

【视觉与语言模型参数解耦】为什么?方案?

一些无编码器的MLLMs统一架构如Fuyu&#xff0c;直接在LLM内处理原始像素&#xff0c;消除了对外部视觉模型的依赖。但是面临视觉与语言模态冲突的挑战&#xff0c;导致训练不稳定和灾难性遗忘等问题。解决方案则是通过参数解耦方法解决模态冲突。 在多模态大语言模型&#xf…

AI比人脑更强,因为被植入思维模型【43】蝴蝶效应思维模型

giszz的理解&#xff1a;蝴蝶效应我们都熟知&#xff0c;就是说一个微小的变化&#xff0c;能带动整个系统甚至系统的空间和时间的远端&#xff0c;产生巨大的链式反应。我学习后的启迪&#xff0c;简单的说&#xff0c;就是不要忽视任何微小的问题&#xff0c;更多时候&#x…

AI 数理逻辑基础之统计学基本原理(上)

目录 文章目录 目录统计学统计学基本概念描述性统计数据可视化图表工具 汇总统计统计数据的分布情况&#xff1a;中位数、众数、平均值统计数据的离散程度&#xff1a;极差、方差、标准差、离散系数 相关分析Pearson 线性关系相关系数Spearman 单调关系相关系数 回归分析回归模…

无招回归阿里

这两天&#xff0c;无招回归阿里的新闻被刷屏了。无招创业成立的两氢一氧公司无招的股份也被阿里收购&#xff0c;无招以这种姿态回归阿里&#xff0c;并且出任钉钉的 CEO。有人说&#xff0c;这是对 5 年前“云钉一体”战略的纠偏。现在确实从云优先到 AI 优先&#xff0c;但云…

算法题(114):矩阵距离

审题&#xff1a; 本题需要我们找出所有0距离最近的1的曼哈顿距离 思路&#xff1a; 方法一&#xff1a;多源bfs 分析曼哈顿距离&#xff1a; 求法1&#xff1a;公式法&#xff0c;带入题目公式&#xff0c;利用|x1-x2||y1-y2|求出 求法2&#xff1a;曼哈顿距离就是最短距离 本…

LLM 性能优化有哪些手段?

LLM(大语言模型)性能优化是一个多维度、多层次的系统工程,涉及从提示工程到模型微调,从推理加速到系统架构优化等多个方面。以下是当前主流的优化手段及其技术细节: 一、提示工程(Prompt Engineering) 提示工程是优化LLM性能最直接、成本最低的方法,适用于快速原型开发…

群体智能避障革命:RVO算法在Unity中的深度实践与优化

引言&#xff1a;游戏群体移动的挑战与进化 在《全面战争》中万人战场恢弘列阵&#xff0c;在《刺客信条》闹市里人群自然涌动&#xff0c;这些令人惊叹的场景背后&#xff0c;都离不开一个关键技术——群体动态避障。传统路径规划算法&#xff08;如A*&#xff09;虽能解决单…

I.MX6ULL 交叉编译环境配置与使用

一、什么是交叉编译 我们一般开发程序在自己的电脑上开发&#xff0c;运行的时候将程序烧录到板子运行。但我们的开发平台是X86架构&#xff0c;而I.MX6ULL是ARM架构&#xff0c;所以需要一个在 X86 架构的 PC 上运行&#xff0c;可以编译 ARM 架构代码的 GCC 编译器&#xff0…

Harmony OS“一多” 详解:基于窗口变化的断点自适应实现

一、一多开发核心概念&#xff08;18N模式&#xff09; 目标&#xff1a;一次开发多端部署 解决的问题&#xff1a; 1、界面级一多&#xff1a;适配不同屏幕尺寸 2、功能级一多&#xff1a;设备功能兼容性处理(CanIUser) 3、工…

SpringMvc获取请求数据

基本参数 RequestMapping("save5") ResponseBody public User save5(String name, int age) {User user new User();user.setName(name);user.setAge(age);return user; } 在url中将name与age进行编写&#xff0c;通过框架可以提取url中的name与age&#xff0c;这…