迅为RK3576开发板Android 多屏显示

迅为iTOP-3576开发板采用瑞芯微RK3576高性能、低功耗的应用处理芯片,集成了4个Cortex-A72和4个Cortex-A53核心,以及独立的NEON协处理器。它适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品。

 

1.1 Android 多屏同显

iTOP-RK3576 开发板支持以下屏幕

迅为 MIPI 7 寸屏幕

标准 HDMI 屏幕(通过 HDMI 线连接)

迅为 LVDS 7 寸屏幕

迅为 LVDS 10.1 寸 1024*600 屏幕

迅为 LVDS 10.1 寸 1280*800 屏幕

然后修改 Android 源码 kernel-6.1/arch/arm64/boot/dts/rockchip/topeet-screen-lcds.dtsi 中的

设备树文件,如下图所示。LVDS 屏幕是 MIPI 通过转接板连接显示的,RK3576 不支持 LVDS

显示接口。

 

我们可以根据自己的需求来修改 topeet-screen-lcds.dtsi 文件。总之,修改

topeet_screen_choose.dtsi 的规律是:打开所连接的屏幕对应的宏定义,rk3576 有三个显示通

道 vp0 vp1 vp2,所打开的宏定义对应的 vp 通道不能重复。默认打开对应的宏定义为多屏同显。

如果打开的宏定义是#define LCD_TYPE_LVDS_10_1_1280x800_GT9271, 需要将

kernel-6.1/arch/arm64/configs/rockchip_defconfig 文件中的

CONFIG_TOUCHSCREEN_GT9271=y 宏定义使能,然后再编译源码。

如果打开的宏定义是#define LCD_TYPE_LVDS_10_1_1024x600_GT911,需要将

kernel-6.1/arch/arm64/configs/rockchip_defconfig 文件中的 CONFIG_TOUCHSCREEN_GT9XX

宏定义使能,然后再编译源码。

1.2 Android 多屏异显

如果要支持多屏异显,首先要调试好双屏或多屏都可以正常显示,并且分别挂载在不同的

vp 上,可以参考上一个小节根据自己的需求打开 topeet-screen-lcds.dtsi 设备树中的宏定义。默

认开启后,多屏显示的是同一个画面(如果要支持双屏或者多屏异显,需要应用支持异显,才会显示不同的内容)。查看当前的屏幕显示状态输入以下命令

cat /sys/kernel/debug/dri/0/summary

如果双屏或者多屏的显示器分辨率比例不同,比如说主屏是 16:9,副屏是 4:3,那么副

屏显示的画面会拉伸或者缩小,原因是副屏的画面是主屏映射过去的,所以副屏上显示的是

主屏的分辨率。如果同样的屏幕情况下,应用支持异显,那么副屏会显示实际正常的分辨率。

所以如果要支持双屏或者多屏同显并要求显示正常,双屏或者多屏的屏幕的分辨率比要一致。

1.2.1 指定主副屏

多屏异显的实际应用中,需要指定哪个是主屏,哪个是副屏。修改 Android14 源码目录下

rk3576_android14/device/rockchip/rk3576/topeet_rk3576/topeet_rk3576.mk 文件,添加如下内容:

如果要指定 MIPI 屏幕为主屏,HDMI 屏幕为副屏,如下设置:

PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI

PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=HDMI-A

如果要指定 MIPI 屏幕为主屏,EDP 屏幕为副屏,如下设置:

PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI

PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=eDP

如果需要定义多个主副屏时,需要用逗号隔开,比如指定 MIPI eDP 为主屏,HDMI-A 为副屏,

设置如下:

PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI,eDP

PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.extend=HDMI-A

1.2.2 异显方案介绍

目前有两种异显方案分别是 Android Presentation 和 Andorid Activity 指定屏幕启动 。

Android Presentation,需要 APP 应用开发中调用相应接口使指定的 view (Presentation

view 是一个特殊的 dialog 类型 view)在副屏中显示。

Android Activity 指定屏幕启动,APP 在启动 activity 时可以使用 display id 参数在对应

的屏幕上直接显示。

两者主要区别在:

1 前者的 acitivity 需要独立开发,把需要显示的内容投到副屏,后者可以不需要源码,调用命令行或者系统接口把第三方 app 的 acitivity 投送到副屏;

2 .前者只有一个 activity 在顶层,通过特殊的 dialog 将指定内容显示在副屏,后者是两

个 activity 分别显示在主副屏。

接下来我们详细讲述这俩种方法。

1.2.3 Android Presentation

本小节讲解 Android Presentation 异显方案,瑞芯微和迅为提供了使用 Android Presentation

编写好的 APP 例程,接下来进行测试。

1.2.3.1 ApiDemos APP

在 Android12 源码中瑞芯微已经提供了使用 Presentation 接口的测试 APP,在源码

development/samples/ApiDemos 目录下,需要使用 mm 命令编译 APP。迅为提供了编译好的

测试 APP 在网盘资料“iTOP-RK3576 开发板/02_【iTOP-RK3576 开发板】/07_多屏显示配套

资料/Android/ApiDemosAPK”目录下。

此 APP 源码在 Android 源码 rk3576_android14/development/samples/ApiDemos 目录下,进

入此目录,输入“mm”命令进行编译,如下图所示:

 

然后使用 adb 命令安装 APP,依次点击 App->Activity->Presentation 选项,即可进入

Presentation 调用界面。如下图所示:

 

在该界面需点击如下副屏的 checkbox 选项,即可在副屏显示相应图片。如下所示:

 

副屏 HDMi 屏幕显示图片,如下所示:

 

1.2.3.2 Presentation sampleAPP

此 APP 在网盘资料“iTOP-RK3576 开发板/02_【iTOP-RK3576 开发板】/07_多屏显示配

套资料/Android/Presentation-sample”目录下,下载此 APP 工程,然后用 Androidstudio 打开,

并编译 apk。编译成功之后,安装 APP,APP 安装成功之后如下图所示:

 

打开 APP 如下图所示:

 

点击“显示副屏”按钮,会在副屏显示,如下图所示:

 

APP 重要知识点讲解:

随着用户的需求增多,特别是对于一些 Android 平板电脑以及其他的一些 Android 智能设

备可能有多个屏幕,用户不仅想要在主屏幕上显示内容,同样在第二屏幕上也要显示想要的

内容,这样可以达到更好的体验效果。Google 也是不负众望在 Android4.2 版本以后提供了

Presentation 类,可以轻松实现在两块屏幕上同时显示不同的内容。Presentation 是一个特殊的

dialog,它的目的是显示内容到第二屏幕。在 Presentation 创建的时候关联一个目标设备,确

定 Presentation 要显示在那个设备上,根据这个设备的信息来配置 Presentation 的 context 和

resources 信息。目前系统提供了两种方式来与目标显示屏进行绑定。

1 通过 MediaRouter 接口获取并绑定:

选择显示 presentation 的设备最简单的方法就是使用 Media Router,media router 服务持续

追踪在系统中哪个音频、视频线路是可用的,当 routes 被选择或者不被选择,或者更好的显

示 presentation display 的线路发生改变后 media router 就会发送消息。所以一些应用程序可以

自动监视这些消息来在首选设备上显示或取消 presentation。

首选显示 presentation 的设备是 Media Router 进行推荐的,如果应用想要显示内容在第二

屏幕上就该使用该设备。下面将给出如何使用 media router 在主屏的设备创建和显示

presentation。

MediaRouter mediaRouter =(MediaRouter)

context.getSystemService(Context.MEDIA_ROUTER_SERVICE); MediaRouter.RouteInfo route =

mediaRouter.getSelectedRoute();

if(route !=null){

Display presentationDisplay = route.getPresentationDisplay();

if(presentationDisplay !=null){

Presentation presentation =newMyPresentation(context, presentationDisplay);

presentation.show();

}

}

根据上面代码可以看出通过系统服务 Media Router 来选择一个合适的 route,从 route 中来

获取首选的 display,如果 display 不为空就会创建该 presentation,创建完成后调用 presentation

的 show 方法将该 presentation 显示出来。

2 通过 DisplayManager 接口获取并绑定

另外一个获取首选 display 的方法是直接使用 display Manager 来获取。display manager 服

务提供方法枚举和描述系统中所有的设备,包括可以显示 presentation 的设备。display manager

持续追踪系统中所有的设备,然而,并不是所有的设备都适合显示 presentation,例如,如果

一个 Activity 试图在主屏幕上显示一个 presentation,它可能会掩盖自己的内容,这就像在

Activity 上打开一个 dialog 一样。

DisplayManager displayManager =(DisplayManager)

context.getSystemService(Context.DISPLAY_SERVICE); Display[] presentationDisplays

=displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);

if(presentationDisplays.length >0){

// If there is more than one suitable presentation display, then we could consider

// giving the user a choice. For this example, we simply choose the first display

// which is the one the system recommends as the preferred presentation display.

Display display = presentationDisplays[1]; // displays[1]是副屏

Presentation presentation =new MyPresentation(context, presentationDisplay);

presentation.show();

}

根据上面代码可以看出通过系统服务 Display Manager 来获取所有适合显示 presentation 的

display 列表,如果获取到了多个适合 display 对象,我们选择副屏的 display。最后显示

presentation。

1.2.4 Android Activity 指定屏幕启动

本小节讲解 Android Activity 指定屏幕启动异显方案,瑞芯微提供了使用 Android Activity

指定屏幕启动编写好的 APP 例程,接下来进行测试。

1.2.4.1 dualscreendemo APP

RK DualScreen 主要区别与 android presentation,在于它实现了应用的派发,允许厂商快

速根据现有的 app 功能,进行模块的集成,减少开发周期和研发成本。示例代码为

DualScreenDemo.zip 工程,在网盘资料“iTOP-RK3576 开发板/02_【iTOP-RK3576 开发板】/07_

多屏显示配套资料/Android/DualScreenDemo”目录下下载。

使用 Androidstudio 打开此工程代码,编译安装 APP,安装完成后如下所示:

打开此 APP,如下所示,有三个按钮。

第三个按钮使用了 Android Activity 指定屏幕启动,关键代码如下所示,第一个和第二个

按钮使用了 Presentation。

private void showSecondByActivity(Context context){

ActivityOptions options = ActivityOptions.makeBasic();

MediaRouter mediaRouter = (MediaRouter)

context.getSystemService(Context.MEDIA_ROUTER_SERVICE);

MediaRouter.RouteInfo route =

mediaRouter.getSelectedRoute(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);

if (route != null) {

Display presentationDisplay = route.getPresentationDisplay();

options.setLaunchDisplayId(presentationDisplay.getDisplayId());

Intent intent = new Intent("android.intent.action.MUSIC_PLAYER");

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent, options.toBundle());

}

}

在 startActivity 接口参数中设置指定屏幕的 display id,Activity 将在指定屏幕上直接启

动显示。

Activity 的多显示器支持需要设备支持<feature

name="android.software.activities_on_secondary_displays" />。

同时 application 或者 activity 需要支持分屏属性即<application>或者<activity>标签下设

置新的属性 android:resizeableActivity="true",这个属性在你 target 到 Android N 后

android:resizeableActivity 的默认值就是 true。

ActivityOptions 提供两个新函数以支持多个显示器,分别是 setLaunchDisplayId()和

getLaunchDisplayId()。

setLaunchDisplayId() 指定 Activity 在启动后应显示在哪个显示器上。

getLaunchDisplayId() 返回操作组件的当前启动显示器。

在上述代码中使用 MediaRouter 接口获取副屏的 display id,同理也可以使用

DisplayManager 接口获取响应的 display id。

1.2.5 支持输入法在副屏显示

修改 Android14 源码下的 device/rockchip/common/display_settings.xml 文件,如下所示:

将设置相应屏幕 shouldShowIme 为 true,如上配置支持输入法在 local:1 的副屏上显示。

1.2.6 副屏 DPI 设置

修改 Android14 源码下的 device/rockchip/common/display_settings.xml 文件,如下所示:

修改 forcedDensity 的值可以修改副屏的屏幕密度。

1.2.7 主屏幕可以触摸,副屏不触摸

如果想要实现主屏可以触摸,副屏不用触摸的功能。有两种解决方式:第一种是在 App

应用代码中实现。第二种需要修改 framework 层的源码。

第一种方式:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,

WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

第二种方式:

修改 Android14 源码 frameworks/native/services/inputflinger/reader/EventHub.cpp 文件,屏蔽掉 device->classes |= InputDeviceClass::EXTERNAL;属性,如下图所示:

1.2.8 多屏异触

多屏异触需要指定主副屏。这里使用修改 Android 源码的方式实现绑定副屏触摸芯片。这

样设置以后,系统开机会自动将 ft5x06 触摸绑定到副屏上面去。修改文件:

frameworks/native/services/inputflinger/reader/EventHub.cpp,添加如下加红的代码。通过修改

EventHub.cpp 文件,在 isExternalDeviceLocked 函数中判断设备名称为指定的副屏设备(比如

副屏的设备名称是 generic ft5x06 (79)),则返回 true。

bool EventHub::Device::isExternalDeviceLocked() {

const char *I2C_DEVICE_NAME = "generic ft5x06 (79)";

ALOGE("input deviceis '%s' ",device->identifier.name.c_str());

if (strcmp(device->identifier.name.c_str(), I2C_DEVICE_NAME) == 0) {

return true;

}

if (configuration) {

std::optional<bool> isInternal = configuration->getBool("device.internal");

if (isInternal.has_value()) {

return !isInternal.value();

}

}

return identifier.bus == BUS_USB || identifier.bus == BUS_BLUETOOTH;

}

这里的 I2C_DEVICE_NAME 需要根据实际情况添加,用户可根据 ALOGE 打印信息在

logcat 中寻找识别到的芯片实际的名字。下面是添加了 ALOGE 打印信息后在 logcat 中得到的

设备名字的截图:

上图中的 goodix-ts 和 generic ft5x06 (79)即为这里使用的触摸 IC 芯片的名字,将这个复制

到代码中即可。修改完毕,重新编译Android镜像,用户测试的时候可以直接使用ApiDemo APP

进行测试。

1.2.9 鼠标异屏切换

在多屏异显情况下,修改以下代码使鼠标箭头可以移动到需要的副屏上去进行操作。

我们需要修改 Android14 源码中

frameworks/native/services/inputflinger/reader/mapper/CursorInputMapper.cpp 文件

搜索"sys.mouse.presentation",然后将下面的代码中 0 改为 1。

//-----rk-code----

char mMousePresentation[PROPERTY_VALUE_MAX] = {1};

property_get("sys.mouse.presentation", mMousePresentation, "1");

if (strcmp(mMousePresentation, "1") == 0) {

if (std::optional<FloatRect> rect = mPointerController->getBounds();

rect.has_value()) {

if(xCursorPosition==rect->left||xCursorPosition==rect->right||yCursorPosition==rect->top||yCursor

Position==rect->bottom){

mDisplayId=getPolicy()->notifyDisplayIdChanged();

}

}

}else{

mDisplayId = mPointerController->getDisplayId();

}

然后重新编译 Android 源码,然后烧写镜像。
1.2.10 副屏显示配置

1.2.10.1 副屏全屏显示

设置副屏(副屏 1、副屏 2 等)是否全屏显示可通过修改 persist.sys.rotation.efull-n(n=1、

2、3、….)参数的取值进行配置,若配置为 true 则会进行全屏显示。

现以 MIPI 主屏、 HDMI 副 屏 为 例 ,修改如下:

在 device/rockchip/rk3576/topeet_rk3576/topeet_rk3576.mk 文件中添加如下内容,使得

HDMI 副屏可以全屏显示(由于副屏图像参考主屏宽高比进行缩放,若宽高比不一致,则出

现黑边,所以默认 HDMI 副屏显示会有黑边):

PRODUCT_PROPERTY_OVERRIDES += persist.sys.rotation.efull-1=true

修改完成后,保存退出,重新编译烧写镜像即可。

注:由于 mipi 竖屏显示与 HDMI 宽高比相差较大,HDMI 设置全屏显示后拉伸较明显!

1.2.10.2 副屏显示方向

副屏的旋转角度可通过 persist.sys.rotation.einit-n(n=1、2、3、….)属性控制,该属性用

于设置副屏(副屏 1、副屏 2 等)的显示方向,可取值为 0/1/2/3,分别表示将副屏显示方

向旋转(顺时针)0 度、90 度、180 度、270 度。

现以 MIPI 主屏、 HDMI 副 屏 为 例 ,修改如下:

在 device/rockchip/rk3576/topeet_rk3576/topeet_rk3576.mk 文件中添加如下内容,使得

HDMI 副屏的显示方向旋转 90 度:

PRODUCT_PROPERTY_OVERRIDES += persist.sys.rotation.einit-1=1

PRODUCT_PROPERTY_OVERRIDES += persist.sys.rotation.efull-1=false

 

修改完成后,保存退出,重新编译烧写镜像即可,HDMI 会旋转 90°竖屏显示。

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

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

相关文章

【Axure】配色库

配色库是一个专为设计师和创意工作者打造的在线资源平台&#xff0c;旨在提供丰富的色彩解决方案&#xff0c;帮助用户轻松找到或创造美观和谐的色彩搭配。其中&#xff0c;一个典型的配色库包含了以下几个核心元素&#xff1a; 渐变色&#xff1a;提供多样化的渐变色方案&…

港科夜闻 | 香港科大与微软亚洲研究院签署战略合作备忘录,推动医学健康教育及科研协作...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大与微软亚洲研究院签署战略合作备忘录&#xff0c;推动医学健康教育及科研协作。根据备忘录&#xff0c;双方将结合各自于科研领域的优势&#xff0c;携手推动医学健康领域的交流与合作。合作方向将涵盖人才培训、…

机器学习第一道菜(一):线性回归的理论模型

机器学习第一道菜&#xff08;一&#xff09;&#xff1a;线性回归的理论模型 一、问题&#xff1a;千金买笑1.1 散点图1.2 机器学习能搞啥 二、模型的建立2.1 线性回归2.2 回归模型 前面讲了机器学习的“四大绝技”&#xff0c;今天&#xff0c;开始研究第一绝技“回归”&…

【Python】数据容器:列表,元组,字符串,集合字典及通用操作

文章目录 一.序列1.1list列表定义常用操作列表的遍历 1.2tuple元组定义常见操作元组的遍历 1.3str字符串定义常见操作字符串的遍历 1.4序列常用操作——切片 二.set集合定义常见操作集合的遍历 三.dict字典定义常用操作字典的嵌套 *数据容器对比总结四.数据容器的通用操作4.1通…

用 Python 自动化处理日常任务

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

java day04-面向对象基础(内存 封装 继承 修饰符 工具类 )

1.对象内存图 1.1 Java 内存分配 1.2 堆和栈 栈:所有局部变量都会在栈内存中创建 局部变量&#xff1a;定义在方法中的变量或者方法声明上的变量 方法执行都会加载到栈中进行 -----------------------------------------------------------------------------------------…

Qt/C++进程间通信:QSharedMemory 使用详解(附演示Demo)

在开发跨进程应用程序时&#xff0c;进程间通信&#xff08;IPC&#xff09;是一个关键问题。Qt 框架提供了多种 IPC 技术&#xff0c;其中 QSharedMemory 是一种高效的共享内存方式&#xff0c;可以实现多个进程之间快速交换数据。本文将详细讲解 QSharedMemory 的概念、用法及…

从前端视角看设计模式之创建型模式篇

设计模式简介 "设计模式"源于GOF&#xff08;四人帮&#xff09;合著出版的《设计模式&#xff1a;可复用的面向对象软件元素》&#xff0c;该书第一次完整科普了软件开发中设计模式的概念&#xff0c;他们提出的设计模式主要是基于以下的面向对象设计原则&#xff…

Pandas数据合并:concat与merge

目录 一、concat方法 1. 基本语法 2. 示例 示例1&#xff1a;按行合并&#xff08;垂直方向&#xff09; 示例2&#xff1a;按列合并&#xff08;水平方向&#xff09; 示例3&#xff1a;使用joininner进行内连接 示例4&#xff1a;处理列名冲突 二、merge方法 1. 基本…

docker的数据卷与dockerfile自定义镜像

docker的数据卷与dockerfile自定义镜像 一. docker的数据卷数据卷容器 二. dockerfile自定义镜像2.1 dockerfile的命令格式镜像的操作命令add和copy的区别 容器启动的命令 2.2 run命令2.3 其它端口映射 三. 练习 一. docker的数据卷 容器于宿主机之间&#xff0c;或者容器和容…

【大数据】机器学习 -----关于data.csv数据集分析案例

打开表 import pandas as pd df2 pd.read_csv("data.csv",encoding"gbk") df2.head()查看数据属性&#xff08;列标题&#xff0c;表形状&#xff0c;类型&#xff0c;行标题&#xff0c;值&#xff09; print("列标题:",df2.columns)Data…

开发规范

开发规范 企业项目开发有2种开发模式&#xff1a;前后台混合开发和前后台分离开发。 前后台混合开发 顾名思义就是前台后台代码混在一起开发&#xff0c;如下图所示&#xff1a; 这种开发模式有如下缺点&#xff1a; 沟通成本高&#xff1a;后台人员发现前端有问题&#xf…

【Mysql进阶知识】从.SQL文件中执行SQL语句

目录 方法一&#xff1a;使用source命令导入 方法二&#xff1a;使用mysql客户端导入 方法一&#xff1a;使用source命令导入 有时候我们需要从 SQL 文件执行一些 SQL 语句&#xff0c;比如要把一个数据库从一台服务器 A 复制到另一台服务器 B 上&#xff0c;那么可以先从服务…

springMVC---resultful风格

目录 一、创建项目 pom.xml 二、配置文件 1.web.xml 2.spring-mvc.xml 三、图解 四、controller 一、创建项目 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi…

RustDesk ID更新脚本

RustDesk ID更新脚本 此PowerShell脚本自动更新RustDesk ID和密码&#xff0c;并将信息安全地存储在Bitwarden中。 特点 使用以下选项更新RustDesk ID&#xff1a; 使用系统主机名生成一个随机的9位数输入自定义值 为RustDesk生成新的随机密码将RustDesk ID和密码安全地存储…

告别 Excel,拥抱 R 语言:开启数据分析新时代

在这个数据驱动的时代&#xff0c;数据分析已然成为每个行业的核心竞争力。从市场营销到金融领域&#xff0c;从医疗健康到教育行业&#xff0c;数据无处不在&#xff0c;深刻影响着每一个决策。然而&#xff0c;面对日益复杂的数据集&#xff0c;单纯依靠 Excel 进行分析&…

LabVIEW驱动电机实现样品自动搜索

利用LabVIEW控制电机驱动相机在XY平面上进行扫描&#xff0c;以检测样品位置。样品最初可能位于相机视野范围之外&#xff0c;需要实现自动搜索样品位置并完成精确定位扫描的功能。该系统需具有以下特点&#xff1a; 高效搜索&#xff1a;能够快速确定样品位置&#xff0c;缩短…

【C语言】_字符串拷贝函数strcpy

目录 1. 函数声明及功能 2. 使用示例 3. 注意事项 4. 模拟实现 4.1 第一版&#xff1a;基本功能判空const修饰 4.2 第二版&#xff1a;优化对于\0的单独拷贝 4.3 第三版&#xff1a;仿strcpy的char*返回值 1. 函数声明及功能 char * strcpy ( char * destination, cons…

大模型WebUI:Gradio全解11——Chatbots:融合大模型的多模态聊天机器人(3)

大模型WebUI&#xff1a;Gradio全解11——Chatbot&#xff1a;融合大模型的多模态聊天机器人&#xff08;3&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.3 组件Chatbot及ChatMessage11.3.1 Chatbot&#xff1a;聊天机器人组件1. API参数2.…

细说STM32F407单片机窗口看门狗WWDG的原理及使用方法

目录 一、窗口看门狗的工作原理 1、递减计数器 2、窗口值和比较器 3、看门狗的启动 4、提前唤醒中断 二、窗口看门狗的HAL驱动程序 1、窗口看门狗初始化 2.窗口看门狗刷新 3.EWI中断及其处理 三、不开启EWI的WWDG示例 1、示例功能 2、项目设置 &#xff08;1&…