STM32F103R8T6 FreeRTOS移植实战:从裸机到多任务避坑指南

简介:这份资源面向嵌入式开发初学者与进阶工程师,提供将FreeRTOS实时操作系统移植到STM32F103R8T6(ARM Cortex-M3内核)的完整工程资料,帮助读者理解轻量级RTOS在资源受限微控制器上的落地方法。压缩包共226个文件,约5.87MB,以c与h源码为主,辅以lst、o、d、crf等编译中间文件,以及uvprojx、uvoptx工程配置、sct分散加载、hex与axf可执行产物和readme说明,覆盖从源码到烧录的完整链路。目录按HARDWARE、CORE、SYSTEM、FreeRTOS、USER、STM32F10x_FWLib等模块组织,分别承载硬件驱动、内核启动与中断、系统时钟与内存管理、任务调度与信号量队列、用户业务逻辑及标准外设库,结构清晰便于按模块研读。目前已有925人学习下载,适合希望掌握Cortex-M3架构、FreeRTOS内核原理与嵌入式移植流程的开发者参考借鉴。

1. 从裸机到多任务:为什么这个 STM32F103R8T6 移植包值得拆一遍

很多刚接触 STM32 的开发者都有过这样的经历:裸机跑得好好的工程,一旦要同时处理按键、串口、屏幕刷新和传感器采集,主循环里的delay就开始互相打架,改到最后自己都理不清哪个任务该先跑。这份 STM32F103R8T6_freertos移植.zip 解决的正是这个痛点——它把 FreeRTOS 实时内核完整地搬到了 STM32F103R8T6 这颗经典芯片上,让你从「一个大循环硬扛」切换到「多个任务各管一摊」的开发模式。STM32F103R8T6 属于 F1 系列中等容量型号,64KB Flash、20KB SRAM,资源不算宽裕,恰恰是练手 RTOS 的好靶子。这份资源适合两类人:一是想从裸机过渡到 RTOS 的初学者,二是需要在 F103 平台上快速搭多任务框架的工程师。拿到手就能编译、下载、看任务跑起来,不用自己从零配时钟树和中断优先级。

2. 工程结构拆解:从启动文件到任务创建的完整链路

2.1 目录布局与关键文件定位

拿到这个移植包,第一件事不是急着打开 main.c,而是先把目录结构摸清楚。一个标准的 FreeRTOS 移植工程通常长这样:

STM32F103R8T6_FreeRTOS/ ├── CMSIS/ # 内核外设访问层 │ ├── core_cm3.h │ └── stm32f10x.h ├── FreeRTOS/ │ ├── Source/ │ │ ├── tasks.c # 任务调度核心 │ │ ├── queue.c # 队列与信号量 │ │ ├── list.c # 内核链表 │ │ ├── timers.c # 软件定时器 │ │ └── portable/ │ │ └── RVDS/ARM_CM3/ # Cortex-M3 移植层 │ │ ├── port.c │ │ └── portmacro.h │ └── Include/ │ └── FreeRTOSConfig.h # 裁剪配置文件 ├── User/ │ ├── main.c │ ├── stm32f10x_it.c # 中断服务函数 │ └── system_stm32f10x.c ├── Drivers/ │ ├── stm32f10x_gpio.c │ ├── stm32f10x_rcc.c │ └── stm32f10x_usart.c └── Start/ ├── startup_stm32f10x_md.s └── stm32f10x_flash.ld

这里有几个文件是移植成败的关键。port.c负责上下文切换的底层汇编,FreeRTOSConfig.h决定内核裁剪到什么程度,stm32f10x_it.c里的SysTick_Handler和PendSV_Handler必须交给 FreeRTOS 接管。很多人移植失败就栽在这三个地方——要么中断向量没重定向,要么堆栈大小给少了,要么 config 里把不该关的功能关了。

2.2 FreeRTOSConfig.h 的核心参数怎么配

这个头文件是整个移植的「控制面板」,配错了轻则任务跑不起来,重则一进调度就 HardFault。以下是一份针对 STM32F103R8T6(20KB SRAM)的典型配置:

/* FreeRTOSConfig.h - 针对 STM32F103R8T6 裁剪 */ #define configUSE_PREEMPTION 1 // 抢占式调度,高优先级任务可打断低优先级 #define configUSE_IDLE_HOOK 0 // 不用空闲钩子,省空间 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ (72000000) // 系统主频 72MHz #define configTICK_RATE_HZ (1000) // 1ms 一个 tick #define configMAX_PRIORITIES (5) // 只用 5 级优先级,够用且省 RAM #define configMINIMAL_STACK_SIZE (64) // 空闲任务栈,单位是字不是字节 #define configTOTAL_HEAP_SIZE (6 * 1024) // 堆区 6KB,留给任务和队列 #define configMAX_TASK_NAME_LEN (8) // 任务名短一点省空间 #define configUSE_16_BIT_TICKS 0 // 32 位 tick 计数 #define configUSE_MUTEXES 1 // 用到互斥量就开 #define configUSE_COUNTING_SEMAPHORES 1 #define configCHECK_FOR_STACK_OVERFLOW 2 // 栈溢出检测,调试期必开 #define configUSE_MALLOC_FAILED_HOOK 1 // 内存分配失败钩子

几个参数值得展开说。configTICK_RATE_HZ设成 1000 意味着每个 tick 是 1ms,这是最常用的值,再高中断开销大,再低任务响应变迟钝。configMINIMAL_STACK_SIZE的单位是「字」,在 32 位机上一个字 4 字节,所以 64 字等于 256 字节,这是空闲任务的最小栈,实际任务要按需加大。configTOTAL_HEAP_SIZE是 FreeRTOS 自己管理的堆,不是芯片的全部 RAM,20KB 的 SRAM 里拿出 6KB 给内核堆是比较稳妥的,剩下的留给全局变量和主栈。configCHECK_FOR_STACK_OVERFLOW设成 2 是最严格的检测方式,会在任务切换时检查栈末尾的标记字有没有被踩,调试阶段强烈建议开着,产品发布再关掉省几个周期。

2.3 中断优先级与 PendSV/SysTick 的接管

Cortex-M3 的中断优先级配置是 FreeRTOS 移植里最容易翻车的地方。FreeRTOS 需要一个最低优先级的中断来做上下文切换(PendSV),还需要一个 tick 中断来驱动调度(SysTick)。在port.c里,这两个中断的优先级被设成最低:

/* port.c 中定义的中断优先级 */ #define configKERNEL_INTERRUPT_PRIORITY (255) /* 最低优先级 */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY (191) /* 允许调用 API 的最高优先级 */

STM32 的 NVIC 优先级寄存器只用了高 4 位,所以 255 对应实际寄存器的 0xF0,191 对应 0xB0。这意味着优先级数值大于 191 的中断里不能调用 FreeRTOS 的 API(比如xQueueSendFromISR),否则会触发断言。很多人在串口中断里直接调xQueueSend而不是xQueueSendFromISR,结果就是随机死机——这是血泪教训级别的坑。

在stm32f10x_it.c里,你需要确保这三个中断向量指向 FreeRTOS 的处理函数:

/* stm32f10x_it.c - 中断向量重定向 */ void SysTick_Handler(void) { if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { xPortSysTickHandler(); // 调度器启动后才交给 FreeRTOS } } void PendSV_Handler(void) { xPortPendSVHandler(); // 上下文切换,必须无条件交给 FreeRTOS } void SVC_Handler(void) { vPortSVCHandler(); // 启动第一个任务时用 }

注意SysTick_Handler里加了一个调度器状态判断。如果调度器还没启动就调用xPortSysTickHandler,内核链表还没初始化,直接跑飞。这个判断是很多移植教程里漏掉的细节。

3. 跑起来:从零编译到看见 LED 按任务节奏闪烁

3.1 工具链准备与工程导入

这份工程可以用 Keil MDK 或者 STM32CubeIDE 打开。如果用 Keil,需要确认安装了 STM32F1 的 Device Family Pack;如果用 CubeIDE,直接把源码目录拖进新建的 STM32 工程即可。编译器优化等级建议先设成-O0或-Og,调试阶段不要开-O2,否则断点跳来跳去会让你怀疑人生。

导入后先别急着编译,检查三个地方:一是启动文件是不是startup_stm32f10x_md.s(md 对应中等容量),二是链接脚本里的 RAM 起始地址和大小是不是0x20000000和0x5000(20KB),三是预处理器宏里有没有定义STM32F10X_MD和USE_STDPERIPH_DRIVER。这三项错一个,编译能过但跑不起来。

3.2 创建第一个任务并启动调度器

main.c是整个工程的入口,典型的 FreeRTOS 启动流程如下:

/* main.c - 创建任务并启动调度器 */ #include "FreeRTOS.h" #include "task.h" #include "stm32f10x.h" /* 任务句柄 */ static TaskHandle_t xLedTaskHandle = NULL; static TaskHandle_t xPrintTaskHandle = NULL; /* LED 闪烁任务:500ms 翻转一次 */ static void vLedTask(void *pvParameters) { GPIO_InitTypeDef gpio; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); gpio.GPIO_Pin = GPIO_Pin_13; gpio.GPIO_Mode = GPIO_Mode_Out_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &gpio); for (;;) { GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13))); vTaskDelay(pdMS_TO_TICKS(500)); // 阻塞 500ms,让出 CPU } } /* 串口打印任务:每秒输出一次 tick 计数 */ static void vPrintTask(void *pvParameters) { for (;;) { printf("Tick: %lu\r\n", (unsigned long)xTaskGetTickCount()); vTaskDelay(pdMS_TO_TICKS(1000)); } } int main(void) { /* 系统时钟初始化,72MHz */ SystemInit(); /* 创建任务:栈深度 128 字,优先级 2 和 1 */ xTaskCreate(vLedTask, "LED", 128, NULL, 2, &xLedTaskHandle); xTaskCreate(vPrintTask, "PRINT", 256, NULL, 1, &xPrintTaskHandle); /* 启动调度器,从此不再返回 */ vTaskStartScheduler(); /* 如果走到这里说明堆不够,调度器启动失败 */ for (;;); }

这段代码里有几个关键点。xTaskCreate的第三个参数是栈深度,单位是字,LED 任务用了 128 字(512 字节),打印任务因为要调printf用了 256 字(1KB)。printf在嵌入式里是个吃栈大户,栈给小了会直接 HardFault。优先级数值越大优先级越高,LED 任务设成 2,打印任务设成 1,所以 LED 会抢占打印。vTaskDelay的参数是 tick 数,用pdMS_TO_TICKS宏把毫秒转成 tick,这样即使以后改了configTICK_RATE_HZ也不用改业务代码。

3.3 验证任务调度是否正常

烧录后如果 LED 以 1Hz 频率闪烁,串口每秒输出一次 tick 计数,说明调度器跑起来了。这时候可以做个压力测试:把 LED 任务的vTaskDelay改成vTaskDelay(1),让它几乎不阻塞,观察打印任务还能不能正常输出。如果打印任务被饿死,说明抢占式调度生效了;如果两个任务都正常,检查configUSE_PREEMPTION是不是被误设成 0。

另一个验证手段是用 GPIO 翻转配合示波器看任务切换频率。在任务切换钩子vApplicationTaskSwitchHook里翻转一个 IO,能直观看到调度器每秒切换多少次。这个钩子需要在FreeRTOSConfig.h里把configUSE_TASK_SWITCH_HOOK打开。

4. 避坑指南:移植 FreeRTOS 时最容易踩的五个雷

4.1 HardFault 一进调度就触发

现象:编译下载都正常,但vTaskStartScheduler()一调用就进 HardFault_Handler。

原因:九成是堆栈配置问题。要么configTOTAL_HEAP_SIZE设得比实际可用 RAM 还大,要么configMINIMAL_STACK_SIZE太小导致空闲任务栈溢出,要么主栈(MSP)和任务栈(PSP)切换时栈指针没对齐。

解决:先把configTOTAL_HEAP_SIZE降到 4KB 试试,把configCHECK_FOR_STACK_OVERFLOW设成 2,在vApplicationStackOverflowHook里打个断点。如果还不行,检查启动文件里的堆栈大小定义,Stack_Size至少给 0x400。

4.2 中断里调用 API 导致随机死机

现象:主循环跑得好好的,一进串口中断调xQueueSendFromISR就偶尔死机,重启后又正常。

原因:中断优先级设错了。STM32 的 NVIC 优先级数值越小优先级越高,而 FreeRTOS 要求调用FromISR系列 API 的中断优先级数值必须大于等于configMAX_SYSCALL_INTERRUPT_PRIORITY(通常是 5 左右)。如果串口中断优先级设成了 0 或 1,就会在中断里操作内核数据结构时被更高优先级中断打断,导致链表损坏。

解决:把所有需要调用 FreeRTOS API 的中断优先级都设成 5 以上。用NVIC_SetPriority(USART1_IRQn, 6)这样的方式显式设置,不要依赖默认值。

4.3 printf 重定向后任务栈不够用

现象:单独跑 LED 任务正常,加上 printf 任务后系统随机崩溃。

原因:printf内部用了大量局部变量,尤其是浮点格式化时栈开销可能超过 500 字节。如果任务栈只给了 128 字(512 字节),很容易踩到栈边界。

解决:给调用printf的任务至少 256 字栈空间,如果格式化浮点数建议给到 512 字。更稳妥的做法是用snprintf到固定缓冲区再通过串口发送,避免printf的不可预测栈开销。

4.4 vTaskDelay 在中断里调用导致断言失败

现象:在定时器中断里调用vTaskDelay后系统卡死,调试器显示停在configASSERT里。

原因:vTaskDelay是任务级 API,只能在任务上下文里调用,不能在中断里用。中断里应该用vTaskDelayUntil的 ISR 版本或者直接操作硬件定时器。

解决:中断里需要延时就用硬件定时器或者xTaskResumeFromISR唤醒一个任务来处理。记住一条铁律:所有带FromISR后缀的 API 才能在中断里调,不带后缀的一律只能在任务里用。

4.5 任务删除了但内存没回收

现象:反复创建和删除任务后,系统可用堆越来越小,最终xTaskCreate返回errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY。

原因:FreeRTOS 的vTaskDelete只回收任务控制块和栈,如果任务里动态申请了内存没释放,或者用了pvPortMalloc没配对vPortFree,就会泄漏。

解决:尽量用静态创建方式xTaskCreateStatic,内存由编译期分配,不依赖堆。如果必须动态创建,确保删除任务前释放所有该任务申请的资源。调试阶段可以在vApplicationMallocFailedHook里打个断点,看看是谁把堆吃光了。

5. 二次开发改造:把这份移植包变成你自己的多任务框架

拿到这份移植包,跑通只是第一步,真正有价值的是把它改造成适合自己项目的框架。我一般会做三件事:加一个任务间通信的队列层、把硬件初始化抽象成独立模块、再补一套轻量级的日志系统。

先说队列层。裸机时代全局变量满天飞,上了 RTOS 之后应该用队列来传递数据。比如串口接收任务收到一帧数据后,通过队列发给解析任务:

/* 定义队列句柄和消息结构 */ typedef struct { uint8_t data[64]; uint16_t len; } UartMsg_t; static QueueHandle_t xUartQueue = NULL; /* 在 main 里创建队列,长度 4 个消息 */ xUartQueue = xQueueCreate(4, sizeof(UartMsg_t)); /* 串口中断里发送到队列 */ void USART1_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; UartMsg_t msg; /* ... 填充 msg ... */ xQueueSendFromISR(xUartQueue, &msg, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } /* 解析任务里阻塞等待 */ static void vParseTask(void *pvParameters) { UartMsg_t msg; for (;;) { if (xQueueReceive(xUartQueue, &msg, portMAX_DELAY) == pdTRUE) { /* 处理 msg */ } } }

这里的关键是portYIELD_FROM_ISR,它确保如果中断唤醒了更高优先级任务,退出中断后立刻切换过去,而不是等下一个 tick。少了这一句,实时性会打折扣。

再说硬件抽象。把 GPIO、USART、SPI 的初始化各自封成一个bsp_xxx_init()函数,放在独立的 bsp 目录下。任务函数里只调 bsp 接口,不直接碰寄存器。这样以后换芯片型号,只需要改 bsp 层,任务代码一行不动。

最后是日志系统。用printf打日志在 RTOS 里有个隐患:多个任务同时调printf会互相穿插,输出乱成一团。解决办法是加一个互斥量:

static SemaphoreHandle_t xLogMutex = NULL; void log_init(void) { xLogMutex = xSemaphoreCreateMutex(); } void log_printf(const char *fmt, ...) { va_list args; if (xSemaphoreTake(xLogMutex, pdMS_TO_TICKS(100)) == pdTRUE) { va_start(args, fmt); vprintf(fmt, args); va_end(args); xSemaphoreGive(xLogMutex); } }

这样每个任务的日志都是完整的一行,不会出现半行被截断的情况。互斥量的超时设成 100ms,避免某个任务持有锁不放导致其他任务永久阻塞。

改造完之后,验证方法很简单:创建三个任务分别以不同频率翻转三个 LED,同时通过队列传递计数,用逻辑分析仪抓三个 IO 的波形。如果三个 LED 各自独立闪烁且互不干扰,队列数据也能正确传递,说明框架搭稳了。从那以后我每次移植 RTOS,都会先把队列和互斥量这两样东西配好再写业务逻辑,不然等到任务多起来再补,改动量会大到让你想重写。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

Spring Boot 整合微信小程序 AccessToken 缓存与分布式锁实战

Spring Boot 整合微信小程序 AccessToken 缓存与分布式锁实战

1. 项目背景与整体设计思路做过微信小程序后端对接的同学应该都有体会,AccessToken 这玩意儿看着简单,真到项目里落地的时候,坑是一点都不少。我最近刚把一个 Spring Boot 服务和小程序做对接,核心需求就是稳定地获取和管理 Acces…

2026/10/19 19:17:17 阅读更多 →
计算机网络基本概念实战指南:从OSI到TCP/IP的分层排查思维

计算机网络基本概念实战指南:从OSI到TCP/IP的分层排查思维

1. 为什么还要回头聊“计算机网络基本概念”你可能觉得奇怪,都什么年代了,怎么还有人写计算机网络基本概念这种“大一第一课”的内容。我一开始也这么想,直到最近帮几个朋友排查问题,发现一个很普遍的现象:很多人能写代…

2026/10/19 19:17:17 阅读更多 →
open-code-review:基于CLI+Diff+LLM Agent的可审计代码审查范式

open-code-review:基于CLI+Diff+LLM Agent的可审计代码审查范式

1. 这不是另一个“AI代码审查工具”,而是一套可落地的开源协作新范式 “open-code-review”这个词组乍看像某个新发布的CLI工具名,但实际它指向的是一类正在快速成型的技术实践:用开源、透明、可审计的方式,把大模型驱动的代码审…

2026/10/19 19:17:17 阅读更多 →

最新新闻

L应用内存取证复盘:蓝队如何从内存镜像还原攻击链路

L应用内存取证复盘:蓝队如何从内存镜像还原攻击链路

我去年处理过一起很有意思的应急事件:某企业内部办公应用L在深夜出现异常外联,登录日志被攻击者清得干干净净,磁盘上能翻到的痕迹少得可怜。但内存镜像拉下来之后,攻击者的后门配置、窃取的会话凭证、甚至绕过二次认证的完整链路全…

2026/10/19 20:09:45 阅读更多 →
4G基站同步异常致小区不可用:从GPS失锁到同步板卡更换复盘

4G基站同步异常致小区不可用:从GPS失锁到同步板卡更换复盘

那天午休刚结束,值班手机弹出一条告警:某4G站点的所有小区同步异常,随后状态快速转成“小区不可用”。这种告警在维护群里并不少见,但真正让人紧张的,是它已经从“失步”一路演变到整站掉线,等于现场业务直…

2026/10/19 20:09:45 阅读更多 →
零基础手作项目artcraft:从创意到实物的完整流程

零基础手作项目artcraft:从创意到实物的完整流程

artcraft 这名字听起来有点像某个游戏 ID,但对我来说,它其实是一间可以随身带走的临时手作工作室。这个项目我已经断断续续做了快两年,核心只有一句话:把脑子里的创意,变成手里拿得住的实物。它没有标准流程&#xff0…

2026/10/19 20:09:45 阅读更多 →
ARIMA模型输出参数解读:Python与R双实现的时间序列预测实战

ARIMA模型输出参数解读:Python与R双实现的时间序列预测实战

先把话放前面:这篇文章不是讲“怎么把ARIMA跑通”的入门教案,而是讲“跑通之后,那些输出参数到底该怎么看、怎么用”。我之前折腾过一个销售预测任务,代码确实整出了预测曲线,项目汇报时也讲得头头是道,结果…

2026/10/19 20:09:45 阅读更多 →
从设计规范到性能优化:前端图表设计系统搭建实战

从设计规范到性能优化:前端图表设计系统搭建实战

1. 项目概述:一张设计稿背后的"图表设计系统"先交代一下背景。我是在做某个跨平台数据产品时,被逼着做了这个代号为diagram-design的项目。说白了,就是一套能把"原始数据"变成"规范图表"的前端图表设计与渲染方…

2026/10/19 20:09:45 阅读更多 →
Postman接口串联实战:变量作用域、提取脚本与执行顺序控制

Postman接口串联实战:变量作用域、提取脚本与执行顺序控制

1. 接口串联的真实痛点与整体设计思路做过接口测试的人几乎都遇到过这种场景:你手里有两个接口,A接口是业务主流程,B接口是前置依赖。A接口的请求体里有一个必填字段,而这个字段的值必须从B接口的响应里拿。比如下单接口需要一个动…

2026/10/19 20:08:44 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →