树莓派Pico迷你开发板MicroPython多线程编程实践

本文详细介绍了树莓派Pico开发板基于MicroPython的多线程编程,包括多线程基础知识、MicroPython底层线程API以及在RP2040双核芯片上的应用实践。通过示例代码展示了如何利用全局变量和锁机制实现线程同步,并总结了在Pico双核MCU上进行多线程编程的关键点。
摘要由CSDN通过智能技术生成

内容目录:
一、多线程基本知识
二、MicroPython/Python低层多线程API介绍
三、树莓派Pico 开发板MicroPython多线程编程实践举例
3.1 Pico RP2040 MCU双核芯片多线程同步的基本原理
3.2 Pico MicroPython多线程编程实践举例
3.3 Pico RP2040 MCU双核芯片MicroPython多线程编程小结
一、多线程基本知识
一个进程(Process)就是一个正在执行的程序,每个进程都有自己独立的一块内存空间和一组系统资源。在进程的概念中,每个进程的内部数据和状态数据都是完全独立的。
在一个进程中可以包含多个线程,多个线程共享一块内存和一组系统资源。因此,系统在各个线程之间切换时,开销要比进程小得多,正因为如此,线程又称为轻量级进程。
Python程序至少有一个线程,这就是所谓的主线程,程序在启动时由Python解释器负责创建主线程,在程序结束后由Python解释器负责停止主线程。在多线程中,主线程负责其他线程的启动、挂起、停止等操作,其他线程被称为子线程。
线程管理包括线程创建、线程启动、线程休眠、等待线程结束和线程停止等操作。
二、MicroPython/Python低层多线程API介绍
MicroPython/Python中的_thread低层线程模块提供了操作多个线程(又称为轻量级进程或任务:light-weight processes or tasks)的底层多线程API(多个控制线程共享全局数据空间)。为了处理多线程同步问题,它提供了简洁的锁机制(也称为互斥锁或二进制信号量:mutexes or binary semaphores)。Python官方还提供了threading线程模块,它是基于_thread低层线程模块而构建的,threading模块提供了用于Python多线程的高级API。
-thread模块定义的常用函数如下:
(1) exception _thread.error:发生线程相关错误时抛出。
(2)_thread.LockType:锁对象的类型。
(3) _thread.start_new_thread(function, args[, kwargs]):启动新线程并返回其标识。线程执行函数 function 附带的参数列表 是args (必须是元组);可选的 kwargs 参数用于指定一个关键字参数字典。
(4)_thread.exit():抛出 SystemExit 异常。
(6)_thread.allocate_lock():分配并得到一个新的锁对象(lock object)。后面假设新的锁对象名称为lock。
对于lock锁对象,该锁对象方法如下:
a) lock.acquire(waitflag=1, timeout=-1): 没有任何可选参数时,该方法无条件申请获得锁,有必要的话会等待其他线程释放锁(同时只有一个线程能获得锁)。如果成功获取到锁返回 True,否则返回 False。
b) lock.release(): 释放锁。锁必须已经被获取(不一定是在同一个线程中获取的)。
c) lock.locked(): 返回锁的状态:如果锁被某个线程获取,则返回 True,否则返回 False。
另外,锁对象也可通过 with 语句来使用,如:
import _thread
lock = _thread.allocate_lock()
with lock:
print(“lock is locked while this executes.”)
这里要特别说明的是,在多核概念及多线程编程中,锁又称为二进制信号量(简称信号量, semaphore),因此,锁对象也叫信号量对象。关于Python低级线程API英文说明文档,可参考文献[1]。
三、树莓派Pico开发板MicroPython多线程编程实践举例
1.Pico RP2040双核芯片多线程同步的基本原理
Raspberry Pi Pico开发板的MCU采用了ARM Cortex-M0架构的RP2040芯片,该芯片拥有两个核Core0和Core1,它允许执行多线程程序。一般在MicroPython MCU应用场景下,树莓派Pico没有管理MCU及系统资源的嵌入式操作系统,因此每个核只允许执行一个线程,最多执行两个线程,见图1所示。
在这里插入图片描述
图1 采用锁机制的线程同步
在图1中,线程Thread1在RP2040 MCU芯片第1个核(Core0)中执行,线程Thread2在RP2040 MCU芯片第2个核(Core1)中执行,线程Thread1和线程Thread2共享一组系统资源。其中,锁Lock (又称为信号量,A.K.A Semaphore) 用于实现两个线程的同步,acquire方法用于无条件申请获得锁对象,release方法用于释放锁对象。
2.Pico MicroPython多线程编程实践举例
这里以树莓派Pico开发板扩展一只按键、两只LED灯接口电路为例(见图2),给出MicroPython多线程控制两只LED灯亮灭的程序示例。图2的上半部为Pico开发板扩展硬件接口原理图,图2的下半部为Pico开发板扩展硬件接口面包板接线图。Pico开发板扩展按键接口的方法有两种,这里采用第一种按键接口方法,关于Pico迷你开发板扩展按键接口的方法详见参考文献[2],本文不再赘述。 在这里插入图片描述
图2 Pico开发板扩展一只按键、两只LED灯接口电路原理图及面包板接线图
MicroPython程序示例1:使用RP2040单核;当图2中的Button按钮被按下时,两只LED灯点亮;松开Button按钮时,延时200ms,两只LED灯熄灭。

#Filename: main.py
#press_button按键采用第一种按键接口方法
import machine
import utime
led_red=machine.Pin(20,machine.Pin.OUT)
led_green=machine.Pin(17,machine.Pin.OUT)
press_button=machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP)
while True:
  if press_button.value()==0:
     led_red.value(1)
     led_green.value(1)
     utime.sleep(0.2)  #休眠200ms
  led_red.value(0)
  led_green.value(0)

MicroPython程序示例2:使用RP2040双核的多线程编程方法1-全局变量法

import machine
import utime
import _thread
led_red=machine.Pin(20,machine.Pin.OUT)
led_green=machine.Pin(17,machine.Pin.OUT)
press_button=machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP)
button_pressed =False
def read_button_thread():
    global button_pressed
    while True:
        if press_button.value()==0:
            button_pressed=True
        utime.sleep(0.01)  #休眠10ms
_thread.start_new_thread(read_button_thread,())
while True:
    if button_pressed==True:
        led_red.value(1)
        led_green.value(1)
        utime.sleep(0.2)
        button_pressed =False
    led_red.value(0)
led_green.value(0)

程序示例2说明:在本程序中,read_button_thread()为自定义的读取按键线程函数,button_pressed定义为全局变量,该全局变量用于双线程操作。执行本程序后,_thread.start_new_thread方法启动读取按键线程操作read_button_thread,可理解读取按键操作是执行图1中的Thread2 (即在RP2040芯片第2个核Core1中执行);而当图2中的Button按钮被按下后的两只LED灯点亮操作是执行图1中的Thread1(即在RP2040芯片第2个核Core1中执行)。
MicroPython程序示例3:使用RP2040双核的多线程编程方法3-采用锁机制的多线程同步法

import machine
import utime
import _thread
led_red=machine.Pin(20,machine.Pin.OUT)
led_green=machine.Pin(17,machine.Pin.OUT)

lock = _thread.allocate_lock()

def led_red_thread():
    while True:
        lock.acquire()
        led_red.value(1)
        utime.sleep(0.5)
        led_red.value(0)
        utime.sleep(0.5)
        lock.release()
        
_thread.start_new_thread(led_red_thread,())

while True:
    while True:
        lock.acquire()
        led_green.value(1)
        utime.sleep(0.5)
        led_green.value(0)
        utime.sleep(0.5)
        lock.release()

程序示例3说明:在本示例程序中,led_red_thread()为自定义的控制红色LED灯发光的线程函数,_thread.allocate_lock()方法为线程分配一个名为lock的锁对象。执行本程序后,_thread.start_new_thread方法启动控制红色LED灯发光的线程操作led_red_thread,可理解红色LED灯发光的控制操作是执行图1中的Thread2 (即在RP2040芯片第2个核Core1中执行);绿色LED灯发光的控制操作是执行图1中的Thread1 (即在RP2040芯片第1个核Core0中执行)。
3. Pico RP2040 MCU双核芯片MicroPython多线程编程小结
(1)我们可以在Pico RP2040 MCU芯片的双核(Core0、Core1)上执行线程,一个线程在一个核上执行(其中一个可视作主线程,另一个被视作子线程)。
(2)我们可以使用全局变量或者锁(信号量)进行RP2040 MCU芯片双核上的线程同步。
(3)Pico RP2040 MCU仅支持两个并发线程。
(4)通常,阻塞主线程的操作应该被放到子线程中处理。
参考文献:
[1]https://docs.python.org/3/library/_thread.html
[2]博主CSDN博文.树莓派Pico迷你开发板扩展按键接口的方法及MicroPython编程.

发布日期:2021年07月06日

  • 12
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
树莓派Pico开发板可以使用Arduino IDE进行编程。以下是使用Arduino IDE进行树莓派Pico开发板编程的步骤: 1. 安装Arduino IDE:首先,您需要下载并安装Arduino IDE。您可以从Arduino官方网站上下载适用于您的操作系统的最新版本。 2. 安装RP2040支持库:树莓派Pico开发板使用RP2040芯片,因此您需要安装RP2040支持库。在Arduino IDE中,打开“工具”菜单,选择“开发板”子菜单,然后选择“开发板管理器”。在搜索栏中输入“RP2040”,找到“Arduino Mbed OS RP2040 Boards”并点击“安装”。 3. 配置开发板:在Arduino IDE中,打开“工具”菜单,选择“开发板”子菜单,然后选择“Raspberry Pi Pico”。接下来,选择正确的端口和上传速度。 4. 编写代码:在Arduino IDE中,打开一个新的空白文件,编写您的树莓派Pico开发板的Arduino代码。您可以使用Arduino语言和库来编写代码,就像在其他Arduino开发板上一样。 5. 上传代码:将树莓派Pico开发板连接到计算机,并确保选择了正确的端口。然后,点击Arduino IDE工具栏上的“上传”按钮,将代码上传到树莓派Pico开发板上。 请注意,树莓派Pico开发板与传统的Arduino开发板略有不同,因此某些功能和库可能不可用或需要特殊配置。您可以参考树莓派Pico开发板的文档和示例代码,以了解更多关于使用Arduino IDE进行树莓派Pico开发板编程的详细信息。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁易学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值