OpenHarmony底座升级指南(3.2升级4.0)

前言

本文旨在帮助开发者完成底座升级,文中主要以OpenHarmony 3.2 release 升级至OpenHarmony 4.0 release为模板描述。

一、流程概览:

1.1 准备工作

在准备阶段,需要完整收集所有的定制化修改,明确修改人;并且要将模块责任田细化明确,确保每个模块都有相应责任人。

1.2 切换阶段

在切换阶段,以编译构建与屏幕点亮的工作量最大,难度最高。

小版本(如4.0 beta切换至4.0 release)切换较为简单:可以在直接拉取社区4.0 release分支后,将在4.0 beta上的定制化修改一次性合入;解决合入冲突并且编译即可。

大版本(如3.2 release切换至4.0 release)切换相对复杂:需要在拉取社区4.0 release分之后,完成与点亮相关的几个关键仓库的修改与适配(kernel、device_xxx、vendor_xxx),并结合至新分支其他子系统,整编通过,实现点亮。所有其他子系统的定制化修改,需要再点亮完成后再进行。

  • 注意事项:关键仓的切换策略会影响整个基线切换进程和后期维护难度。通常来讲,有两种可行策略:1.使用当前产品化版本(3.2 release)中的关键仓库直接在4.0 release中进行替换;然后参考社区在4.0 release中的改动,进行接口适配。2.直接使用社区版本(4.0 release),并根据产品特性的修改记录,进行新一轮适配。

1.3 验证阶段

与常规项目类似,即开发自验证与测试验证,确保升级后的各功能质量。

二、编译问题处理

整体编译产品,执行编译命令后,处理编译报错问题。易现的编译问题:

1、未适配的产品模块容易出现编译报错。
2、新增的白名单规则导致的编译报错。
3、更严格的模块依赖规范导致的编译报错。
4、产品组件编译后并未安装到out下的产品目录导致运行错误。
5、更严格的语法检查规范容易导致语法检查错误。

2.1 屏蔽非点亮模块编译

在碰到编译中暂时无法解决的错误,如非产品点亮相关,可暂时屏蔽改模块的编译。

1、屏蔽产品组件,修改BUILD.gn文件,例如从group属性中删除某组件

文件路径:vendor/[manufacturerName]/产品名/modules/BUILD.gn

文件路径:vendor/[manufacturerName]/产品名/modules/BUILD.gngroup("modules") {deps = [":[manufacturerName]_wlan_combo",
#    ":sc2355_sdio_wlan",":[manufacturerName]bt_tty",":wifi_board_config",":bt_configure_pskey",":bt_configure_rf",":bt_configure_pskey_aa",":bt_configure_rf_aa",":wcnmodem",
#    ":gnssmodem",":build_modules",        
#    "wcn/bluetooth/hal:libbt_vendor",    //编译报错,从编译中屏蔽蓝牙模块":vpu",":nvt_nt36xxx_spi_ts",":novatek_ts_fw",":mali_kbase",

2、屏蔽产品部件,从ohos.build中删除产品部件,也可能需要在config.json中关联的productdefine中的产品配置中删除关联配置

文件路径:vendor/[manufacturerName]/[productName]/ohos.build
{"parts": {"product_[productName]": {"module_list": ["//device/board/[manufacturerName]/[productName]:[productName]_group",...]},
#################可从该文件中删除modem、radio部件等不影响亮屏的部件##################    
#    "modem":{
#      "module_list": [
#        "//vendor/[manufacturerName]/[productName]/modem:modem"
#      ]
#    },
#    "radio":{
#      "module_list": [
#        "//vendor/[manufacturerName]/[productName]/telephony:radio"
#      ]
#    }
#  },
#####################################################################################"subsystem": "product_[productName]"
}

2.2 白名单问题处理

开发者手机项目中以前用的代码底座是3.2release的,当前要切换社区4.0release的代码位底座,切换后,新增的部分代码报了很多依赖错误,未改动的模块也报了很多依赖问题,如:

2.2.1. 对于未改动的模块报的依赖错误

已确定不影响当前功能,没必要改,可待后续代码升级时自动修复;若需修改,可参考下面的修改方法

2.2.2 对于开发手机修改或添加的相关代码的依赖报错
2.2.2.1 修改适配位置//device/soc
  1. 当前适配了新芯片,位置在//device/soc/[manufacturerName]/[productName]/hardware,可在//build/subsystem_config.json添加新子系统的配置如:
  "soc_[manufacturerName]": {"path": "device/soc/[manufacturerName]/[productName]/hardware","name": "soc_[productName]"}

其中,soc_[manufacturerName]代表子系统名称,soc_[productName]代表部件名称

  1. 在device/soc/[manufacturerName]/[productName]/hardware目录下,没特殊情况时各gni,gn文件中配置的子系统名称,部件名称改为上一步配置的名称,如:
  subsystem_name = "soc_[manufacturerName]"part_name = "soc_[productName]"
  1. 新增部件(一个部件只能属于一个子系统)定义文件//device/soc/[manufacturerName]/[productName]/hardware/bundle.json
{"name": "@ohos/soc_[productName]","description": "device [productName] soc components","homePage": "","version": "3.1","license": "Apache License 2.0","repository": "","publishAs": "code-segment","segment": {"destPath": "device/soc/[manufacturerName]/[productName]/hardware"},"dirs": {},"scripts": {},"component": {"name": "soc_[productName]","subsystem": "soc_[manufacturerName]","syscap": [],"adapted_system_type": ["standard"   //适配标准系统],"rom": "","ram": "","hisysevent_config": [],"deps": {"components": [ //各子组件依赖的库,依据gn文件中的external_deps,deps数据"hilog","graphic_2d",...],"third_party": [ //第三方依赖"libdrm"]},"build": {"sub_component": [ //要参与编译的子组件,有的是group,group下可能再包含group,只需添加最上层grou即可"//device/soc/[manufacturerName]/[productName]/hardware:hardware_group","//device/soc/[manufacturerName]/[productName]/hardware/aosp/hardware/interfaces/graphics/common:common-impl","//device/soc/[manufacturerName]/[productName]/hardware/omx_il:lib_omx"],"inner_kits": [ //如果其他部件有依赖本部件(soc_[productName])中的子组件,如动态库等,需要在此添加如下配置,外部才能引用;----注意:如果外部未引用,而在此添加本部件中的某组件,会导致此组件异常。{"header": {"header_base": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libdmabufheap/include","header_files": ["BufferAllocator/BufferAllocator.h","BufferAllocator/BufferAllocatorWrapper.h","BufferAllocator/dmabufheap-defs.h"]},"name": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libdmabufheap:libaosp_dmabufheap"},...{"header": {"header_base": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libmemion/include","header_files": ["C2UnisocDmaBuffer.h","dmaphyaddr-defs.h","VideoMemAllocator.h"]},"name": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libmemion:libmemion"}],"test": []}}
}
  1. 添加//device/soc/[manufacturerName]/[productName]/hardware/ohos.build文件,定义子系统包含的部件,编译入口配置文件
{"subsystem": "soc_[manufacturerName]", //子系统名"parts": {"soc_[productName]": {    //部件名称"module_list": [ //部件包含模块的gn目标"//device/soc/[manufacturerName]/[productName]/hardware:hardware_group","//device/soc/[manufacturerName]/[productName]/hardware/omx_il:lib_omx"]}}
}
2.2.2.2 修改适配位置//device/board
  1. 修改//device/board/[manufacturerName]/[productName]/BUILD.gn,去掉group(“[productName]_group”)下deps中的//device/soc/[manufacturerName]/[productName]/hardware:hardware_group,此编译目标已在上一步定义过,此处不在需要;

  2. 添加//device/board/[manufacturerName]/[productName]/bundle.json部件定义文件(以前没这个文件,当前版本代码不添加这个文件的话,如gn文件中用到了init组件,不在bundle.json中deps下添加的话会报错)

  {"name": "@ohos/device_[productName]","description": "device board","version": 3.2,"license": "Apache License 2.0","publishAs": "code-segment","segment": {"destPath": "device/board/[manufacturerName]/[productName]"},"dirs": {},"scripts": {},"component": {"name": "device_[productName]","subsystem": "device_[productName]","syscap": [],"features": [],"adapted_system_type": [ "standard" ],"hisysevent_config": [],"rom": "","ram": "","deps": {"components": ["init"    //当前部件中gn文件用到了init组件],"third_party": []},"build": {"sub_component": ["//device/board/[manufacturerName]/[productName]:[productName]_group"],"test": []}}}
  1. 根据上一步定义的子系统名和部件名device_[productName],修改本部件下各gn中的子系统名和部件名的相关配置

  2. 修改//device/board/[manufacturerName]/[productName]/ohos.build

{"subsystem": "device_[productName]","parts": {"device_[productName]": {"module_list": [ // ${product_name} 当前就是[productName]"//device/board/[manufacturerName]/${product_name}:[productName]_group"  //改前为"//device/soc/[manufacturerName]/${product_name}/hardware:hardware_group",此模块在前几步已配置],"test_list": ["//kernel/linux/build/test:linuxkerneltest"]}}
}
2.2.2.3 修改适配位置vendor
  1. 修改//vendor/[manufacturerName]/[productName]/ohos.build, 去掉module_list下的"//device/board/[manufacturerName]/ p r o d u c t _ n a m e : {product\_name}: product_name:{product_name}_group", 因为前面已配置

  2. 添加//vendor/[manufacturerName]/[productName]/bundle.json,参考前面的方法添加即可

  3. 修改外部依赖错误(编译时这种错误依赖会报错,可以在发现报错时再改,可能是外部依赖放到了deps,也可能内部依赖放到了external_deps中),如下图所示:

  1. 修改部件名称错误,如把不属于此子系统的部件名,配置为了编译目标的部件名,也可在编译报错时再找到对应位置修改

  2. 修改//vendor/[manufacturerName]/[productName]/config.json,添加上诉步骤中新增的子系统,如:

    {"subsystem": "soc_[manufacturerName]","components": [{"component": "soc_[productName]","features": []}]}
  1. 修改//vendor/[manufacturerName]/[productName]/modules/BUILD.gn中相关子系统名称和部件名称
    因为此文件中相关编译目标所属的group(“modules”)在//device/board/[manufacturerName]/[productName]/BUILD.gn中定义(“//vendor/[manufacturerName]/[productName]/modules:modules”)。
    为何此时,vendor下的子系统名部件名没有配置为product_[productName]也没有报依赖错误?因为此时gn文件中用的是ohos_prebuilt_executable这种,只是用来拷贝文件
2.2.3 临时屏蔽依赖报错,绕过依赖检查,继续编译
        ...else:raise Exception(_warning_info)

和check_part_deps()和check()函数中的抛异常语句:

        ...else:raise Exception(message)
  1. 在//build/templates/common/check_external_deps.py 中注释掉check_parts_deps() 函数中的两个抛异常语句

  2. 在//build/templates/common/check_part_subsystem_name.py 中注释掉check()函数第二个抛异常语句

  3. 此方法只能临时使用,后续其他模块的依赖错误或依赖不规范问题也是需要整改的

2.3 基于4.0的模块依赖规范的修改:

1、部件编译文件BUILD.gn中使用的外部依赖(非本部件中的组件)不可放在deps属性中,需移到external_deps中

   external_deps = ["c_utils:utils","graphic_chipsetsdk:surface","hdf_core:libhdf_host","hdf_core:libhdf_ipc_adapter","hdf_core:libhdf_utils","hdf_core:libhdi","hilog:libhilog","ipc:ipc_single",]

2、device下产品部件配置文件bundle.json中需添加依赖的系统部件到components下

    "component": {"name": "device_[productName]","subsystem": "device_[productName]","syscap": [],"features": [],"adapted_system_type": [ "standard" ],"hisysevent_config": [],"rom": "","ram": "","deps": {"components": ["init","c_utils","hilog"],"third_party": []},"build": {"sub_component": ["//device/board/[manufacturerName]/[productName]:[productName]_group"],"test": []}}}

2.4 产品仓模块编译配置修改

产品仓模块编译后没有安装到对应的产品目录,需确认:

1、 确认模块编译文件BUILD.gn,将部件名和子系统名改为产品目录对应的部件名和子系统名

产品路径:device/board/产品名/camera/vdi_impl/v4l2/BUILD.gn

产品路径:device/board/产品名/camera/vdi_impl/v4l2/BUILD.gnohos_shared_library("camera_host_vdi_impl_1.0") {...install_enable = truepart_name = "device_laphone"        //这里改为产品部件名subsystem_name = "device_laphone"    //这里改为产品子系统名
}group("camera_board_vdi_impl") {    //包含在groupdeps = [":camera_host_vdi_impl_1.0",":chipset_build",]
}group("[productName]_group") {deps = [..."//device/board/[manufacturerName]/[productName]/camera/vdi_impl/v4l2:camera_board_vdi_impl",    //group被包含在另一个group"//third_party/alsa-lib:libasound","//third_party/alsa-utils:alsa-utils",]if (is_standard_system) {deps += [ "startup/reboot_loader:rebootloader" ]}
}

2、确认vendor下产品的ohos.build的配置是否关联了该模块的编译

文件路径:device/board/[manufacturerName]/***/bundle.json..."component": {"name": "device_[productName]","subsystem": "device_[productName]","syscap": [],"features": [],"adapted_system_type": [ "standard" ],"hisysevent_config": [],"rom": "","ram": "","deps": {"components": ["init","c_utils","hilog"],"third_party": []},"build": {"sub_component": ["//device/board/[manufacturerName]/[productName]:[productName]_group"    //包含了上1、中的group],"test": []}}}
  1. feature配置问题:

vendor产品config.json中的feature特性名变更导致的报错,需要确认gni头文件中的变量是否一致。

文件:vendor/[manufacturerName]/产品名/config.json{"subsystem": "hdf","components": [{"component": "drivers_interface_audio","features": []},{"component": "drivers_peripheral_audio","features": ["drivers_peripheral_audio_feature_full_test_suite = true","drivers_peripheral_audio_feature_alsa_lib = true"]},{"component": "drivers_peripheral_codec","features": []}]}feature对应gni头文件:drivers/peripheral/audio/audio.gni
declare_args() {drivers_peripheral_audio_feature_mono_to_stereo = falsedrivers_peripheral_audio_feature_hal_notsupport_pathselect = falsedrivers_peripheral_audio_feature_hdf_proxy_stub = truedrivers_peripheral_audio_feature_user_mode = falsedrivers_peripheral_audio_feature_full_test_suite = falsedrivers_peripheral_audio_feature_policy_config = truedrivers_peripheral_audio_feature_alsa_lib = truedrivers_peripheral_audio_feature_rich_device = falsedrivers_peripheral_audio_feature_community = truedrivers_peripheral_audio_feature_effect = false
}

2.5 解决部分编译报错问题

语法问题导致的编译警告报错:

1、未使用的临时变量,执行语法屏蔽或删除操作;

2、c代码中定义的无参函数需增加默认参数void;

​ 其他代码也要按语法规范书写,要么通过cflags,cflags_c,cflags_cc等属性添加-Wnoerror类参数屏蔽警告错误。

​ 针对c++使用cflags、cflags_cc 参考:

  cflags_cc = ["-Wall","-Wextra","-Werror","-Wno-error","-DGST_DISABLE_DEPRECATED","-DHAVE_CONFIG_H","-DCOLORSPACE=\"videoconvert\"","-fno-strict-aliasing","-Wno-sign-compare","-Wno-builtin-requires-header","-Wno-unused-variable","-Wno-unused-label","-Wno-implicit-function-declaration","-Wno-format","-Wno-int-conversion","-Wno-unused-function","-Wno-thread-safety-attributes","-Wno-inconsistent-missing-override","-fno-rtti","-fno-exceptions","-ffunction-sections","-fdata-sections",]

针对c使用cflags_c参考:

  cflags_c = ["-Wall","-Wextra","-Werror","-Wno-predefined-identifier-outside-function","-Wno-macro-redefined","-Wno-format","-Wno-unused-parameter","-Wno-unused-variable","-fsigned-char","-fno-common","-fno-strict-aliasing",]

三、屏幕点亮

4.0相对于3.2,在OpenHarmony 4.0图形HDI基础适配及点屏上存在较大差异,所以应先了解差异点再进行点亮。

3.1 进程调用关系变化

3.1.1 进程数量变化

新增加两个uhdf进程。allocator_host进程及composer_host进程。

删除了disp_gralloc_host 进程,并使用allocator_host替换。

uhdf添加进程配置如下:

display_composer :: host {hostName = "composer_host";priority = 40;processPriority = -8;threadPriority = 1;caps = ["SYS_NICE"];uid = ["composer_host"];gid = ["composer_host", "graphics", "vendor_mpp_driver"];composer_device :: device {device0 :: deviceNode {policy = 2;priority = 160;moduleName = "libdisplay_composer_driver_1.0.z.so";serviceName = "display_composer_service";}}
}
allocator :: host {hostName = "allocator_host";priority = 40;allocator_device :: device {device0 :: deviceNode {policy = 2;priority = 160;moduleName = "liballocator_driver_1.0.z.so";serviceName = "allocator_service";}}
}
3.1.2 拉起关系变化
  • composer

以前版本composer由render_service通过单例拉起,现在通过composer service拉起接口实现层libdisplay_composer_vdi_impl.z.so,对外提供标准的IPC服务.

  • allocator

进程名字由disp_gralloc_host变更成allocator_host。通过allocator_service拉起接口实现层libdisplay_buffer_vdi_impl.z.so,对外提供标准的IPC服务。

3.2 接口协议更新

3.2.1 接口更新

结构体定义由原来的.h变为接口描述语言IDL代替,在协议升级过程中,会遇到大量结构体命名空间不一样的冲突,总体解决思路就是去掉原有的.h头文件依赖,增加新的接口头文件即可。

  • allocator_host

    头文件更新:由display_type.h 更新成v1_0/display_buffer_type.h。由DisplayBufferType.idl生成在out下

    接口协议更新:

    由原来的display_gralloc.cpp中提供的接口更换成OHOS::HDI::Display::Buffer::V1_0::IDisplayBufferVdi,并新建接口实现文件:

    display_buffer_vdi_impl.cpp/.h。

    参考drivers/peripheral/display/hal/default_standard/src/display_gralloc/display_buffer_vdi_impl.cpp中的接口,并按自己的实际情况完成实现。

  • composer_host

    头文件更新:由display_type.h 更新成v1_0/display_composer_type.h。由DisplayComposerType.idl生成在out下

    由原来的hdi_session.cpp中提供的接口更换成OHOS::HDI::Display::Composer::V1_0::IDisplayComposerVdi,并新建接口实现文件:

    display_composer_vdi_impl.cpp/.h

    参考drivers/peripheral/display/hal/default_standard/src/display_device/display_composer_vdi_impl.cpp中的接口,并按自己的实际情况完成实现。

3.2.2 其它头文件更新
  • BufferHandle

新结构体去掉了key,如果代码中有用到,需要让以下定义保持一致:

drivers/hdf_core/interfaces/inner_api/hdi/base/buffer_handle.h
drivers/peripheral/base/buffer_handle.h
foundation/graphic/graphic_2d/frameworks/surface/include/buffer_handle.h
  • 其它头文件:

drivers/peripheral/display/interfaces/include下的头文件与device_type.h有关联。要解耦,不要使用。

3.3 开机动画

在4.0中,开机动画默认使用的是播放视频,对点屏不友好,建议修改成原图片播放方式,修改方法如下:

frameworks/bootanimation/include/boot_animationconfig.h

@@ -33,7 +33,7 @@ public:bool IsBootVideoEnabled();
private:BootCustomConfig custConfig_;
-   bool bootVideoEnabled_ = true;
+   bool bootVideoEnabled_ = false; //不使用视频开机动画模式
};
} // namespace OHOS

3.4 hello_composer编译报错

合入如下修改解决:

diff --git a/rosen/samples/composer/hello_composer.cpp b/rosen/samples/composer/hello_composer.cpp
index a907af7db..520da2e38 100644
--- a/rosen/samples/composer/hello_composer.cpp
+++ b/rosen/samples/composer/hello_composer.cpp
@@ -74,7 +74,7 @@ void HelloComposer::Run(const std::vector<std::string> &runArgs)sleep(1);std::shared_ptr<OHOS::AppExecFwk::EventRunner> runner = OHOS::AppExecFwk::EventRunner::Create(false);mainThreadHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
-    g_receiver = new VSyncReceiver(vsyncConnection, mainThreadHandler_);
+    g_receiver = new VSyncReceiver(vsyncConnection, nullptr, mainThreadHandler_);g_receiver->Init();mainThreadHandler_->PostTask(std::bind(&HelloComposer::RequestSync, this));runner->Run();
@@ -473,6 +473,7 @@ void HelloComposer::DoPrepareCompleted(sptr<Surface> surface, const struct PrepaclientCount++;}}
+    LOGI("clientCount:%{public}d");auto addr = static_cast<uint8_t *>(fbBuffer->GetVirAddr());if (hasClient) {

3.5 问题列举

本次实战主要是把产品从3.2.3-Release升级到4.0-Release。中间看到这些变化,心里有点慌,从而记录下来,并提供给大家参考。框架上遇到的一些问题,前面几节已经给大家说明了,以下是一些升级的步骤及建议。

1、添加接口协议文件、gn编译、hcs配置。

为composer添加display_composer_vdi_impl.cpp/.h

为gralloc添加display_buffer_vdi_impl.cpp/.h。

在gn中添加目标libdisplay_composer_vdi_impl和libdisplay_buffer_vdi_impl。

在device_info.hcs中添加进程配置。

2、编译修改。

这个是工作量比较大的地方。原则上就是去掉drivers/peripheral/display/interfaces/include下的头文件依赖,并添加

#include “v1_0/display_composer_type.h”

 #include "v1_0/display_buffer_type.h"

以及命名空间:

using namespace OHOS::HDI::Display::Composer::V1_0;

using namespace OHOS::HDI::Display::Buffer::V1_0;

当然gn中也要添加相应的依赖。

3、调试。

主要使用hello_composer调试,关注hdi_backend.cpp中Repaint函数执行流程,并在hilog中搜索关键命令字:REQUEST_CMD,一个完整的流程必须包含以下命令:

REQUEST_CMD_PREPARE_DISPAY_LATERS
REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE
REQUEST_CMD_SET_DISPLAY_CLENT_BUFFER
REQUEST_CMD_COMMIT

如果so没有正常加载,也可以在以下文件中添加打印:

drivers/peripheral/display/buffer/hdi_service/src/allocator_service.cpp
drivers/peripheral/display/composer/hdi_service/src/display_composer_service.cpp

可以为dlopen添加详细错误信息,默认没有添加:

if (libHandle_ == NULL) {error = dlerror();DISPLAY_LOGE("composer load path%{public}s, dlopen err=%{public}s", DISPLAY_COMPOSER_VDI_LIBRARY, error);return HDF_FAILURE;}

四、合入其他模块修改

其他模块的合入,需要各个责任田单独负责。后续将有关于audio与camera相关的升级指导。

为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (Harmony OS)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. ……

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门?:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

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

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

相关文章

嵌入式项目——平衡小车(1)

焊接 驱动板需要焊接的如上图。 陀螺仪8pin排母电机两路排线插口。(个别同学需要焊接)两个电池仓,注意电池仓分正反。 安装 底部电池板 4个 双通尼龙柱M3*224个 尼龙螺钉M3*6电机驱动板

【算法笔记】深入理解dfs(两道dp题)

DFS过程的概述 一个一个节点的搜&#xff0c;如果是树状结构的话&#xff0c;先找到最左边那一条分支搜到最后一个节点&#xff0c;这个时候最后一个节点&#xff08;假设是b&#xff09;的数据会被更新&#xff08;具体看题目的要求&#xff09;&#xff0c;然后返回到上一个…

【计算机图形学】NAP: Neural 3D Articulation Prior

文章目录 1. 这篇论文做了什么事&#xff0c;有什么贡献&#xff1f;2. Related Work铰接物体建模3D中的Diffusion model扩散模型 3. Pipeline铰接树参数化基于Diffusion的铰接树生成去噪网络 4. 实验评价铰接物体生成——以往做法与本文提出的新指标NAP捕捉到的铰接物体分布质…

玩转Mysql 四(MySQL逻辑架构与数据引擎)

一路走来&#xff0c;所有遇到的人&#xff0c;帮助过我的、伤害过我的都是朋友&#xff0c;没有一个是敌人。 一、MySQL逻辑架构 1、从Oracle收购MySQL后&#xff0c;MySQL逻辑架构受Oracle影响&#xff0c;MySQL8版本中逻辑架构受Oracle的影响逐步完善查询缓存&#xff0c;O…

数据结构:树详解

创建二叉树 给出了完整的先序遍历序列&#xff0c;子树为空用’#’表示&#xff0c;所以这样我们在通过先序遍历序列创建二叉树时我们直到先序遍历序列是先进行根结点&#xff0c;然后左子树最后右子树的顺序进行遍历的&#xff0c;所以对于完整的先序遍历序列我们可以直到先序…

VS code的使用介绍

VS code的使用介绍 简介下载和安装常用的插件使用教程快捷键 集成Git未找到 Git。请安装 Git&#xff0c;或在 "git.path" 设置中配置。操作步骤打开文件夹初始化仓库文件版本控制状态提交文件到git打开git操作栏位 好用的插件ChineseDraw.io Integration实体关系 Gi…

Windows电脑无法睡眠解决办法

原因 电脑无法休眠的原因&#xff0c;是打开离开模式策略后&#xff0c;windows内核会持续调用CPU资源&#xff0c;导致系统一直在运行而无法关闭。关闭后就好了。 解决步骤 修改注册表 操作步骤如下: 按winR&#xff0c;输入regedit&#xff0c;打开注册表编辑页面。输入如下…

YOLOv5+混合注意力机制再涨4.3%,Transformer混合设计依旧可以卷

在工业生产过程中&#xff0c;由于低效率、不统一的评估、高成本以及缺乏实时数据&#xff0c;传统的手动检测焊接缺陷不再被应用。 为了解决表面贴装技术中焊接缺陷检测的低准确率、高误检率和计算成本问题&#xff0c;提出了一种新方法。该方法是一种专门针对焊接缺陷检测算法…

STM32入门教程-2023版【3-2】STM32如何使用库函数及几种方法

关注 点赞 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 五、库函数的使用方法 &#xff08;1&#xff09;第一种 想使用库函数&#xff0c;可以先打开.h文件&…

Nginx快速入门:worker、master进程的作用和热部署原理(十)

0. 引言 我们通过查询nginx进程&#xff0c;可以发现nginx有两个进程&#xff1a;worker和master。一个程序启动了两个进程&#xff0c;那么这两个进程的作用和区别是什么呢&#xff1f;nginx又是如何利用这两个进程进行工作的呢&#xff1f;nginx不停机热部署又是如何实现的&…

12月笔记

#pragma once 防止多次引用头文件&#xff0c;保证同一个&#xff08;物理意义上&#xff09;文件被多次包含&#xff0c;内容相同的两个文件同样会被包含。 头文件.h与无.h的文件&#xff1a; iostream是C的头文件&#xff0c;iostream.h是C的头文件&#xff0c;即标准的C头文…

一个H3C交换机周期性断网并自动恢复的排查案例

一个朋友发我一个H3C日志&#xff0c;这个交换机是汇聚层交换机&#xff0c;1和2口是trunk口&#xff0c;其它接口是access接口&#xff0c;17-21口据说接的都是监控、终端。日志里面看到大量的拓朴改变&#xff0c;好几个网口up、down的日志&#xff0c;怀疑是环路&#xff0c…

Linux操作系统基础 – 管理目录

Linux操作系统基础 – 管理目录 Linux Essentials – Manage Directories By JacksonML 本文简要介绍在Linux系统中如何管理目录的方法及实例&#xff0c;希望对您有所帮助。 1. Linux目录 一个目录&#xff0c;是一个存储文件名及相关信息的单独工作的文件。所有的文件&am…

SpringBoot学习(七)-SpringBoot集成Swagger

集成Swagger终极版 学习目标&#xff1a; 了解Swagger的概念及作用掌握在项目中集成Swagger自动生成API文档 Swagger简介 前后端分离 前端 -> 前端控制层、视图层后端 -> 后端控制层、服务层、数据访问层前后端通过API进行交互前后端相对独立且松耦合 产生的问题 前…

Qt——TCP UDP网络编程

目录 前言正文一、TCP二、UDP1、基本流程2、必备知识 三、代码层级1、UDP服务端 END、总结的知识与问题1、如何获取QByteArray中某一字节的数据&#xff0c;并将其转为十进制&#xff1f;2、如何以本年本月本日为基础&#xff0c;获取时间戳&#xff0c;而不以1970为基础&#…

Docker-Compose部署Redis(v7.2)分片集群(含主从)

文章目录 一、前提准备1. 文件夹结构 二、配置文件1. redis.conf2. docker-compose文件 三、构建集群1. 自动分配主从关系2.1 构建3 master集群2.2 手动配置从节点 四、测试1. 集群结构2. 分片测试 环境 docker desktop for windows 4.23.0redis 7.2 目标 搭建如下图分片主从…

基于Kettle开发的web版数据集成开源工具(data-integration)-应用篇

目录 &#x1f4da;第一章 基本流程梳理&#x1f4d7;页面基本操作&#x1f4d7;对应后台服务流程 &#x1f4da;第二章 二开思路&#x1f4d7;前端&#x1f4d7;后端&#x1f4d7;后续补充&#xff1a;[Kettle Local引擎源码使用记录](https://renxiaozhao.blog.csdn.net/arti…

简单工厂模式、工厂方法、抽象工厂模式

下面例子中鼠标&#xff0c;键盘&#xff0c;耳麦为产品&#xff0c;惠普&#xff0c;戴尔为工厂。 简单工厂模式 简单工厂模式不是 23 种里的一种&#xff0c;简而言之&#xff0c;就是有一个专门生产某个产品的类。 比如下图中的鼠标工厂&#xff0c;专业生产鼠标&#xf…

STM32 JLINK SWD调试器手动复位才能烧写的问题

STM32 JLINK SWD调试器手动复位才能烧写的问题 Chapter1 STM32 JLINK SWD调试器手动复位才能烧写的问题 Chapter1 STM32 JLINK SWD调试器手动复位才能烧写的问题 原文链接&#xff1a;https://blog.csdn.net/denghuajing/article/details/121649667 问题 只有手动复位的情况下…

B059-权限管理系统01

目录 知识点介绍项目演示项目搭建动态菜单查询分析(权限表分析)权限系统表分析角色模块pageInfopageHelper实现前端动态分页高级查询新增与修改删除角色 分配权限-表分析角色授权数据-一级和二级权限查询 知识点介绍 项目演示 准备数据库 准备工程auth_new tips&#xff1a;…