基于MicroPython的Raspberry Pi Pico W双核LED控制故障求助
Raspberry Pi Pico W MicroPython 线程控制LED故障排查建议
核心问题定位
你的代码里主线程长期占用锁资源,导致CoreTask线程根本无法获取锁执行LED控制逻辑:
- 主线程在最外层
while True循环开头就调用sLock.acquire(),但只有在HTTP连接处理的异常分支或请求处理完成后才释放锁。 - 当
s.accept()处于阻塞等待客户端连接状态时,主线程会一直持有锁,CoreTask线程无法进入临界区执行LED开关操作。
排查与修复步骤
验证线程执行状态
在CoreTask函数的while True循环开头添加打印语句:print("CoreTask trying to acquire lock"),如果终端只输出主线程的日志,完全看不到这条打印,说明线程被锁阻塞,无法执行。修正锁的使用逻辑
锁的作用是保护共享资源的临界区代码,而非整个业务流程。你的场景中LED仅由CoreTask操作,主线程未访问LED,因此锁是多余的,可直接删除锁相关代码:# 移除以下两行 # sLock = _thread.allocate_lock() # CoreTask中的sLock.acquire()和sLock.release()也一并删除如果后续有共享资源需要保护,需将锁的
acquire()和release()仅包裹在访问共享资源的代码段前后,避免长期持有锁。简化测试排除干扰
先注释掉主线程的网络连接、HTTP服务代码,只保留CoreTask线程,测试LED是否正常闪烁。确认线程和LED控制本身无问题后,再逐步恢复网络代码,每次恢复后测试,定位是否有其他阻塞逻辑影响线程执行。线程调度注意事项
MicroPython的_thread依赖时间片轮转或阻塞操作触发线程切换,避免在主线程中编写无阻塞的无限循环(除非主动调用utime.sleep()等让出CPU的操作),否则会抢占其他线程的执行时间。
修复后示例代码(简化锁逻辑)
import machine import _thread import network import socket import utime from machine import Pin led = machine.Pin('LED', machine.Pin.OUT) ssid = 'someSSID' password = 'somePASSWORD' wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.connect(ssid, password) html = """<!DOCTYPE html> <html> <body> <div id="humidity">100</div> <div id="temperature">21</div> </body> </html> """ def CoreTask(): while True: print('LED...') led.on() utime.sleep(1) led.off() utime.sleep(1) _thread.start_new_thread(CoreTask, ()) while True: # Wait for connect or fail max_wait = 10 while max_wait > 0: if wlan.status() < 0 or wlan.status() >= 3: break max_wait -= 1 print('waiting for connection...') utime.sleep(1) # Handle connection error if wlan.status() != 3: raise RuntimeError('network connection failed') else: print('connected') status = wlan.ifconfig() print( 'ip = ' + status[0] ) # Open socket addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] s = socket.socket() s.bind(addr) s.listen(1) print('listening on', addr) # Listen for connections while True: try: cl, addr = s.accept() print('client connected from', addr) request = cl.recv(1024) print(request) request = str(request) response = html cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n') cl.send(response) cl.close() except OSError as e: cl.close() print('connection closed')
内容的提问来源于stack exchange,提问作者bzc0fq
相关产品推荐
相关产品推荐

