当前位置: 首页 > news >正文

FreeRTOS-rust食用指南

Rust 环境安装

  rustup 是 Rust 的安装程序,也是它的版本管理程序,Linux 命令行下使用如下方式安装

# 安装 rustup
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
#更新 rustup
rustup update# 版本检查
rustc -V
cargo -V

FreeRTOS-rust 框架介绍

  FreeRTOS-rust 是一个开源项目,旨在简化在嵌入式应用中使用 Rust 语言与 FreeRTOS 实时操作系统(RTOS)的集成。该项目基于 FreeRTOS 的原始 C 代码,并提供了 Rust 语言的接口。方便用户在嵌入式设备上使用 FreeRTOS 操作系统并使用 Rust 语言开发程序。

目录介绍

FreeRTOS-rust
├── .cargo						# 对 cargo 本身的配置
│   └── config.toml
├── Cargo.toml					# 对当前工作空间的配置
├── freertos-cargo-build		# 负责对 freertos 源码进行编译
│   ├── Cargo.toml				# 对当前 package 进行配置
│   └── src
│       └── lib.rs
├── freertos-rust				# 负责编译 freertos 的 rust 接口层
│   ├── Cargo.toml				# 对当前 package 进行配置
│   ├── build.rs				# package 编译前自动调用的脚本
│   └── src						# 适配层源码
│       ├── allocator.rs
│       ├── base.rs
│       ├── critical.rs
│       ├── delays.rs
│       ├── event_group.rs
│       ├── freertos			# freertos C 接口适配层和实现的钩子函数
│       │   ├── ports
│       │   │   └── arm
│       │   │       └── hooks.c
│       │   └── shim.c
│       ├── hooks.rs
│       ├── isr.rs
│       ├── lib.rs
│       ├── mutex.rs
│       ├── patterns
│       │   ├── compute_task.rs
│       │   ├── mod.rs
│       │   ├── processor.rs
│       │   └── pub_sub.rs
│       ├── portmacro.h
│       ├── prelude
│       │   ├── mod.rs
│       │   └── no_std.rs
│       ├── queue.rs
│       ├── semaphore.rs
│       ├── shim.rs
│       ├── task.rs
│       ├── timers.rs
│       ├── units.rs
│       └── utils.rs
├── freertos-rust-examples			# freertos 应用示例
│   ├── Cargo.toml					# 对当前 package 进行配置
│   ├── FreeRTOS-Kernel				# freertos 内核C源码
|		├── freertos-addons			# freertos 扩展库C++源码(无需关注)
│   ├── build.rs					# package 编译前自动调用的脚本
│   └── examples					# 各平台的rust freertos 应用开发示例
│       ├── linux
│       ├── nrf9160
│       ├── stm32-cortex-m3
│       │   ├── FreeRTOSConfig.h
│       │   ├── layout.ld
│       │   ├── main.rs
│       │   └── memory.x
│       ├── stm32-cortex-m4-blackpill
│       └── win
└── publish-all.sh

框架介绍

  FreeRTOS-rust 的整体框架分为三大块 freertos-cargo-buildfreertos-rustfreertos-rust-examples,其中 freertos-cargo-build 负责对项目中所有 C语言代码的编译,包括 FreeRTOS-Kernel 内核源码,freertos C 适配层接口以及 freertos 各种钩子函数实现,内部利用 cc crate 以及 build.rs 文件中提供的信息,将C语言代码打包为静态库。freertos-rust 中包括了 freertos 的C适配层接口和钩子函数实现,以及转换为 rust 语言的对外接口,应用开发使用的 rust freertos 接口均来自这里。freertos-rust-examples 中包括了 freertos 的C语言内核源码以及各平台的rust 应用示例。

各部分使用的语言:

  • FreeRTOS 内核源码:C 语言
  • FreeRTOS 对外接口:Rust 语言
  • APP 应用开发:Rust 语言
  • 项目编译体系:Rust 语言

FreeRTOS-rust 项目集成

注:本次项目集成是以 STM32F103ZET6 芯片平台为基础进行的,其他芯片平台实现方式类似。

项目获取

  github 开源代码仓库:https://github.com/lobaro/FreeRTOS-rust

git clone https://github.com/lobaro/FreeRTOS-rust.git

环境准备

Rust 工具链安装

  设置使用 nightly 版本的 rust 工具链,能够使用更多的新功能。

# 将默认的 Rust 工具链设置为 Nightly 版本
rustup default nightly
# 安装 Nightly gun 工具链
rustup toolchain install nightly-gnu# 将 nightly-gnu 设置为默认工具链
rustup default nightly-gnu

添加新的目标平台

  为工具链添加新的目标平台,添加平台后就可以使用 cargo build --target thumbv7m-none-eabi 编译进行指定平台的交叉编译了。

# 为工具链添加目标平台
rustup target add thumbv7m-none-eabi

调试工具安装

  安装 cargo 和 llvm 工具用于对交叉编译生成的文件进行转换和分析,例如 cargo strip、cargo objdump 等。

cargo install cargo-binutils
rustup component add llvm-tools-preview

FreeRTOS 内核源码获取

  项目在构件时会对 FreeRTOS 的源码进行交叉编译所以需要在项目根目录执行如下命令,拉取源码。

git submodule update --init --recursive

移植适配

examples Cargo.toml 配置修改

  目录:./FreeRTOS-rust/freertos-rust-examples/Cargo.toml
  将 stm32l1xx 的依赖库修改为 stm32f1xx 的依赖库,并将依赖库改为最新的库版本。

[package]
name = "freertos-rust-examples"
version = "0.1.1"
authors = ["Tobias Kaupat <tk@lobaro.de>"]
edition = "2018"
description = """
Create to use FreeRTOS in rust projects. It contains binaries for demos on some architecutres.
"""
keywords = ["FreeRTOS", "embedded", "demo", "examples"]
repository = "https://github.com/lobaro/FreeRTOS-rust"[dependencies]
freertos-rust = {path = "../freertos-rust"}[target.'cfg(target_arch = "arm")'.dependencies]
cortex-m = {version = "0.7.7", features = ["critical-section-single-core"]}
cortex-m-rt = "0.7.3"# Example: stm32-cortex-m3, [target.<triple>.dependencies] triple form cargo build --target thumbv7m-none-eabi
# or form .cargo/config.toml  [build] target = "thumbv7m-none-eabi"
[target.thumbv7m-none-eabi.dependencies]
nb = "0.1.2"
embedded-hal = "0.2.3"
panic-halt = "0.2.0"
stm32f1xx-hal = {version = "0.10.0", features = ["rt", "stm32f103"], default-features = false}# Example: stm32-cortex-m4-blackpill
[target.thumbv7em-none-eabihf.dependencies]
panic-halt = "0.2.0"
embedded-hal = "0.2.3"
stm32f4xx-hal = {version = "0.8.3", features = ["rt", "stm32f411"]}# Example: nrf9160
[target."thumbv8m.main-none-eabihf".dependencies]
nrf9160-pac = "0.2.1"# Example: win
[target.x86_64-pc-windows-gnu.dependencies]# Example: linux
[target.x86_64-unknown-linux-gnu.dependencies][build-dependencies]
freertos-cargo-build = {path = "../freertos-cargo-build"}

stm32-cortex-m3 FreeRTOS配置修改

  目录:
./FreeRTOS-rust/freertos-rust-examples/examples/stm32-cortex-m3/FreeRTOSConfig.h

// 修改CPU主频
// #define configCPU_CLOCK_HZ				( 4200000UL ) //also systick runs at this frequency
#define configCPU_CLOCK_HZ				( 72000000UL ) //also systick runs at this frequency// 禁止可视化跟踪调试
// #define configUSE_TRACE_FACILITY		1
#define configUSE_TRACE_FACILITY		0// 禁止堆栈溢出检测功能
// #define configCHECK_FOR_STACK_OVERFLOW	2
#define configCHECK_FOR_STACK_OVERFLOW	0// 禁用状态格式函数
// #define configUSE_STATS_FORMATTING_FUNCTIONS (1)
#define configUSE_STATS_FORMATTING_FUNCTIONS (0)

stm32-cortex-m3 连接脚本修改

  目录:
./FreeRTOS-rust/freertos-rust-examples/examples/stm32-cortex-m3/layout.ld
./FreeRTOS-rust/freertos-rust-examples/examples/stm32-cortex-m3/memory.x

MEMORY
{FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512KRAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 64K
}

stm32-cortex-m3 main.rs 应用修改

  目录:
./FreeRTOS-rust/freertos-rust-examples/examples/stm32-cortex-m3/main.rs

#![no_std]
#![no_main]
// For allocator
// #![feature(lang_items)]
#![feature(alloc_error_handler)]
use core::fmt::Write;
use core::panic::PanicInfo;
use core::alloc::Layout;use nb::block;use cortex_m;
use cortex_m::asm;
use cortex_m_rt::exception;
use cortex_m_rt::{entry, ExceptionFrame};use embedded_hal::digital::v2::OutputPin;
use freertos_rust::*;// use stm32f1xx_hal::gpio::*;
use stm32f1xx_hal::gpio::IOPinSpeed;
use stm32f1xx_hal::gpio::OutputSpeed;
use stm32f1xx_hal::timer::Timer;
use stm32f1xx_hal::serial;
use stm32f1xx_hal::rcc::RccExt;
use stm32f1xx_hal::time::U32Ext;
use stm32f1xx_hal::prelude::_fugit_RateExtU32;
use stm32f1xx_hal::prelude::_stm32_hal_afio_AfioExt;
use stm32f1xx_hal::prelude::_stm32_hal_flash_FlashExt;
use stm32f1xx_hal::prelude::_stm32_hal_gpio_GpioExt;use stm32f1xx_hal as hal;use crate::hal:: {stm32::{Peripherals},
};// extern crate panic_halt; // panic handler#[global_allocator]
static GLOBAL: FreeRtosAllocator = FreeRtosAllocator;fn delay() {let mut _i = 0;for _ in 0..2_00 {_i += 1;}
}fn delay_n(n: i32) {for _ in 0..n {delay();}
}pub struct MyDevice<D1: OutputPin> {d1: D1,
}impl<D1: OutputPin> MyDevice<D1>{pub fn from_pins(d1: D1) -> MyDevice<D1> {MyDevice {d1}}pub fn set_led(&mut self, on:bool){if on {let _ =self.d1.set_high();} else {let _ =self.d1.set_low();}}}#[entry]
fn main() -> ! {// 获取对内核外设的访问权限let cp = cortex_m::Peripherals::take().unwrap();// 获取对特定设备外设的访问权限let dp = Peripherals::take().unwrap();let mut afio = dp.AFIO.constrain();// 获得原始flash和rcc设备的所有权,并将它们转换为相应的HAL结构let mut flash = dp.FLASH.constrain();let rcc = dp.RCC.constrain();// 冻结系统中所有时钟的配置,并将冻结的频率存储在时钟树中let clocks = rcc.cfgr.freeze(&mut flash.acr);// 通过拆分 GPIOB 引脚,获取对其各引脚的互斥访问let mut gpiob = dp.GPIOB.split();let mut device = MyDevice::from_pins(gpiob.pb5.into_push_pull_output(&mut gpiob.crl));device.d1.set_speed(&mut gpiob.crl, IOPinSpeed::Mhz50);let mut gpioa = dp.GPIOA.split();// USART1 on Pins A9 and A10let pin_tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);let pin_rx = gpioa.pa10;// 设置串口USART1的参数let serial = serial::Serial::new(dp.USART1,(pin_tx, pin_rx),&mut afio.mapr,serial::Config::default().baudrate(115200_u32.bps()).stopbits(serial::StopBits::STOP1).wordlength_8bits().parity_none(),&clocks,);// 将串行结构拆分为接收和发送部分let (mut tx, mut _rx) = serial.split();let number = 103;writeln!(tx,"Hello formatted string {}", number).unwrap();// 将系统计时器配置为每秒触发一次更新let mut timer = Timer::syst(cp.SYST, &clocks).counter_hz();// 设置定时器的频率1Hztimer.start(1.Hz()).unwrap();// 等待计时器触发更新并更改LED的状态, 每秒钟切换 LED 状态(高电平/低电平)。for _i in 0..3 {// 等待定时器block!(timer.wait()).unwrap();// 设置高电平device.set_led(true);block!(timer.wait()).unwrap();// 设置低电平device.set_led(false);}device.set_led(false);// 创建任务Task::new().name("hello").stack_size(128).priority(TaskPriority(2)).start(move |_| {loop {freertos_rust::CurrentTask::delay(Duration::ms(100));tx.bwrite_all(b"led hight").unwrap();device.set_led(true);freertos_rust::CurrentTask::delay(Duration::ms(100));tx.bwrite_all(b"led low").unwrap();device.set_led(false);}}).unwrap();// 启动系统任务调度Task::new().name("hello").stack_size(128).priority(TaskPriority(2)).start(task_function).unwrap();FreeRtosUtils::start_scheduler();
}#[exception]
unsafe fn DefaultHandler(_irqn: i16) {
// custom default handler
// irqn is negative for Cortex-M exceptions
// irqn is positive for device specific (line IRQ)
// set_led(true);(true);
// panic!("Exception: {}", irqn);
}#[exception]
unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {loop {// 在这里添加遇到 HardFault 时希望执行的代码}
}// define what happens in an Out Of Memory (OOM) condition
#[alloc_error_handler]
fn alloc_error(_layout: Layout) -> ! {asm::bkpt();loop {// 在这里添加遇到 error 时希望执行的代码}
}#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {loop {// 在这里添加遇到 panic 时希望执行的代码}
}

编译烧录

项目编译

  在项目根目录下执行如下指令进行进行编译并转换为 Hex 文件用于烧录

# 编译整个项目
cargo build --package freertos-rust-examples --example stm32-cortex-m3 --target thumbv7m-none-eabi --release
# 删除ELF执行文件中的符号表
cargo strip --target thumbv7m-none-eabi --example stm32-cortex-m3 --release
# ELF文件转Hex文件用于stm32f103烧录
cargo objcopy --example stm32-cortex-m3 --target thumbv7m-none-eabi -- -O ihex stm32-cortex-m3.hex

固件烧录

  从 Linux 环境拷贝出 stm32-cortex-m3.hex 文件到 window 环境,然后使用 Keil、STM32 ST-LINK Utility 等方式进行烧录即可,具体方法请自行百度。

总结:

  FreeRTOS-rust 项目基于 FreeRTOS 内核源码构建安全的 rust 应用开发环境,要比一些使用纯 rust 重新开发 FreeRTOS 的项目更加贴合实际,对比的优点主要有以下部分:

  1. 使用 C语言的 FreeRTOS 内核源码要比使用 rust 重新开发的内核源码至少在体积上小 3倍左右。
  2. 使用 C语言的 FreeRTOS 内核源码稳定性更好,因为开源版本已经经过了无数轮的迭代和问题修复。
  3. 使用 C语言的 FreeRTOS 内核源码这种方式目前在实际项目应用中更具有可行性,因为大部分嵌入式项目的底座还是 C的。
      但是在获取 rust 内存安全特性的同时也会带来一些问题:
  4. 应用层使用 rust 开发,FreeRTOS 内核源码依然是C语言的,这部分代码 rust 的安全机制无法进行追踪,如果出现问题,更加难以排查。
  5. 目前在嵌入式领域很多优秀的开源 C 语言组件还没有实现 rust 重写,应用层如果想完全使用 rust 开发,目前还存在一些难度,当然 rust 项目也可以使用之前的 C库组件。
  6. 使用 rust 开发应用程序不可避免的需要进行外设操作甚至是MCU的寄存器操作,目前嵌入式芯片的底层 rust 驱动库不够多,很多芯片没有 rust 的底层驱动库,类似与 stm32 的 ARM 系列芯片虽然已经有底层驱动库,但是版本还在迭代,使用起来不是特别方便。
  7. 使用 rust 进行应用层开发,代码的体积是需要首先考虑的事情,一般来说,同样功能的实现,rust 代码体积至少比 C代码体积大2~3倍。

🌀路西法 的个人博客拥有更多美文等你来读。

相关文章:

FreeRTOS-rust食用指南

Rust 环境安装 rustup 是 Rust 的安装程序&#xff0c;也是它的版本管理程序&#xff0c;Linux 命令行下使用如下方式安装 # 安装 rustup curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh #更新 rustup rustup update# 版本检查 rustc -V cargo -VFreeRTOS-rust…...

如何使用智能化RFID管控系统,对涉密物品进行安全有效的管理?

载体主要包括纸质文件、笔记本电脑、优盘、光盘、移动硬盘、打印机、复印机、录音设备等&#xff0c;载体&#xff08;特别是涉密载体&#xff09;是各保密、机要单位保证涉密信息安全、防止涉密信息泄露的重要信息载体。载体管控系统主要采用RFID射频识别及物联网技术&#xf…...

0基础学LabVIEW

对于零基础的朋友来说&#xff0c;学习LabVIEW需要一个科学的学习路径和方法。通过观看优质的B站教程打好基础&#xff0c;再结合实际项目进行实践操作&#xff0c;能够快速提升LabVIEW的应用能力。以下是从入门到进阶的学习建议。 ​ 一、利用B站入门教程打基础 筛选优质教程…...

Go语言精进之路读书笔记(第二部分-项目结构、代码风格与标识符命名)

说明&#xff1a;《Go语言精进之路》第一部分-熟知Go语言的一切&#xff0c;不在博客中做读书笔记了&#xff0c;大家可以自己读一读&#xff0c;每个人心里都会有自己对Go语言的认识和理解。 直接从第二部分-项目接口、代码风格与标识符命名开始 第二章目录如下 第5条 使用…...

Windows server 2016 无法部署docker问题

根据流程winserver16安装docker ee&#xff0c;发现服务器管理器的添加角色和功能-功能中没有 container 根据流程winserver16安装docker desktop&#xff0c;发现安装 hyper-v 报错 原因&#xff1a; 本人测试用windows server 2016使用vmware搭建&#xff0c;而vmware本身可…...

智能AI之隐私安全,尤其是医疗

前言 智能AI能更好的服务我们的生活&#xff0c;各行各业都将会有她的影子。我们在依赖她的情况下&#xff0c;我们的隐私安全吗&#xff1f; 前两天分享了用她分析CT拍片、还有一份血检报告单&#xff0c;回复的确实比有些医生都说的专业全面。以至于我都有冲动依赖她开…...

【hot100】054螺旋矩阵

一、思路 这个题目主要有两个问题&#xff0c;一是什么时候切换方向&#xff0c;二是如何切换方向 问题一&#xff1a;此步移动完后&#xff0c;判断下一个元素&#xff0c;如果大于等于边界值&#xff08;从0开始&#xff09;或者小于边界值时或者访问数组为真时 问题二&am…...

【Java学习】类和对象

目录 一、选择取块解 二、类变量 三、似复刻变量 四、类变量的指向对象 五、变量的解引用访问 1.new 类变量(参) 2.this(参) 3.类变量/似复刻变量. 六、代码块 七、复制变量的赋值顺序 八、访问限定符 1.private 2.default 九、导类 一、选择取块解 解引用都有可以…...

TestHubo基础教程-创建项目

TestHubo是一款国产开源一站式测试工具&#xff0c;涵盖功能测试、接口测试、性能测试&#xff0c;以及 Web 和 App 测试&#xff0c;可以满足不同类型项目的测试需求。本文将介绍如何快速创建第一个项目&#xff0c;以快速入门上手。 1、创建项目 在 TestHubo 中&#xff0c;…...

JS 链表

文章目录 链表题的一些总结两种链表定义set存储链表节点&#xff0c;存的是整个空间同时处理长短不一的两个链表处理方法 while(l1 || l2)处理方法 while(l1 & l2) dummyhead的使用 链表题的一些总结 两种链表定义 class class ListNode {val;next null;constructor(va…...

数据结构(陈越,何钦铭)第三讲 树(上)

3.1 树与数的表示 3.1.1 顺序查找 int SequentialSearch(List Tbl,ElementType K){int i;Tbl->Element[0]K;for(iTbl->Length;Tbl->Element[i]!K;i--);return i; } typedef struct LNode *List; struct LNode{ElementType Element[MAXSIZE];int Length; };3.1.2 二分…...

企业文件安全:零信任架构下的文件访问控制

在企业数字化转型的进程中&#xff0c;传统的文件访问控制模型已难以满足日益复杂的网络安全需求。零信任架构作为一种新兴的安全理念&#xff0c;为企业的文件安全访问提供了全新的解决方案。 一、传统文件访问控制的局限性 传统的文件访问控制主要基于网络边界&#xff0c;…...

性格测评小程序06用户注册校验

目录 1 必填校验2 验证密码强度3 账号唯一性校验最终效果总结 上一篇我们介绍了用户注册的功能&#xff0c;注册的时候对密码进行了加密。除了密码加密外还需要验证账号的唯一性和密码强度的问题&#xff0c;本篇我们介绍一下如何在表单提交的时候增加自定义校验的能力。 1 必填…...

$符(前端)

1‌. jQuery 的别名 用途&#xff1a;$ 是 jQuery 的核心标识符&#xff0c;用于快速选择 DOM 元素或调用 jQuery 方法。 // 选择所有 <div> 元素并隐藏 $(div).hide(); // 发起 AJAX 请求 $.get(/api/data, response > console.log(response)); 注意&#xff1a;虽然…...

Windows 11如何显示全部右键菜单?

在Windows 11系统中&#xff0c;默认的右键菜单进行了简化&#xff0c;若你想要显示全部右键菜单&#xff0c;可以通过以下几种方法实现&#xff1a; 方法一&#xff1a;临时显示完整右键菜单 在需要操作的区域按下Shift键的同时点击鼠标右键&#xff0c;此时弹出的就是完整的…...

离线量化算法和工具 --学习记录1

离线量化算法和工具 一、离线量化的基础概念1.1、基本流程1.2、量化的优点和缺点1.3、如何生产一个硬件能跑的量化模型1.4、PTQ的概念以及和QAT的区别1.5、离线量化的标准流程1.6、校准数据的选择1.7、量化模式的选择1.8、校准方式的选择1.9、量化算法的选择1.10、写入量化参数…...

python第七课

WSGI Middleware 中间件&#xff0c;可以理解称对应用程序的一组装饰器&#xff0c;对两边都起作用的元素。 重写environ&#xff0c;然后基于URL&#xff0c;将请求对象路由给不同的应用对象支持多个应用或者框架顺序地运行于同一个进程中通过转发请求和相应&#xff0c;支持负…...

华为IPD简介

创作灵感 现在“熟悉华为IPD”经常出现在高级招聘岗位能力要求上&#xff0c;于是作者写下此文章以此巩固相关知识储备 名词解释 华为IPD&#xff08;Integrated Product Development&#xff0c;集成产品开发&#xff09;是华为引入并优化的一套产品开发管理体系&#xff0…...

如何在Spring Boot中配置分布式配置中心

文章目录 如何在Spring Boot中配置分布式配置中心分布式配置中心的概念1. 集中管理2. 动态配置3. 环境隔离4. 安全性5. 可扩展性与适应性6. 与 CI/CD 流程的集成Spring Cloud Config 概述1. 集中式配置管理2. 多环境支持3. 版本控制4. 动态刷新5. 安全性6. 与微服务架构的无缝集…...

Golang internals

To be continued... time.Time golang的时区和神奇的time.Parse context.Context Go Context的踩坑经历 sync.Pool sync.Pool workflow in Go 1.12 new shared pools in Go 1.13 什么是cpu cache理解 Go 1.13 中 sync.Pool 的设计与实现Go: Understand the Design of Sync.Pool…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

MeshGPT 笔记

[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭&#xff01;_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...