使用 release key 对 LineageOS 进行编译和签名

news2024/12/26 7:50:36

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

为什么需要使用 release key

test-key 是一个公开的、众所周知的开发测试密钥,广泛用于测试阶段。这意味着任何人都可以获取这个密钥,并用它签署自己修改的 APK 或系统文件。

使用 test-key 签署的系统镜像通常无法通过 Google 的 CTS(兼容性测试套件)认证,Google Play 商店、Google 服务框架等应用可能无法正常运行,某些第三方应用(例如银行应用或数字版权管理应用)也可能拒绝在设备上运行。

OTA 更新包必须使用 Release Key 来签名。签名的更新包经过验证,只有具有相同 Release Key 的设备才能接收和安装更新。

image.png

生成 release key

执行 nano make_keys.sh 创建脚本,内容如下

subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=linchaolong.dev@gmail.com'

# 创建 keys 目录(如果不存在)
mkdir -p keys

for cert in bluetooth cyngn-app media networkstack nfc platform releasekey sdk_sandbox shared testcert testkey verity; do \
    ./development/tools/make_key keys/$cert "$subject"; \
done

通过脚本创建 keys 目录并使用 make_key 命令生成你自己的密钥。

运行脚本生成密钥文件。

# 添加执行权限
chmod +x make_keys.sh
# 运行脚本
./make_keys.sh

为了避免密码解密的复杂性,生成一个未加密的私钥,防止签名过程提示输入密码。

Enter password for 'keys/bluetooth' (blank for none; password will be visible):
creating keys/bluetooth.pk8 with no password



Enter password for 'keys/cyngn-app' (blank for none; password will be visible): 
creating keys/cyngn-app.pk8 with no password

Enter password for 'keys/media' (blank for none; password will be visible):
creating keys/media.pk8 with no password

Enter password for 'keys/networkstack' (blank for none; password will be visible):
creating keys/networkstack.pk8 with no password

Enter password for 'keys/nfc' (blank for none; password will be visible):
creating keys/nfc.pk8 with no password

Enter password for 'keys/platform' (blank for none; password will be visible):
creating keys/platform.pk8 with no password

Enter password for 'keys/releasekey' (blank for none; password will be visible):
creating keys/releasekey.pk8 with no password

Enter password for 'keys/sdk_sandbox' (blank for none; password will be visible):
creating keys/sdk_sandbox.pk8 with no password

Enter password for 'keys/shared' (blank for none; password will be visible):
creating keys/shared.pk8 with no password

Enter password for 'keys/testcert' (blank for none; password will be visible):
creating keys/testcert.pk8 with no password

Enter password for 'keys/testkey' (blank for none; password will be visible):
creating keys/testkey.pk8 with no password

Enter password for 'keys/verity' (blank for none; password will be visible):
creating keys/verity.pk8 with no password

生成的密钥都在 keys 目录下,每条命令会生成两个文件:一个 .x509.pem 公钥证书文件和一个 .pk8 私钥文件:

  • releasekey:主要用于签署系统中的所有 APK 文件,确保这些 APK 来自可信任的来源。

  • platform:签署系统框架和其他核心组件,确保这些组件未被篡改。

  • shared:用于签署需要跨应用共享 UID 的 APK,例如具有相同签名的应用可以共享数据。

  • media:专门用于签署与多媒体相关的 APK 文件。

  • networkstack:用于签署与网络堆栈相关的组件和应用,确保网络功能的安全性。

  • testkey:这是 Android 系统中的默认密钥,主要用于开发和测试环境下的签名,但不应在生产环境中使用。

  • cyngn-priv-app:可能与 CyanogenMod 或 LineageOS 特定的私有应用签名有关。

  • bluetooth:用于签署蓝牙服务或相关的 APK 文件。

  • sdk_sandbox:签署与 SDK 沙箱相关的应用或组件,确保开发环境的安全。

  • verity:用于签署与 Verified Boot 相关的组件,确保设备启动时的安全性。

ls keys

bluetooth.pk8       media.pk8              nfc.pk8            releasekey.pk8        shared.pk8         testkey.pk8
bluetooth.x509.pem  media.x509.pem         nfc.x509.pem       releasekey.x509.pem   shared.x509.pem    testkey.x509.pem
cyngn-app.pk8       networkstack.pk8       platform.pk8       sdk_sandbox.pk8       testcert.pk8       verity.pk8
cyngn-app.x509.pem  networkstack.x509.pem  platform.x509.pem  sdk_sandbox.x509.pem  testcert.x509.pem  verity.x509.pem

生成 target files

# 初始化编译环境
source build/envsetup.sh

# 设置构建目标
breakfast wayne

# 开始编译
mka target-files-package otatools

签名 target files

LineageOS 18.1 及以下版本的签名流程

sign_target_files_apks -o -d keys \
    $OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \
    signed-target_files.zip

注意:对于早于 18.1 的 LineageOS 版本,您必须在 sign_target_files_apks 命令前添加 ./build/tools/releasetools/

./build/tools/releasetools/sign_target_files_apks -o -d keys \
    $OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \
    signed-target_files.zip

LineageOS 19.1及以上版本的签名流程

sign_target_files_apks -o -d keys \
    --extra_apks AdServicesApk.apk=keys/releasekey \
    --extra_apks FederatedCompute.apk=keys/releasekey \
    --extra_apks HalfSheetUX.apk=keys/releasekey \
    --extra_apks HealthConnectBackupRestore.apk=keys/releasekey \
    --extra_apks HealthConnectController.apk=keys/releasekey \
    --extra_apks OsuLogin.apk=keys/releasekey \
    --extra_apks SafetyCenterResources.apk=keys/releasekey \
    --extra_apks ServiceConnectivityResources.apk=keys/releasekey \
    --extra_apks ServiceUwbResources.apk=keys/releasekey \
    --extra_apks ServiceWifiResources.apk=keys/releasekey \
    --extra_apks WifiDialog.apk=keys/releasekey \
    --extra_apks com.android.adbd.apex=keys/com.android.adbd \
    --extra_apks com.android.adservices.apex=keys/com.android.adservices \
    --extra_apks com.android.adservices.api.apex=keys/com.android.adservices.api \
    --extra_apks com.android.appsearch.apex=keys/com.android.appsearch \
    --extra_apks com.android.art.apex=keys/com.android.art \
    --extra_apks com.android.bluetooth.apex=keys/com.android.bluetooth \
    --extra_apks com.android.btservices.apex=keys/com.android.btservices \
    --extra_apks com.android.cellbroadcast.apex=keys/com.android.cellbroadcast \
    --extra_apks com.android.compos.apex=keys/com.android.compos \
    --extra_apks com.android.configinfrastructure.apex=keys/com.android.configinfrastructure \
    --extra_apks com.android.connectivity.resources.apex=keys/com.android.connectivity.resources \
    --extra_apks com.android.conscrypt.apex=keys/com.android.conscrypt \
    --extra_apks com.android.devicelock.apex=keys/com.android.devicelock \
    --extra_apks com.android.extservices.apex=keys/com.android.extservices \
    --extra_apks com.android.graphics.pdf.apex=keys/com.android.graphics.pdf \
    --extra_apks com.android.hardware.biometrics.face.virtual.apex=keys/com.android.hardware.biometrics.face.virtual \
    --extra_apks com.android.hardware.biometrics.fingerprint.virtual.apex=keys/com.android.hardware.biometrics.fingerprint.virtual \
    --extra_apks com.android.hardware.boot.apex=keys/com.android.hardware.boot \
    --extra_apks com.android.hardware.cas.apex=keys/com.android.hardware.cas \
    --extra_apks com.android.hardware.wifi.apex=keys/com.android.hardware.wifi \
    --extra_apks com.android.healthfitness.apex=keys/com.android.healthfitness \
    --extra_apks com.android.hotspot2.osulogin.apex=keys/com.android.hotspot2.osulogin \
    --extra_apks com.android.i18n.apex=keys/com.android.i18n \
    --extra_apks com.android.ipsec.apex=keys/com.android.ipsec \
    --extra_apks com.android.media.apex=keys/com.android.media \
    --extra_apks com.android.media.swcodec.apex=keys/com.android.media.swcodec \
    --extra_apks com.android.mediaprovider.apex=keys/com.android.mediaprovider \
    --extra_apks com.android.nearby.halfsheet.apex=keys/com.android.nearby.halfsheet \
    --extra_apks com.android.networkstack.tethering.apex=keys/com.android.networkstack.tethering \
    --extra_apks com.android.neuralnetworks.apex=keys/com.android.neuralnetworks \
    --extra_apks com.android.ondevicepersonalization.apex=keys/com.android.ondevicepersonalization \
    --extra_apks com.android.os.statsd.apex=keys/com.android.os.statsd \
    --extra_apks com.android.permission.apex=keys/com.android.permission \
    --extra_apks com.android.resolv.apex=keys/com.android.resolv \
    --extra_apks com.android.rkpd.apex=keys/com.android.rkpd \
    --extra_apks com.android.runtime.apex=keys/com.android.runtime \
    --extra_apks com.android.safetycenter.resources.apex=keys/com.android.safetycenter.resources \
    --extra_apks com.android.scheduling.apex=keys/com.android.scheduling \
    --extra_apks com.android.sdkext.apex=keys/com.android.sdkext \
    --extra_apks com.android.support.apexer.apex=keys/com.android.support.apexer \
    --extra_apks com.android.telephony.apex=keys/com.android.telephony \
    --extra_apks com.android.telephonymodules.apex=keys/com.android.telephonymodules \
    --extra_apks com.android.tethering.apex=keys/com.android.tethering \
    --extra_apks com.android.tzdata.apex=keys/com.android.tzdata \
    --extra_apks com.android.uwb.apex=keys/com.android.uwb \
    --extra_apks com.android.uwb.resources.apex=keys/com.android.uwb.resources \
    --extra_apks com.android.virt.apex=keys/com.android.virt \
    --extra_apks com.android.vndk.current.apex=keys/com.android.vndk.current \
    --extra_apks com.android.vndk.current.on_vendor.apex=keys/com.android.vndk.current.on_vendor \
    --extra_apks com.android.wifi.apex=keys/com.android.wifi \
    --extra_apks com.android.wifi.dialog.apex=keys/com.android.wifi.dialog \
    --extra_apks com.android.wifi.resources.apex=keys/com.android.wifi.resources \
    --extra_apks com.google.pixel.camera.hal.apex=keys/com.google.pixel.camera.hal \
    --extra_apks com.google.pixel.vibrator.hal.apex=keys/com.google.pixel.vibrator.hal \
    --extra_apks com.qorvo.uwb.apex=keys/com.qorvo.uwb \
    --extra_apex_payload_key com.android.adbd.apex=keys/com.android.adbd.pem \
    --extra_apex_payload_key com.android.adservices.apex=keys/com.android.adservices.pem \
    --extra_apex_payload_key com.android.adservices.api.apex=keys/com.android.adservices.api.pem \
    --extra_apex_payload_key com.android.appsearch.apex=keys/com.android.appsearch.pem \
    --extra_apex_payload_key com.android.art.apex=keys/com.android.art.pem \
    --extra_apex_payload_key com.android.bluetooth.apex=keys/com.android.bluetooth.pem \
    --extra_apex_payload_key com.android.btservices.apex=keys/com.android.btservices.pem \
    --extra_apex_payload_key com.android.cellbroadcast.apex=keys/com.android.cellbroadcast.pem \
    --extra_apex_payload_key com.android.compos.apex=keys/com.android.compos.pem \
    --extra_apex_payload_key com.android.configinfrastructure.apex=keys/com.android.configinfrastructure.pem \
    --extra_apex_payload_key com.android.connectivity.resources.apex=keys/com.android.connectivity.resources.pem \
    --extra_apex_payload_key com.android.conscrypt.apex=keys/com.android.conscrypt.pem \
    --extra_apex_payload_key com.android.devicelock.apex=keys/com.android.devicelock.pem \
    --extra_apex_payload_key com.android.extservices.apex=keys/com.android.extservices.pem \
    --extra_apex_payload_key com.android.graphics.pdf.apex=keys/com.android.graphics.pdf.pem \
    --extra_apex_payload_key com.android.hardware.biometrics.face.virtual.apex=keys/com.android.hardware.biometrics.face.virtual.pem \
    --extra_apex_payload_key com.android.hardware.biometrics.fingerprint.virtual.apex=keys/com.android.hardware.biometrics.fingerprint.virtual.pem \
    --extra_apex_payload_key com.android.hardware.boot.apex=keys/com.android.hardware.boot.pem \
    --extra_apex_payload_key com.android.hardware.cas.apex=keys/com.android.hardware.cas.pem \
    --extra_apex_payload_key com.android.hardware.wifi.apex=keys/com.android.hardware.wifi.pem \
    --extra_apex_payload_key com.android.healthfitness.apex=keys/com.android.healthfitness.pem \
    --extra_apex_payload_key com.android.hotspot2.osulogin.apex=keys/com.android.hotspot2.osulogin.pem \
    --extra_apex_payload_key com.android.i18n.apex=keys/com.android.i18n.pem \
    --extra_apex_payload_key com.android.ipsec.apex=keys/com.android.ipsec.pem \
    --extra_apex_payload_key com.android.media.apex=keys/com.android.media.pem \
    --extra_apex_payload_key com.android.media.swcodec.apex=keys/com.android.media.swcodec.pem \
    --extra_apex_payload_key com.android.mediaprovider.apex=keys/com.android.mediaprovider.pem \
    --extra_apex_payload_key com.android.nearby.halfsheet.apex=keys/com.android.nearby.halfsheet.pem \
    --extra_apex_payload_key com.android.networkstack.tethering.apex=keys/com.android.networkstack.tethering.pem \
    --extra_apex_payload_key com.android.neuralnetworks.apex=keys/com.android.neuralnetworks.pem \
    --extra_apex_payload_key com.android.ondevicepersonalization.apex=keys/com.android.ondevicepersonalization.pem \
    --extra_apex_payload_key com.android.os.statsd.apex=keys/com.android.os.statsd.pem \
    --extra_apex_payload_key com.android.permission.apex=keys/com.android.permission.pem \
    --extra_apex_payload_key com.android.resolv.apex=keys/com.android.resolv.pem \
    --extra_apex_payload_key com.android.rkpd.apex=keys/com.android.rkpd.pem \
    --extra_apex_payload_key com.android.runtime.apex=keys/com.android.runtime.pem \
    --extra_apex_payload_key com.android.safetycenter.resources.apex=keys/com.android.safetycenter.resources.pem \
    --extra_apex_payload_key com.android.scheduling.apex=keys/com.android.scheduling.pem \
    --extra_apex_payload_key com.android.sdkext.apex=keys/com.android.sdkext.pem \
    --extra_apex_payload_key com.android.support.apexer.apex=keys/com.android.support.apexer.pem \
    --extra_apex_payload_key com.android.telephony.apex=keys/com.android.telephony.pem \
    --extra_apex_payload_key com.android.telephonymodules.apex=keys/com.android.telephonymodules.pem \
    --extra_apex_payload_key com.android.tethering.apex=keys/com.android.tethering.pem \
    --extra_apex_payload_key com.android.tzdata.apex=keys/com.android.tzdata.pem \
    --extra_apex_payload_key com.android.uwb.apex=keys/com.android.uwb.pem \
    --extra_apex_payload_key com.android.uwb.resources.apex=keys/com.android.uwb.resources.pem \
    --extra_apex_payload_key com.android.virt.apex=keys/com.android.virt.pem \
    --extra_apex_payload_key com.android.vndk.current.apex=keys/com.android.vndk.current.pem \
    --extra_apex_payload_key com.android.vndk.current.on_vendor.apex=keys/com.android.vndk.current.on_vendor.pem \
    --extra_apex_payload_key com.android.wifi.apex=keys/com.android.wifi.pem \
    --extra_apex_payload_key com.android.wifi.dialog.apex=keys/com.android.wifi.dialog.pem \
    --extra_apex_payload_key com.android.wifi.resources.apex=keys/com.android.wifi.resources.pem \
    --extra_apex_payload_key com.google.pixel.camera.hal.apex=keys/com.google.pixel.camera.hal.pem \
    --extra_apex_payload_key com.google.pixel.vibrator.hal.apex=keys/com.google.pixel.vibrator.hal.pem \
    --extra_apex_payload_key com.qorvo.uwb.apex=keys/com.qorvo.uwb.pem \
    $OUT/obj/PACKAGING/target_files_intermediates/*-target_files*.zip \
    signed-target_files.zip

生成安装包

ota_from_target_files -k keys/releasekey \
    --block --backup=true \
    signed-target_files.zip \
    signed-ota_update.zip

注意:对于早于 18.1 的 LineageOS 版本,必须在 ota_from_target_files 命令前添加 ./build/tools/releasetools/

./build/tools/releasetools/ota_from_target_files -k keys/releasekey \
    --block --backup=true \
    signed-target_files.zip \
    signed-ota_update.zip

执行完成后,在当前目录下生成的 signed-ota_update.zip 就是签名后的刷机包



Android.bp    android.ipr~    build        external    libnativehelper  pdk                    signed-target_files.zip
Makefile      android.iws     cts          frameworks  lineage          platform_testing       system
android       art             dalvik       hardware    lineage-sdk      prebuilts              test
android.iml   bionic          developers   kernel      make_keys.sh     sdk                    toolchain
android.iml~  bootable        development  keys        out              sign_ota_wayne.sh      tools
android.ipr   bootstrap.bash  device       libcore     packages         signed-ota_update.zip  vendor

自动化脚本

以 LineageOS17.1(wayne) 为例,nano sign_ota_wayne.sh 创建脚本,内容如下

source build/envsetup.sh

# 设置构建目标
breakfast wayne

# target files
mka target-files-package otatools


# sign target files
./build/tools/releasetools/sign_target_files_apks -o -d keys \
    $OUT/obj/PACKAGING/target_files_intermediates/*-target_files-*.zip \
    signed-target_files.zip


# sign ota package
./build/tools/releasetools/ota_from_target_files -k keys/releasekey \
    --block --backup=true \
    signed-target_files.zip \
    signed-ota_update.zip

通过脚本把生成自定义签名安装包的流程自动化。

# 添加执行权限
chmod +x signing_ota_wayne.sh
# 执行脚本
./sign_ota_wayne.sh

刷机

进入recovery模式(或者同时按住【音量+】和【开机键】)

fastboot reboot recovery

注意:如果目前设备安装包签名和现在刷的安装包不一样,需要格式化 system 分区。格式化流程:【Factory reset】【Format system partition】。

【Apply update】【Apply from adb】开启 adb sideload
截图.png

开始刷机

adb sideload E:\lineageos\signed-ota_update.zip

等待刷机完成重启系统。

screenshot.png

参考:
Signing Builds

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

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

相关文章

详解HTTP/HTTPS协议

HTTP HTTP协议全名为超文本传输协议。HTTP协议是应用层协议,其传输层协议采用TCP协议。 请求—响应模型 HTTP协议采用请求-响应模型,通常由客户端发起请求由服务端完成响应。资源存储在服务端,客户端通过请求服务端获取资源。 认识URL 当…

jacoco生成单元测试覆盖率报告

前言 单元测试是日常编写代码中常用的,用于测试业务逻辑的一种方式,单元测试的覆盖率可以用来衡量我们的业务代码经过测试覆盖的比例。 目前市场上开源的单元测试覆盖率的java插件,主要有Emma,Cobertura,Jacoco。具体…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0916)

接口文档: https://apifox.com/apidoc/shared-26c67aee-0233-4d23-aab7-08448fdf95ff/api-93850835 接口根路径: http://big-event-vue-api-t.itheima.net 本项目的技术栈 本项目技术栈基于 ES6、vue3、pinia、vue-router 、vite 、axios 和 element-plus http:/…

企业社会信任数据,信任指数(2004-2022年)

企业社会信任是指公众对企业及其行为的信任程度,这种信任度是基于企业的商业行为、产品质量、服务态度、信息披露透明度和社会责任履行等多方面因素的综合评估。 2004年-2022年 企业社会信任数据(大数据)https://download.csdn.n…

【网络】高级IO——select版本TCP服务器

目录 前言 一,select函数 1.1.参数一:nfds 1.2.参数二: readfds, writefds, exceptfds 1.2.1.fd_set类型和相关操作宏 1.2.2.readfds, writefds, exceptfds 1.2.3.怎么理解 readfds, writefds, exceptfds是输入输出型参数 1.3.参数三…

LeetCode[中等] 3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 思路:滑动窗口,设置左右指针left与right,maxLength存储长度 利用HashSet性质,存储滑动窗口中的字符 如果没有重复的,那么right继续向…

5.基础漏洞——文件上传漏洞

目录 一.文件上传漏洞原理 二.文件上传漏洞条件: 三.上传限制手段分为两大类 (1)客户端校验 (2)服务端校验 四.具体实现 1.文件上传漏洞——绕过JS检测 2.文件上传漏洞——绕过MIME类型检测 3.文件上传漏洞——绕过黑名单检测 绕过方式:(1) 绕过方式:(2) …

yum本地源配置

yum本地源配置 1.打开虚拟机,点击设置。 2.选择CD/DVD,选择系统镜像文件,设备状态选择“连接”。 3.使用命令lsblk,查看磁盘空间,发现镜像文件。 4.在/dev下找到sr0镜像文件: ls /dev 5.挂载镜像文件&#xf…

闯关leetcode——27. Remove Element

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/remove-element/description/ 内容 Given an integer array nums and an integer val, remove all occurrences of val in nums in-place. The order of the elements may be changed. Then retur…

有关C# .NET Core 过滤器的使用

想用一个过滤器实现特定接口的审核日志记录,结果报了错,看了看感觉有些基础要补,所以想记录下来 错误: 在属性过滤器中使用了依赖注入,结果在应用在控制层接口时报了传参的错 //过滤器 public class AuditRecordFil…

C#语言依然是主流的编程语言之一,不容置疑

C#语言是由微软在2000年发布的现代面向对象编程语言。尽管在编程语言市场中的占有率相对较低,但C#依然保持了强大的存在感,并未像一些其他语言那样逐渐被淘汰。C#语言不仅有其存在的独特理由,而且拥有许多令人无法忽视的优势。以下从多个方面…

.Net Gacutil工具(全局程序集缓存工具)使用教程

GAC介绍: GAC(Global Assembly Cache)全局程序集缓存,是用于存放.Net应用程序共享的程序集。 像平常我们在Visual Studio中引用系统程序集时,这些程序集便来自于GAC。 GAC默认位置为:%windir%\Microsoft…

visual prompt tuning和visual instruction tuning

visual prompt tuning:作为一种微调手段,其目的是节省参数量,训练时需要优化的参数量小。 输入:视觉信息image token可学习的prompt token 处理任务:比如常见的分类任务 visual prompt tuning visual instruction tu…

【网络】高级IO——poll版本TCP服务器

目录 前言 一,poll函数 1.1.参数一:fds 1.2.参数二,nfds 1.3.参数三,timeout 1.4.返回值 1.5.poll函数简单使用示例 二,poll版TCP服务器编写 2.1.编写 2.2.poll的优缺点 2.3.源代码 前言 由于select函数有下面几个特别…

基于Python的自然语言处理系列(10):使用双向LSTM进行文本分类

在前一篇文章中,我们介绍了如何使用RNN进行文本分类。在这篇文章中,我们将进一步优化模型,使用双向多层LSTM来替代RNN,从而提高模型在序列数据上的表现。LSTM通过引入一个额外的记忆单元(cell state)来解决…

Linux:vim编辑技巧

命令模式 光标跳转 输入18,再输入G,可以跳转到18行。 复制、粘贴、删除 P是往上一行粘贴 小写u可以撤销 查找/撤销/保存 大写U可能失效,用CTRLr 末行模式 保存/退出/文件操作 字符串替换 开关参数的控制

基于python+django+vue的在线学习资源推送系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…

近乎实时的物联网数据管道架构

这篇论文的标题是《Near Real-Time IoT Data Pipeline Architectures》,作者是 Markus Multamki,完成于 2024 年,属于计算机科学与工程硕士学位论文。论文主要研究了物联网(IoT)数据分析的可扩展数据管道架构&#xff…

FloodFill算法【下】

417. 太平洋大西洋水流问题 题目链接:417. 太平洋大西洋水流问题 题目解析 题目给我们一个矩阵,这个矩阵相当于陆地,被两个洋包围,左和上代表太平洋,右和下代表大西洋。 矩阵里面的数字代表海拔,水可以…

STM32之FMC—扩展外部 SDRAM

文章目录 一、FMC外设介绍二、SDRAM 控制原理1、SDRAM关键参数a、容量、分区b、引脚SDRAM 使用 2、SDRAM芯片IS42S16400J3、SDRAM 控制引脚说明控制逻辑地址控制SDRAM 的存储阵列SDRAM 的命令预充电刷新 W9825G6KH:W9825G6KH引脚 三、STM32F429 FMC四、其他文章打开…