详解全志R128 RTOS安全方案功能
介绍 R128 下安全方案的功能。安全完整的方案基于标准方案扩展,覆盖硬件安全、硬件加解密引擎、安全启动、安全系统、安全存储等方面。
配置文件相关
本文涉及到一些配置文件,在此进行说明。
env*.cfg配置文件路径:
board/<chip>/<board>/configs/env*.cfg
sys_config.fex路径:
board/<chip>/<board>/configs/sys_config.fex
image_header.cfg路径:
board/<chip>/<board>/configs/image_header.template.cfg
sys_partition*.fex路径:
board/<chip>/<board>/configs/sys_partition.fex
功能介绍
R128 FreeRTOS 系统上支持如下安全功能
安全硬件
下图是 ARM 为 M33 Star 提供的一种基于 TrustZone 的 SoC 架构参考实现
当 CPU 取指或者访问数据时,经过 SAU 与 IDAU 审查之后,携带安全属性,进入 AHB 总线。
由于 SAU/IDAU 机制只适用于 Arm M33 Star 处理器,那么 AHB 设备使用下列两种方法识别与应答这些携带安全属性的访问
- 第一种是外设在设计时就可以识别安全属性;
- 第二种需要借助其他控制器来实现,比如上图中的 PPC。开发人员设置 PPC 为不同的外设设置不同的访问规则。同理 MPC 则是用于设置存储器区域的安全属性。
R128 上有些外设可以识别安全属性,比如 CE、DMA 等。大部分外设需要借助 SPC 来配置其安全属性。其中的 PPC 对应 R128 上的 SPC,MPC 对应 R128 上的 SMC,TZMA
Arm M33 Star TrustZone 简介
Arm M33 Star TrustZone 与 Arm A 系列的 TrustZone 类似,在设计上,处理器都具有安全与非安全状态,非安全软件只能访问非安全内存。与 Arm A 处理器中的 TrustZone 技术不同, Arm M33 Star 的 Secure 和 Normal 世界是基于内存映射的,转换在异常处理中自动发生。
安全扩展功能
除了 ARM TrustZone 安全扩展功能外,R128 在 SoC 设计上还实现了一些安全硬件来保障完整的安全特性。
- SMC
SMC 配置 hspsram 存储区域的安全属性,只有在安全环境才可以使用该模块。
- TZMA
TZMA 用于配置 lspsram、sram、spi flash、dsp sram、csi&vad sram 地址空间的安全属性。
模块 | 大小 |
---|---|
TZMA0 | 128KB |
TZMA1 | 128KB |
TZMA2 | 256KB |
TZMA3 | 256KB |
DSP_TZMA0 | 256KB |
EXPSRAM_TZMA | 64KB |
LPSRAM_TZMA | 8MB |
FLASH_TZMA | 192MB |
- SPC
SPC 配置外设的安全属性,只有在安全环境才可以使用该模块
- CE
CE 是 AW SoC 的硬件加解密引擎,支持 AES/SHA/RSA 等算法。
- TRNG
TRNG 是真随机数发生器,随机源是 8 路独立的唤醒振荡器,由模拟器件电源噪声产生频率抖动,用低频时钟重采样,然后进行弹性抽取和熵提取处理,最终输出 128bit 真随机数。
- SID/efuse
efuse:一次性可编程熔丝技术,是一种 OTP(One‑Time Programmable,一次性可编程)存储器。efuse 内部数据只能从 0 变成 1,不能从 1 变成 0,只能写入一次。
Secure ID,控制 efuse 的访问。efuse 的访问只能通过 sid 模块进行。sid 本身非安全,安全非安全均可访问。但通过 sid 访问 efuse 时,安全的 efuse 只有安全世界才可以访问,非安全世界访问的结果为 0。
- Flash Encryption
Flash Encryption 模块向 Flash 写数据时计算 AES 进行加密,从 Flash 读出数据时进行解密。支持在 SBUS 读写数据和 CBUS 读操作时进行 AES 实时加解密。仅 Nor Flash 支持。
- Secure Timer and Watchdog
支持一套安全 Timer 与一套安全 Watchdog
硬件加解密引擎
CE:Crypto Engine,是 AW SoC 中一个硬件加解密模块,支持多种对称、非对称、摘要生成算法。包含安全/非安全两套接口。
CE 驱动支持算法如下,但 CE 硬件加密模块支持的加密算法不仅限下列算法。
算法 | 支持 |
---|---|
AES‑ECB‑128/192/256 | √ |
AES‑CBC‑128/192/256 | √ |
AES‑CTR‑128/192/256 | √ |
AES‑OFB‑128/192/256 | √ |
AES‑CFB8‑128/192/256 | √ |
HASH‑MD5 | √ |
HASH‑SHA1 | √ |
HASH‑SHA224 | √ |
HASH‑SHA256 | √ |
HASH‑SHA384 | √ |
HASH‑SHA512 | √ |
RSA‑512 | √ |
RSA‑1024 | √ |
RSA‑2048 | √ |
CE具体接口可以在 CE | R128 Documents 找到,TRNG可以在 TRNG | R128 Documents 找到,这里不过多赘述。
安全启动
安全固件构建
安全固件与非安全固件打包过程、封装格式类似,仅在原本非安全打包方式基础上,对每个镜像加入签名信息。
source envsetup.sh
lunch_rtos R128_xxx_m33
mrtos clean
mrtos_menuconfig # 开启CONFIG_COMPONENTS_TFM。注:非安全固件需关闭
mrtos
createkeys # 创建签名密钥,无需每次执行
pack ‑s # 打包安全固件
pack ‑s 打包完成后,生成安全固件,固件位于 out 目录下,文件名为rtos_freertos_{BOARD}_uart0_secure_[8|16]Mnor_v[NUM].img
。其中 v[NUM] 表示固件的版本信息,NUM 为版本号,由安全固件版本号(见4.7 节)决定。
在首次进行安全固件打包之前,必须运行一次 createkeys 创建自己的签名密钥,并将创建的秘钥妥善保存。每次执行 createkeys 后都会生成新的密钥,因此不用每次都执行,除非需要更换密钥。
安全固件配置
打包生成安全固件前,需确保 TFM 打开,在 M33 核执行 mrtos menuconfig 进入配置主界面,进行如下配置:
System components ‑‑‑>aw components ‑‑‑>TFM Support ‑‑‑>[*] TFM support
只有安全固件需要开始 TFM,非安全固件需要关闭,且仅有 M33 支持 TFM。
启动流程
R128 包含三个处理器,分别为 M33(ARM)、C906(RISC‑V)、HIFI5(DSP),仅 M33 支持安全隔离。
从安全性考虑,Brom 启动时,系统必须处于安全状态,因此,选择 M33 作为启动核。
R128 对于 nor 和 nand 方案采用不同的启动流程。对于 nor 方案,安全启动流程如下图所示。启动过程没有 uboot,由 boot0 直接启动安全和非安全 OS,其中 brom、boot0、S‑OS 位于安全域,M33 N‑OS、DSP OS、RISC‑V OS 位于非安全域。
对于 nand 方案,由于 nand 需要完整的 nand 驱动才能加载位于逻辑分区的数据,而 boot0 目前只有简单驱动,只能读取物理数据,uboot 有完整的驱动,才能读取逻辑数据。因此 nand 方案启动过程是由 boot0 启动 M33 S‑OS,再由 M33 S‑OS 启动 uboot,启动流程如下图所示。
校验流程
对于 Nor 方案来说,Brom 加载并校验 sboot,通过后,sboot 加载 M33 S‑OS、M33 N‑OS、RISC‑V OS、DSP OS,并对他们进行校验。所有校验处理都在安全域进行,保障了校验过程的安全性。
对于 nand 方案来说,Brom 加载并校验 Sboot,再由 Sboot 加载和校验 M33 S‑OS,最后 Uboot 对 M33 N‑OS、RISC‑V OS、DSP OS 进行加载和校验
签名校验
R128 支持两种签名校验,一种是软件 ECC‑256 算法,一种是硬件 SHA256‑RSA2048 算法,默认使用 SHA256‑RSA2048 算法。具体的签名校验方法配置在board/R128s2/pro/configs/image_header.template.cfg配置文件中,如下所示选择具体的签名校验算法:
"magic" : "AWIH",
"hversion" : "0.5",
"pversion" : "0",
"key_type" : "rsa", #rsa/ecc
"image" : {"max_size": "16384K"},
配置完签名算法 key_type 后,在创建密钥执行 createkeys 时会自动根据配置文件生成对应的密钥,并在执行打包命令的时候会采用对应的签名校验算法进行固件打包签名。
信任链
R128 整个安全启动过程中,以 efuse 中的根公钥 hash 为起点,通过层层校验,保障每一层固件在没有篡改的情况下正常运行。
在实现过程中,每一层可使用不同的签名密钥,充分保障了安全性。
烧写 rotpk.bin 与 secure enable bit
烧写 rotpk.bin 与 secure enable bit,主要包括以下几种方式:
- 使用 PhoenixSuit 烧写安全固件,安全固件烧写完毕时自动烧写 efuse 中的 secure enable bit 位。
- 通过 efuse 或 TFM 控制台命令将 rotpk.bin 烧写到设备的 efuse 中,具体操作方式见 5.5 节 TFM 使用示例。
-
在 烧 写 安 全 固 件 完 毕 时, 解 析 安 全 固 件 获 取 rotpk.bin 并 写 入 efuse, 然 后 再将 efuse 中 的 secure enable bit 置 1。(该 方 式 需 要 在 uboot 中 开 启 宏:CONFIG_SUNXI_BURN_ROTPK_ON_SPRITE=y)
-
对于 Nand 方案支持 Dragon SN 工具烧写 rotpk.bin 到设备的 efuse 中。
efuse 的硬件特性决定了 efuse 中每个 bit 仅能烧写一次。此外,efuse 中会划分出很多区域,大部分区域也只能烧写一次。详细请参考芯片 SID 规范。
烧写 secure enable bit 后,会让设备变成安全设备,此操作是不可逆的。后续将只能启动安全固件,启动不了非安全固件。
如果既烧写了 secure enable bit,又烧写了 rotpk.bin,设备就只能启动与 rotpk.bin 对应密钥签名的安全固件;如果只烧写 secure enable bit,没有烧写 rotpk.bin,此设备上烧写的任何安全固件都可以启动。调试时可只烧写 secure enable bit,但是设备出厂前必须要烧写 rotpk.bin。
防回退
R128 支持防止固件版本回退,打包过程中会根据配置文件image_header.template.cfg中的pversion 对应的版本信息加入到镜像的 Image Header 中。
在启动过程中,brom 在 sboot 校验之前,会读取 sboot 镜像 Image Header 中的版本信息,将该版本信息与 efuse 中 NV 区域保存的版本信息进行对比:
-
如果 efuse 中的版本信息高,不启动 sboot0,brom 转入 fel 烧写。
-
如果 efuse 的版本小于等于 Image Header 中的版本,继续加载 sboot 并校验。
sboot 启动过程中,如果发现 efuse 的版本小于 Image Header 中的版本,则将此版本信息写入到efuse 中的 NV 区域
安全固件最多支持更新 32 个版本。
安全量产方法
支持三种量产方式:
- 使用 LiveSuit/PhoenixSuit 烧写安全固件,在固件烧写完成时自动烧写 secure bit。启动之后,提供控制台命令方式烧写 rotpk。
- 离线安全固件量产方式,flash 上同时保存安全与非安全 boot0,第一次启动时,走非安全boot0,在非安全 boot0 中烧写 secure bit,重启;第二次启动时,走安全 boot0,进行正常的安全启动。rotpk 可以在非安全 boot0 中烧写,也可以在控制台中烧写。
- 对于 Nand 方案支持 Dragon SN 工具烧写 efuse,因此可以在使用 LiveSuit/PhoenixSuit 烧写安全固件时自动烧写 secure bit,启动后再通过 Dragon SN 工具烧写 rotpk
安全系统
软件系统架构
R128 系统中只有一份安全 OS,即运行在 M33 上的 S‑OS,其他 RISC‑V/DSP 如需访问安全资源,跨核调用到 M33 N‑OS,M33 N‑OS 再调用 S‑OS 的资源。
TFM
M33 Star 安全 OS 我们采用的 Arm 官方推出的 TF‑M(Trusted Firmware‑M),TF‑M 实现了ARMv8‑M 架构的 SPE(Secure Porcessing Environment),它是一种对标 PSA 认证的平台安全架构参考实现,方便 Chip、RTOS 与 Device 通过 PSA 认证。其软件框架如下图所示。
TF‑M 包含:
- 安全启动。用来来认证 NSPE/SPE 镜像的完整性。
- TF‑M Core。负责控制 SPE 与 NSPE 隔离、通信。
- 安全服务。包括 ITS(Internal Trusted Storage),PS(Protected Storage)等。
源码结构
供非安全环境调用的 TFM API 接口放置在 M33 rtos 下的components/aw/tfm目录下,安全 M33 RTOS 编译前配置上 CONFIG_COMPONENTS_TFM,即可将 NSC 相关 API编入到 M33 RTOS 镜像中。
TFM 接口
非安全端调用传入的非安全端 API 接口指针 pxCallback
函数原型
uint32_t tfm_sunxi_nsc_func(Callback_t pxCallback);
参数:
- pxCallback:非安全端 API 接口指针
返回值
- 该函数被调用的次数
调用说明: 该函数用于安全非安全交互测试,在非安全端调用该函数之后,会切换到安全端,该函数在安全端会调用传入的非安全端 API 接口指针。
按照给定的 key_name 将长度为 key_bit_len 的 key_data 烧写到对应的安全 efuse 区域
函数原型
int tfm_sunxi_efuse_write(char key_name, unsigned char key_data, unsigned int key_bit_len);
参数:
- key_name:efuse 对应的区域名
- key_data:待烧写到 efuse 中的数据
- key_bit_len:待烧写到 efuse 中数据的长度
返回值
- 0:成功
- 负数:失败
在安全端进行加解密操作
函数原型
int tfm_sunxi_aes_with_hardware(crypto_aes_req_ctx_t *aes_ctx);
参数:
- aes_ctx:crypto_aes_req_ctx_t 结构体指针
返回值
- 仅返回 0:无意义
调用说明: 调用之前,请注意对待加解密所需的数据密钥进行对应的 cache 操作
在安全端设置 flashenc 所需的 nonce 值
函数原型
void tfm_sunxi_flashenc_set_nonce(uint8_t *nonce);
参数:
- nonce:nonce 值,共 6 Bytes。
返回值
- 无
开启/关闭特定通道的 flashenc
函数原型
void tfm_sunxi_flashenc_enable(uint8_t id)/tfm_sunxi_flashenc_disable(uint8_t id);
参数:
- id:通道 index
返回值
- 无
设置 flashenc
函数原型
void tfm_sunxi_flashenc_config(uint8_t id, uint32_t saddr, uint32_t eaddr, uint32_t *key);
参数:
- id:通道 index
- saddr:设置的起始地址
- eaddr:设置的结束地址
- key:加密密钥
返回值
- 无
设置 flashenc 加密密钥
函数原型
void tfm_sunxi_flashenc_set_key(uint8_t id,uint32_t *key);
参数:
- id:通道 index
- 加密密钥
返回值
- 无
设置 flashenc 加密地址范围
函数原型
void tfm_sunxi_flashenc_set_region(uint8_t id, uint32_t saddr, uint32_t eaddr);
参数:
- id:通道 index
- saddr:设置的起始地址
- eaddr:设置的结束地址
返回值
- 无
设置 efuse 中的 ssk 作为 flashenc 的加密密钥
函数原型
void tfm_sunxi_flashenc_set_ssk_key(uint8_t id);
参数:
- id:通道 index
返回值
- 无
跳转到 tfm 安全空间利用 ssk 作为密钥进行 aes 加密
函数原型
void tfm_sunxi_aes_encrypt_with_hardware_ssk(uint8_t dst_addr, uint8_t src_addr, int len);
参数:
- dst_addr: 加密后数据存放地址
- src_addr: 加密数据存放地址
- len:加密数据长度
返回值
- 无
dump 出对应地址的值
函数原型
void tfm_sunxi_hexdump(const uint32_t *addr, uint32_t num);
参数:
- addr:起始地址
- num:dump 的 word 个数
返回值
- 无
打印出当前 sau 配置信息
函数原型
void tfm_sunxi_sau_info_printf(void);
参数:
- 无
返回值
- 无
读寄存器值
函数原型
uint32_t tfm_sunxi_readl(uint32_t reg);
参数:
- reg:寄存器地址
返回值
- 寄存器值
写寄存器值
函数原型
void tfm_sunxi_writel(uint32_t reg, uint32_t value);
参数:
- reg:待写的寄存器
- value:待写入的值
返回值
- 无
读取 efuse 内容
读取 efuse 内容函数原型
int tfm_sunxi_efuse_read(char key_name, unsigned char key_data, size_t key_bit_len);
参数:
- key_name:efuse 对应的区域名
- key_data:存放读取 efuse 的数据
- key_bit_len:读取数据的长度
返回值
- 负数:函数运行错误
- 正数:实际读取的 bit 数
TFM 开启配置
在 RTOS 环境下,M33 核执行 mrtos menuconfig 进入配置主界面,进行如下配置:
System components ‑‑‑>aw components ‑‑‑>TFM Support ‑‑‑>[*] TFM support #TFM驱动[*] TFM test demo #TFM测试代码
R128 中提供了四个TFM 的 测 试 demo, 包 括 tfm_demo、tfm_crypto_demo、tfm_efuse_write 和 tfm_efuse_read,分别用于测试安全非安全交互、非安全调用安全加密接口和对 efuse 内容进行读写(对 efuse 进行读写需要开启 efuse 驱动 DRIVERS_EFUSE)。
c906>rpccli arm tfm_demo
secure call 1 time, non‑secure call 1 time.
secure call 2 time, non‑secure call 2 time.
secure call 3 time, non‑secure call 3 time.
secure call 4 time, non‑secure call 4 time.
secure call 5 time, non‑secure call 5 time.
secure call 6 time, non‑secure call 6 time.
secure call 7 time, non‑secure call 7 time.
secure call 8 time, non‑secure call 8 time.
secure call 9 time, non‑secure call 9 time.
secure call 10 time, non‑secure call 10 time.c906>rpccli arm tfm_crypto_demo
tfm aes ecb test success!c906>rpccli arm tfm_efuse_write rotpk E2990EC8B001F2732EE5517739F52F6177E80AAEE220B5DBDA928BC5940FD025
#efuse中写入rotpk
key_hex_string: E2990EC8B001F2732EE5517739F52F6177E80AAEE220B5DBDA928BC5940FD025, buf_len: 64c906>rpccli arm tfm_efuse_read rotpk #efuse中读取rotpk
efuse [rotpk] data:
0x08133AA0: E2 99 0E C8 B0 01 F2 73 2E E5 51 77 39 F5 2F 61 |.......s..Qw9./a|
0x08133AB0: 77 E8 0A AE E2 20 B5 DB DA 92 8B C5 94 0F D0 25 |w.... .........%|
中提供的 TFM 接口和测试 demo 位于 lichee/rtos/components/aw/tfm
目录下。
相关文章:
详解全志R128 RTOS安全方案功能
介绍 R128 下安全方案的功能。安全完整的方案基于标准方案扩展,覆盖硬件安全、硬件加解密引擎、安全启动、安全系统、安全存储等方面。 配置文件相关 本文涉及到一些配置文件,在此进行说明。 env*.cfg配置文件路径: board/<chip>/&…...
【MySQL】WITH AS 用法以及 ROW_NUMBER 函数 和 自增ID 的巧用
力扣题 1、题目地址 601. 体育馆的人流量 2、模拟表 表:Stadium Column NameTypeidintvisit_datedatepeopleint visit_date 是该表中具有唯一值的列。每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people)每天只有…...
基于SpringBoot的在线考试系统源码和论文
网络的广泛应用给生活带来了十分的便利。所以把在线考试管理与现在网络相结合,利用java技术建设在线考试系统,实现在线考试的信息化管理。则对于进一步提高在线考试管理发展,丰富在线考试管理经验能起到不少的促进作用。 在线考试系统能够通…...
基于Spring Boot的美妆分享系统:打造个性化推荐、互动社区与智能决策
基于Spring Boot的美妆分享系统:打造个性化推荐、互动社区与智能决策 1. 项目介绍2. 管理员功能2.1 美妆管理2.2 页面管理2.3 链接管理2.4 评论管理2.5 用户管理2.6 公告管理 3. 用户功能3.1 登录注册3.2 分享商品3.3 问答3.4 我的分享3.5 我的收藏夹 4. 创新点4.1 …...
Axure医疗-住院板块,住院患者原型预览,新增医护人员原型预览,新增病房原型预览,选择床位原型预览,主治医生原型预览,主治医生医嘱原型预览
目录 一.医疗项目原型图-----住院板块 1.1 住院板块原型预览 1.2 新增住院患者原型预览 1.3 新增医护人员原型预览 1.4 新增病房原型预览 1.5 选择床位原型预览 1.6 主治医生原型预览 1.7 主治医生医嘱原型预览 1.8 主治医生查看患者报告原型预览 1.9 护士原型预…...
前端实战第一期:悬浮动画
悬浮动画 像这样的悬浮动画该怎么做,让我们按照以下步骤完成 步骤: 先把HTML内容做起来,用button属性创建一个按钮,按钮内写上悬浮效果 <button classbtn>悬浮动画</button>在style标签内设置样式,先设置盒子大小&…...
Python学习笔记(五)函数、异常处理
目录 函数 函数的参数与传递方式 异常处理 函数 函数是将代码封装起来,实现代码复用的目的 函数的命名规则——同变量命名规则: 不能中文、数字不能开头、不能使用空格、不能使用关键字 #最简单的定义函数 user_list[] def fun(): #定义一个函数&…...
Vue实现模糊查询
在Vue中实现模糊查询,你可以使用JavaScript的filter和includes方法,结合Vue的v-for指令。下面是一个简单的例子: 首先,你需要在你的Vue实例中定义一个数据数组和一个查询字符串。 data() { return { items: [Apple, Banana, Che…...
【十一】【C++\动态规划】1218. 最长定差子序列、873. 最长的斐波那契子序列的长度、1027. 最长等差数列,三道题目深度解析
动态规划 动态规划就像是解决问题的一种策略,它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题,并将每个小问题的解保存起来。这样,当我们需要解决原始问题的时候,我们就可以直接利…...
主板部件
▶1.主要部件 主板是计算机的重要部件,主板由集成电路芯片、电子元器件、电路系统、各种总线插座和接口组成,目前主板标准为ATX。主板的主要功能是传输各种电子信号,部分芯片负责初步处理一些外围数据。不同类型的CPU,需要不同主板与之匹配。…...
2023年度学习总结
想想大一刚开始在CSDN写作,这一坚持,就是我在CSDN的第九个年头,这也是在CSDN最有里程碑的一年,这一年我被评为CSDN的博客专家啦!先是被评为Unity开发领域新星创作者,写的关于一部分Unity开发的心得获得大家…...
服务器感染了.kann勒索病毒,如何确保数据文件完整恢复?
导言: 勒索病毒成为当前网络安全领域的一大威胁。.kann勒索病毒是其中的一种变种,对用户的数据造成了极大的威胁。本文91数据恢复将介绍.kann勒索病毒的特征、应对策略以及预防措施,以帮助用户更好地保护个人和组织的数据安全。当面对被勒索…...
使用results.csv文件数据绘制mAP对比图
yolov5每次train完成(如果没有中途退出)都会在run目录下生成expX目录(X代表生成结果次数 第一次训练完成生成exp0 第二次生成exp1…以此类推)。expX目录下会保存训练生成的weights以及result.txt文件,其中weights是训练…...
【算法刷题】## 算法题目第1讲:双指针处理数组题目 带视频讲解
算法题目第一讲:双指针处理数组题目 解决力扣: [344. 反转字符串][167. 两数之和 II - 输入有序数组][26. 删除有序数组中的重复项][27. 移除元素][283. 移动零][5. 最长回文子串] 配合b站视频讲解食用更佳:https://www.bilibili.com/video/BV1vW4y1P…...
达梦数据:数字化时代,国产数据库第一股终于到来?
又是新的一年开始。回首一年前的此时,在大家千呼万唤地期待中,数据基础制度体系的纲领性文件正式发布。 时隔一年之后,数据资源入表如约而至。2024年1月1日《企业数据资源相关会计处理暂行规定》正式施行,各行各业海量数据巨大的…...
selenium4.0中常见操作方式50条
前阵子升级了py3.9,一些常年陪伴的库也都做了升级,不少命令也更新了,适度更新一下记忆。 1. 打开浏览器:driver webdriver.Chrome() 2. 访问网址:driver.get("Example Domain") 3. 获取当前网址ÿ…...
如何解决使用融云音视频时由于库冲突导致编译不通过的问题
音视频库里面使用了一些第三方库,比如 openssl,libopencore-amrnb 等第三方库,如果集成的过程中遇到冲突可以尝试这样修改: 1、在 Build Settings 中 Other Linker Flags 中把 -all_load 去掉; 2、如果遇到 openssl 库…...
ISP 基础知识积累
Amber:现有工作必要的技术补充,认识需要不断深入,这个文档后续还会增加内容进行完善。 镜头成像资料 ——干货满满,看懂了这四篇文章,下面的问题基本都能解答 看完思考 1、ISP 是什么,有什么作用ÿ…...
Android Studio新手实战——深入学习Activity组件
目录 前言 一、Activity简介 二、任务栈相关概念 三、常用Flag 四、结束当前Activity 五、Intent跳转Activity 六、更多资源 前言 Android是目前全球最流行的移动操作系统之一,而Activity作为Android应用程序的四大组件之一,是Android应用程序的核…...
[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-10奈奎斯特稳定性判据-Nyquist Stability Criterion
本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-10奈奎斯特稳定性判据-Nyquist Stability Criterion Cauchy’s Argument Priciple 柯西幅角原理 结论: s s s平面内顺时针画一条闭合曲线 A A A, B B B曲…...
企业培训系统开发:构建灵活高效的学习平台
企业培训系统的开发在当今数字化时代是至关重要的。本文将介绍一些关键技术和代码示例,以帮助您构建一个灵活、高效的企业培训系统。 1. 技术选型 在开始企业培训系统的开发之前,首先需要选择合适的技术栈。以下是一个基本的技术选型示例:…...
2023秋电子科大信软 程算I 机考真题
基本情况 对应课程:程序设计与算法基础I 考试时间:2小时 题型:函数题编程题 函数题只需要完成期中一些(个)函数即可 编程题需要自己手动写main函数 提示:本次考试为全年级机考,分上下午场&am…...
Hive用户自定义函数之UDF开发
在进行大数据分析或者开发的时候,难免用到Hive进行数据查询分析,Hive内置很多函数,但是会有一部分需求需要自己开发,这个时候就需要自定义函数了,Hive的自定义函数开发非常方便,今天首先讲一下UDF的入门开发…...
Unity中URP下的线性雾
文章目录 前言一、线性雾 雾效因子二、MixFog1、ComputeFogIntensity 雾效强度计算2、雾效颜色混合 lerp(fogColor, fragColor, fogIntensity); 前言 在之前的文章中,我们实现了URP下的雾效支持。 Unity中URP下的添加雾效支持 在上一篇文章中,我们解析了 URP 下统…...
SpringBoot全局Controller返回值格式统一处理
一、Controller返回值格式统一 1、WebResult类 在 Controller对外提供服务的时候,我们都需要统一返回值格式。一般定义一个 WebResult类。 统一返回值(WebResult类)格式如下: {"success": true,"code": 2…...
程序媛的mac修炼手册-- 终端shell的驾驭 zsh vs bash
进入终端(Terminal)为新下载的应用配置环境,是Mac生产力up up的关键一步,更是编程小白装大神的第一步。Fake it till you make it , 硅谷大神标准路径~ shell的基本原理 为应用配置环境,相当于在应用和操作系统间架桥。由此&…...
基于PHP的校园代购商城系统
有需要请加文章底部Q哦 可远程调试 基于PHP的校园代购商城系统 一 介绍 此校园代购商城系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。(附带参考设计文档) 技术栈:phpmysqlbootstrapphpstudyvscode 二 功能 …...
感知与认知的碰撞,大模型时代的智能文档处理范式
目录 0 写在前面1 GPT4-V:拓宽文档认知边界2 大语言模型的文档感知缺陷3 大一统文档图像处理范式3.1 像素级OCR任务3.2 OCR大一统模型3.3 长文档理解与应用 4 总结抽奖福利 0 写在前面 由中国图象图形学学会青年工作委员会发起的第十九届中国图象图形学学会青年科学…...
ECMAScript和JavaScript的区别
ECMAScript和JavaScript之间的关系和差异可以从以下几个方面来理解: 定义: ECMAScript:ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)通…...
[BUG]Datax写入数据到psql报不能序列化特殊字符
1.问题描述 Datax从mongodb写入数据到psql报错如下 org.postgresql.util.PSQLException: ERROR: invalid bytesequence for encoding "UTF8": 0x002.原因分析 此为psql独有的错误,不能对特殊字符’/u0000’,进行序列化,需要将此特殊字符替…...
搭设企业网站教程/东莞哪种网站推广好
让我们来尝试一次深度匹配,在我们的模式匹配中检查对象的内容。//code-examples/Rounding/match-deep-script.scalacase class Person(name: String, age:Int) val alice new Person("Alice",25) val bob new Person("Bob",32) val charli…...
池州哪家做网站/北京培训seo哪个好
在通过java连接cassandra时,其中com.datastax.driver.core是通过maven加入的,通过Idea运行时是正常的,在导出jar时如果不是将所有的jar打包成一个jar时也是正常的,但是如果将所有的第三方打包成jar,则会出现如下错误&a…...
营销4p/南宁百度seo
Java字符串对象和常量池的总结 字符串对象 new 当执行String str1 new String("123");时,虚拟机会创建几个对象呢,答案是两个。 当一个字符串对象被new出来的时候,有两种情况: 当字符串常量池中已经有这个对象时&…...
wordpress 产品视频上传/app 推广
修改鼠标滚轮方向&配置MacBook触控板的多指快捷操作背景:问题描述:解决办法:参考链接:软件下载:几点经验:背景: 从 macOS 转到 windows 系统最不适应的就是鼠标的滚轮方向,用久了…...
网站设计中 查询怎么做/手机优化器
1准备工作 , 加载apicloud 海康视频模块。 引入 SDK 重新生成项目测试 再config.xml写入appid 话不多说直接上代码 videoapi.require("haikangVideo");video.open({ip:ip,port:port,channel:1,user:name,pwd:pwd,fixedOn: api.frameName,fixed: true,rect : {x : …...
建设中小企业网站/网络营销专业如何
but we cant use it unless you put visual studio in 64bit mode.最近装dlib时候遇到这个问题,很简单就能解决掉 Visual Studio用户通常应该以64位模式执行所有操作。默认情况下,Visual Studio是32位,在其输出和自己的执行中都是如此&…...