Python能做嵌入式开发吗?先说结论:能,但你需要先接受一个前提——Python不是用来“替代C”的,它是嵌入式开发这个链条里多出来的一种选择,而且这套生态已经比大多数人想象中成熟。
我经常在硬件群里看到两种完全对立的回答。有人说Python只适合写写爬虫、做做数据分析,碰硬件就是浪费资源;另一个人直接甩出一段用MicroPython控制舵机、读取传感器、上报MQTT的视频。两边吵到最后也没个结论,原因是他们嘴里说的“嵌入式”根本不是同一个概念。一个想的是STM32上几十KB内存的裸机固件,另一个手里是一块能跑Linux的开发板,已经把Python当主力语言在做边缘视觉识别应用。
这篇文章就是写给那些准备动手、但还没摸清全景的人。我会把Python在嵌入式领域的真实生态铺开讲清楚:哪些硬件真的能跑,哪些场景是硬凑,哪些环节Python是主力,哪些环节Python只是辅助。读完你至少能判断,自己手头的项目到底适不适合用Python去碰。
1. 别急着站队:先看清你碰的是哪一层“嵌入式”
1.1 固件级、板级、应用级:三个经常被混淆的词
“嵌入式”这个帽子实在太大了,大到三个层级的开发工作可以互相不认识。我平时做技术交流时,会先让对面明确自己处在哪一层,否则后续讨论毫无意义。
固件级,指的是直接和单片机寄存器、外设中断、时钟树打交道的开发方式。典型场景是STM32、GD32、STC这类MCU,资源少得可怜,常常是几十KB的RAM配上几百KB的Flash。这个层级最传统的语言是C,近期Rust也在挤入,但生态还在早期。这里的核心矛盾是每字节都要精打细算,一个变量放哪儿、中断服务函数能写几行,都要心里有数。
板级,指的是带有应用处理器、能够运行Linux或者RTOS智能系统的硬件,常见的有各类ARM Cortex-A系列开发板、工业边缘盒子。这个层级的资源明显富裕,内存动辄几百MB甚至几GB,存储也有几个GB,跑一个CPython解释器毫无压力。Python在板级开发里可以承担大量业务逻辑:Web服务、图像处理、云平台对接、算法调度。如果你听到有人说“我天天用Python做嵌入式开发”,他大概率说的是这一层。
应用级,强调最终产品形态。一个设备内部可能有多个处理器:MCU负责电机控制,另一个应用处理器负责UI展示和联网。Python可以出现在应用处理器上,而MCU仍然跑C。也就是说,Python不是跟着“嵌入式的名字”走的,而是跟着“有没有足够的资源跑运行时”走的。
1.2 为什么不少老工程师会告诉你“Python不行”
说Python不适合做嵌入式的人,多数是把“嵌入式”默认等价成了“固件级开发”。他们脑子里出现的典型画面是一个Cortex-M0+内核的单片机,4KB的SRAM,要在20毫秒内完成一个高精度ADC采样,还要在硬件定时器中断里做PID输出。这种情况下Python确实不行,而且这不是优化能解决的,是机制层面的不匹配。
再往深一层说,C编译后的产物是直接烧进Flash里的机器码,CPU从上电那刻起就在执行这些指令,不需要额外的运行时。Python则不一样,无论是CPython还是MicroPython,本质都是“解释器加脚本”的组合。解释器本身要占Flash,运行时要占RAM,还要有面向对象系统、垃圾回收机制这些额外开销。把这些基础成本摊到一颗几块钱的MCU上,确实奢侈。
另外还有一个现实因素:很多固件工程师的成长路线是从寄存器到库函数再到RTOS,他们的工具链是Keil、IAR、GCC,调试器和示波器。Python在他们的体系里没有位置,也没有必要有位置。如果一个工程师说Python做不了嵌入式,不要立刻反驳,先问他做的是车身控制器还是物联网网关,聊完你会发现他说的完全正确。
1.3 Python真正插进嵌入式流程的点位
Python想在嵌入式世界里发挥作用,有三种完全不同的姿态。第一种是把自己作为“固件本体”,通过MicroPython这类精简解释器运行时,直接跑在MCU上。第二种是把自己作为“应用层主力”,跑在带Linux的处理器上,负责设备外层生态。第三种是把自己放在开发者的电脑里,通过串口、USB、GPIB等方式与嵌入式设备通信,辅助开发调试和产线测试。
这三种姿态不是互斥的,很多项目会同时用上两三种。举例来说,我做过一个农业环境监测设备:Cortex-M4单片机用C写主固件,负责传感器采集和继电器控制;一个运行Linux的边缘网关用Python开发,负责接收单片机串口数据、进行部分异常判断、推送到服务器;开发阶段我自己电脑上还用Python脚本自动给单片机烧录测试固件,并且模拟上位机反复发送指令,验证固件升级流程。
所以“Python能不能做嵌入式开发”应该改成“你要做的嵌入式项目,Python在其中能扮演什么角色”。这样提问才精准,也才能找到对应的工具链和硬件选型。
2. 一块板子在手:Python能跑的三种硬件路线
2.1 MCU里的解释器路线:MicroPython与CircuitPython
MicroPython是Python 3语言的一个精简实现,专门为微控制器设计,运行时会暴露machine模块,让你用Pin、I2C、UART、PWM等类直接操作硬件。CircuitPython则是Adafruit主导的一个分支,更偏教育和传感器生态,很多扩展板、屏幕、传感器模块都有现成驱动库。
这条路线适合的硬件主要集中在ESP32、ESP8266、RP2040、部分STM32开发板等32位MCU上。要注意,能跑和适合跑是两回事。一块Cortex-M0+核、32KB内存的入门MCU即使理论上能塞进MicroPython,实际开发体验也会让你怀疑人生。真正用MicroPython做开发的场景,我建议至少选择ESP32、RP2040这类内存放宽到几百KB、能够轻松使用网络协议栈的芯片。
选择MicroPython做产品有一个不得不提的现实:解释器固件搬运成本低,但性能和功耗表现主要取决于你的脚本质量。你不能把C语言里那套“一切都能精确控制”的思维搬过来。它适合做快速原型、小众智能硬件、教学项目,以及需要在设备端动态修改逻辑的场景。
2.2 能跑Linux的处理器:Python以应用进程方式工作
嵌入式Linux设备是Python的主场。在这一层,Python不再是“精简版解释器”,而是完整的CPython环境,系统里装上Python 3解释器之后,你用pip安装的库几乎都能正常工作。
比如一个带触摸屏的工业控制面板,界面可以用Qt用C++写,也可以用Python配合PySide6快速搭建。硬件访问能力也绝对够用:通过libgpiod操作GPIO,通过spidev和smbus连接SPI/I2C外设,通过python-can读写CAN总线,这些库在嵌入式Linux社区非常成熟。
在做智能摄像头或端侧视觉检测时,Python的优势更明显。OpenCV、NumPy、PyTorch这些库直接运行在Linux板卡上,可以省下大量跨语言接口开发时间。你会发现一个规律:只要处理器能够跑起Linux,Python的生态丰富度几乎不输PC设备。唯一要注意的是交叉编译和部署问题,有些第三方库里包含C扩展,需要在目标平台上编译出对应的.so文件。
2.3 PC加板卡加仪器:上位机才是Python最早真香的区域
还有一个常被忽略的路线:嵌入式硬件不变,Python跑在你的电脑上,扮演上位机、调试工具、产测软件的开发者角色。这个玩法从Python诞生没多久就有人用了,也是很多硬件工程师实际上最先接触Python的地方。
PySerial去读写串口,PyUSB去操作USB设备,PyVISA去控制示波器、万用表、频谱仪,socket去连设备的网络服务,这些库的稳定性比很多厂商自带工具都靠谱。更重要的是,你可以把测试逻辑写成脚本,提交到CI里,每次固件更新后自动跑一遍整机冒烟测试。这在硬件开发里带来的效率提升,甚至比在MCU里硬塞MicroPython更可观。
三种路线放在一起对比会更清楚:
| 路线方向 | 典型硬件 | Python运行形态 | 开发重点 | 适合人群 |
|---|---|---|---|---|
| MCU解释器 | ESP32、RP2040 | MicroPython/CircuitPython | 硬件IO、网络协议、脚本逻辑 | 创客、快速原型、教学 |
| 嵌入式Linux | ARM Cortex-A开发板 | CPython进程 | 应用逻辑、视觉、Web服务 | 物联网产品、边缘计算 |
| 上位机辅助 | PC连接板卡/仪器 | 完整Python环境 | 自动化测试、数据分析 | 硬件工程师、测试工程 |
看明白这张表之后,你就不会再去问“Python能不能替换C”这类问题了。Python和C各自擅长一段,真正的嵌入式老手从来不选边站,他只会把合适的语言放到合适的层级里。
3. 第一步实践:用ESP32加MicroPython跑通一个真实项目
3.1 为什么第一块板子选ESP32
在MicroPython生态里,ESP32几乎是最省心的起点。原因有三个:价格足够低,坏了不心疼;内置Wi-Fi和蓝牙,能让脚本快速展示联网能力;第三方资料极其丰富,无论是官方文档还是社区案例,随便一搜就有大量可直接参考的代码。
STM32也不错,但是在MicroPython社区里,不同型号的固件适配参差不齐,还需要你自己确认板载Flash和RAM是否足够。RP2040也可以,尤其是喜欢砸键盘焊接的人,它的外设库文档很友好。但第一条路我仍然建议ESP32,因为“能让设备连上网”这个正反馈,会让你更有动力走下去。
实际开发中还要分清模组和开发板。建议直接买带USB转串口芯片的开发板,比如常见的ESP32 DevKitC,插上USB线就能进入下载模式。你需要提前装好USB转串口驱动,Windows上通常是CP210x或者CH340,装好之后能在设备管理器里看到一个新的COM口。
3.2 烧录固件:从擦除到写入的完整链路
MicroPython固件本身要从MicroPython官网下载对应板卡的bin文件。烧录工具通用的是esptool,它是Python写的,同时也证明了Python在嵌入式工具链里的存在感。
用Python包管理器安装esptool非常简单:
python -m pip install esptool擦除整片Flash前,先确认串口号。Linux下通常是/dev/ttyUSB0,macOS是/dev/cu.usbserial-xxxx,Windows是COM3这类名字。可以用esptool.py chip_id探测一下,能返回芯片信息说明通信没问题。
esptool.py --port COM3 erase_flash esptool.py --port COM3 write_flash -z 0x1000 ESP32_GENERIC-20240101-v1.23.0.bin注意ESP32的固件写入偏移量通常是0x1000,这是引导程序所在的位置。如果你写错了地址,板子会变砖,但通常重新擦除再烧就能救回来。烧录完成后,用任意串口工具连接115200波特率,或者直接用mpremote连接:
python -m pip install mpremote mpremote connect COM3 repl看到>>>提示符,说明MicroPython已经在运行了。这个提示符叫REPL,可以直接敲Python代码交互执行。
3.3 让LED和按键先协作起来
新环境跑通了,先做一个简单的按键控制LED程序。ESP32开发板上的LED一般接到GPIO2,也有的型号不同,最好查一下原理图。按键我通常用IO0,这块引脚同时是BOOT按键,按下为低电平。
from machine import Pin import time led = Pin(2, Pin.OUT) button = Pin(0, Pin.IN, Pin.PULL_UP) press_count = 0 while True: if button.value() == 0: press_count += 1 led.value(press_count % 2) print("press count:", press_count) time.sleep_ms(200)这段逻辑并不复杂,但里面有几个嵌入式相关的细节值得展开。
Pin.PULL_UP启用了内部上拉电阻,保证按键悬空时读到高电平,按下时拉到地变成低电平。判断button.value() == 0比判断== 1更安全,因为外部干扰通常把信号拉低导致误触发,不过具体还要看电路设计。time.sleep_ms(200)是简单消抖,防止一次按键按下产生多次计数。真正产品级消抖应该用定时器加状态机,但初学阶段用延时理解原理最直接。
你也可以用GPIO中断替代轮询,这样MCU在按键没有触发时可以去做别的事:
from machine import Pin led = Pin(2, Pin.OUT) button = Pin(0, Pin.IN, Pin.PULL_UP) def on_press(pin): led.toggle() button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)MicroPython的中断处理函数要求尽量短小,不要在回调里做耗时操作,也不要用sleep。如果确实需要处理复杂逻辑,通常的做法是在中断函数里设置一个标志位,然后在主循环里处理它。
3.4 把无线模块变成项目的核心能力
ESP32最吸引人的还是联网能力。连上家里的Wi-Fi只需要几行代码:
import network import time wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): wlan.connect("你的SSID", "你的密码") while not wlan.isconnected(): time.sleep_ms(500) print("connecting...") print("connected:", wlan.ifconfig())连上Wi-Fi之后,你可以用MicroPython自带模块做HTTP请求。比如读取一个JSON接口的数据,再去控制LED闪烁。这种玩法在传统固件开发里写起来相当麻烦,但Python把网络栈的复杂度都隐藏在标准库里了。
Web服务端也很容易搭,在MicroPython的microdot框架或者原始socket连接上略作封装,就能让手机通过浏览器访问设备状态。作为动手派,你完全可以做一个小项目:设备每隔5秒读取温度传感器,同时开启一个Web服务,手机打开页面就能看到实时温度。这一套流程下来,你对Python嵌入式开发的核心链路就有体感了。
4. 被真实硬件教育过才会懂:性能和资源的边界
4.1 内存和Flash的实用下限
Python跑在MCU上不是不能跑,但你对资源要有清醒认知。一个相对完整的MicroPython固件占用Flash通常以几百KB计算,运行时要留出几十KB级别的RAM给堆和栈。对于ESP32这种Flash有4MB、RAM有520KB的芯片,毫无压力;对于很多寄存器级小芯片,压力就不小。
我强调过很多次:能用和好用是两个维度。在MicroPython的世界里,我建议你只考虑RAM在160KB以上的MCU,否则经常会遇到内存分配失败的异常。你写一行字符串拼接可能就会触发垃圾回收,设备会出现几十毫秒甚至更长的卡顿,这在控制类场景里是不能接受的。
选型之前先想清楚产品的内存峰值。MicroPython启动后,系统自身和运行时环境会占据一块固定开销,剩下的才留给你的变量、对象、网络缓冲区。如果你要处理一张较大的摄像头图像,或者要缓存一段音频,那对内存的需求会成倍增加。最简单的开发技巧是尽早做一些压力测试:循环创建对象、传输大文件、不断上报数据,看看什么时候会内存溢出。提前摸到边界,比写完整套代码再返工要高效得多。
4.2 垃圾回收、中断与实时性限制
Python语言的垃圾回收机制在PC上很自然,但放在嵌入式里就会变成一个不确定的延迟源。当可分配内存达到阈值时,运行时可能暂停当前代码去回收不再使用的对象,这个暂停时间对多数应用来说是体验问题,对控制应用来说可能就是事故。
MicroPython对这个问题做过一些优化,比如使用分代GC、优化分配器,但它本质上仍然不是硬实时系统。如果你需要在一个绝对精确的时间窗口内完成PWM波形切换,或者必须保证某个中断响应时间小于几微秒,Python脚本做不到,至少不如裸机C那样可控。
我常用的开发原则是:硬件中断里尽量只做置位和清标志这种极轻量操作,把真正耗时的工作放到主循环或调度器里去完成。如果协议层允许抖动,Python能扛过去;如果硬件时序要求严格,就得把时序敏感的部分用底层机制实现,Python只管业务逻辑。
4.3 当你发现自己撞上性能瓶颈之后
很多人一遇到性能问题就全盘否定Python,其实这是一种偷懒。解决办法往往是一层一层补:
最表层的优化是调整代码风格。Python在MCU上的慢,很多时候来自频繁的字符串拼接、循环里反复创建对象、不合理的类型转换。尽量避免分配临时对象、尽量用局部变量、尽量复用缓冲区,常常能获得数倍提升。
再深一层是使用MicroPython提供的编译优化手段。@micropython.native装饰器可以把Python函数编译成原生机器码,@micropython.viper还能进一步使用更多的底层类型提示。这些机制不是所有平台都完全支持,但用来加速热点计算函数是有效的。
最后兜底的手段是写C扩展。MicroPython允许你用C语言编写自定义模块,再把它链接进固件里。Python脚本负责调用、传参和业务编排,真正的算法核心用C实现。这种混合模式在工程里是最常见的:既要Python的开发效率,又要关键的实时性能。
5. 嵌入式开发里的“C与Python分工论”
5.1 量产固件里Python真的没位置吗
聊到量产,很多工程师会直接断言“量产不可能用MicroPython”。这句话对,但也不完全对。对于一部分对成本极其敏感、出货量巨大的消费电子产品,确实会把MCU选得很低端,然后把每一分钱都省下来,这个时候Python解释器等于额外增加了几块钱的Flash和RAM成本,属于不能接受的开销。
但如果产品本身定义就需要灵活的脚本更新逻辑,或者团队想在设备端做用户可编程能力,那么Python跑在MCU上就是一种商业选择。最典型的例子是教育硬件、传感器开发工具、自动化设备里的参数配置模块。这些产品的成本不敏感,但要求开发速度快,并且希望用户能通过像写Python脚本一样的方式去二次开发。
严格来说,MicroPython能不能量产,取决于你的成本账和可靠性要求,不存在绝对的“能”或“不能”。但多数量产项目更理性的做法是:在成本敏感的固件层用C,在有应用处理器的高层用Python,或者只拿Python做开发工具。选错了层级才是真正的问题。
5.2 原型验证的价值常常被低估
如果手头要做一个全新硬件产品的Demo,哪怕最终方案必定是C固件,我也会先拿MicroPython把整个链路跑通。原因很简单:Python让你快速验证的是逻辑,而不是语言本身的优劣。
传感器接口协议、上位机通信格式、UI交互流程、状态机迁移逻辑,这些东西在原型阶段会频繁调整。每改一次就用C重新编译烧录,时间成本太高。MicroPython里直接改脚本、按个重启键、看一下REPL输出,就能完成新一轮验证。等逻辑稳定了,再把它翻译成C固件,准确率会高很多。
有人觉得这样“白做一遍”,恰恰相反,这套原型代码本身就是最详细的伪代码文档。你从Python版本里可以清楚看到状态怎么切换、数据怎么流动、异常怎么处理,C工程师照着写会少走很多弯路。
5.3 用原生模块突破“Python做不到”的部分
在一些正式产品里也有折中方案:单片机里真正硬实时的核心继续用C编写,同时在固件中嵌入一个MicroPython虚拟机,让产品具备脚本化能力。这种架构在很多工业自动化品牌里并不罕见。
C层负责编码器读取、电机控制、电流环等必须硬实时的任务;Python层负责设置参数、读取诊断信息、和上位机交互。两层之间通过共享内存、消息队列或者回调函数通信。这样既保留了MCU底层控制的确定性,又获得了Python层的灵活性。
开发这种架构的技术门槛会高一些,需要你能修改MicroPython配置、裁剪不需要的功能,还要处理内存布局和调用接口。但对创业团队或非标设备开发团队来说,这种投入的回报非常高:产品发布后想增加一个通信协议,不需要升级固件,直接用Python脚本灌进去就行。
6. 别忽略的另一块拼图:硬件工程师的Python自动化台
6.1 串口、USB和仪表控制:这些库就像硬件万金油
不要只盯着“Python在板子上有没有跑起来”,硬件开发周期里有一大块工作量在电脑上完成,而Python是现代硬件工程师最值得修炼的辅助技能。
串口调试是最常见的场景。用PySerial收发数据并不是简单地替代串口助手,你可以把逻辑判断写进代码里,自动检查固件是否返回正确应答。比如刚烧录完一个设备,你可以直接写一个脚本自动扫描当前机器上的串口,逐个发送版本查询指令:
import glob import serial def enumerate_serial_ports(): ports = glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*") results = [] for port in ports: try: s = serial.Serial(port, 115200, timeout=0.5) s.write(b"$VER\r\n") response = s.read(128) results.append((port, response)) s.close() except serial.SerialException: continue return results for port, resp in enumerate_serial_ports(): print(port, resp)这段代码看起来很简单,但我实际使用中它帮我节省了大量重复劳动。生产线来了一批新板子,不需要一个个手动开串口助手点来点去,插上USB然后运行脚本,几十秒钟就能批量读完序列号和固件版本。
除了串口,PyUSB可以让你直接和USB HID设备、自定义USB设备通信。PyVISA则是一套操作GPIB、USB、LAN接口仪器的标准库,许多示波器、频谱分析仪、可编程电源都支持这个接口,Python控制它们做自动化老化测试,效率远高于手动记录。
6.2 产测自动化里常见的设计格局
产测在硬件行业经常被低估,但它是真正能体现工程水平的地方。一条普通的产品线,每天要测几百台设备,靠人肉点界面根本测不过来。Python产测脚本的通用模式是:被测设备上电后进入测试模式,电脑通过串口或Wi-Fi连接设备,依次发送测试指令,收集返回值,判断是否通过,最后把结果写进本地数据库或直接上传MES系统。
这里用到的核心技术点跟应用开发不太一样。你要处理并发和超时,因为多台设备可能同时连接电脑,需要区分不同串口;要做数据记录,每台设备的测试数据需要能追溯到批次;要处理错误和失败,一台设备不通过时不能中断整批测试,而要把问题记录下来。
Python在这些方面有天然优势:serial库处理通信,pandas和sqlite3处理记录,tkinter或PySide6做个简单的测试操作界面,再加一个logging日志模块,整条产测链路就能闭环了。
6.3 一个能立刻就用的冒烟测试代码框架
我分享一个适合大多数串口设备的冒烟测试框架雏形。它做四件事:连接设备、读取版本、控制一个GPIO输出、验证返回结果。
import serial import time def run_smoke_test(port): steps = [] with serial.Serial(port, 115200, timeout=1) as ser: ser.reset_input_buffer() ser.write(b"$VER\r\n") resp = ser.read(64) steps.append(("version", resp, b"v1." in resp)) ser.write(b"$LED,ON\r\n") time.sleep(0.2) ser.write(b"$LED,OFF\r\n") steps.append(("led_ctrl", True, True)) return all(ok for _, _, ok in steps) if __name__ == "__main__": print(run_smoke_test("COM3"))思路很简单,但你可以不断往里面塞协议测试项,比如读取传感器数值是否在合理范围内、切换工作模式后电流是否突变、Wi-Fi信号强度是否达标。每增加一个测试项,就是给产品多上了一道保险。Python让这道保险的边际成本变得很低,这也是很多大型硬件公司愿意招“懂硬件的Python工程师”的原因。
7. 说到底,选择标准是什么:我给动手派的建议
7.1 别问“Python能不能”,要问“这个项目值不值得”
每个人启动新项目时有不同的背景,所以我给不了“全行业通用”的准则,但可以给你一套我用了很久的判断模型。
如果你是做快速创意验证、学生竞赛作品、智能家居DIY、或者想给非技术朋友展示一套能交互的硬件Demo,直接选择MicroPython方案。你获得的是最快的“从想法到实物”路径,成本是放弃底层极致优化。
如果你要做电池供电的穿戴设备、高可靠电机控制、车规电子产品、或者量级达到数十万台的低成本消费电子,老老实实选C做固件,Python可以作为产测和开发工具存在。硬件越便宜、对功耗越敏感、生命周期越长,Python在“固件层”的存在感就越弱。
如果你面对的是带Linux的板卡、边缘设备网关、带摄像头的智能终端,那么Python不仅可以用,甚至可能成为主语言。尤其是视觉、Web后台、云对接这些需求多的时候,它在开发效率上对C的领先是压倒性的。
7.2 我在实际项目中积累下的几条选型经验
最后分享几条从踩坑里总结出来的经验,仅供参考。
第一,选型时把硬件资源余量留足,别卡着官方给的下限买。做了多年项目,最怕的就是“理论上够用”。运行Python的MCU,建议Flash和RAM都选择实际需求两倍以上的型号。很多芯片价格差异不大,但替换起来时间成本很高。
第二,一定保留一个调试口。MicroPython最舒服的开发姿势就是REPL实时交互,没有调试串口,很多设备状态只能靠猜。PCB设计时哪怕只留三个测试点,都会让后期调试轻松很多。
第三,Python脚本部署到设备时,最好形成版本管理习惯。我在项目里会把脚本上传到Git仓库,同时把版本号打印在启动日志里。出了事能知道设备里跑的是哪一版脚本,否则几个设备不同步会让排查变成灾难。
第四,也是最重要的一点,不要因为Python方便就不去读数据手册。即使你用MicroPython,也必须知道某个外设芯片的上电时序、某个总线的速率上限、某个引脚的驱动能力。Python帮你屏蔽的是寄存器操作细节,不是硬件物理世界的基本规律。
嵌入式开发说到底还是“用代码跟物理世界打交道”,Python给你提供了更顺手的对话方式,但你要懂得对面那个世界的脾气。先把手头板子的数据手册翻一遍,再把这篇全景图里提到的工具链跑一遍,你会发现Python做嵌入式开发,从来不是一句“能”或“不能”能概括的,它更像一把新钥匙,能打开哪扇门,取决于你想走进哪个房间。