ArtOS 快速开发框架

ArtOS 快速开发框架

首页
ArtOS框架
使用文档视频教程
Micropython
官方文档学习教程固件开发
发现
树莓派ESP32
生态圈
智能生活直播物联工业物联Node-RED
开发资源
开发板软件资源器件资源
关于ArtOS
登录 →
ArtOS 快速开发框架

ArtOS 快速开发框架

首页 ArtOS框架
使用文档视频教程
Micropython
官方文档学习教程固件开发
发现
树莓派ESP32
生态圈
智能生活直播物联工业物联Node-RED
开发资源
开发板软件资源器件资源
关于ArtOS
登录
  1. 首页
  2. Micropython
  3. 学习教程
  4. Micropython中的ISR操作

Micropython中的ISR操作

0
  • 学习教程
  • 发布于 2025-12-24
  • 13 次阅读
极客熊
极客熊

一、什么是ISR?

ISR (Interrupt Service Routine) 是在硬件中断触发时执行的一段代码。中断是硬件事件,它允许处理器暂停当前任务,转而执行对特定事件的响应代码。

主要特点:

  • 触发条件:当某些硬件外设(例如定时器、外部引脚、串口接收数据等)触发中断时,ISR 会被调用。

  • 优先级和响应:ISR 通常具有较高的优先级,因此它能够中断正在执行的任务或代码。

  • 执行方式:ISR 中的代码必须尽可能短小,以尽快释放中断,让主程序能够继续执行。

ISR 基本规则

ISR 基本规则

  1. 尽量简短

    • ISR 中应尽可能只做状态更新、计数器累加或触发事件。

    • 不应做耗时操作(如打印、延时、网络请求、I/O)。

  2. 禁止阻塞操作

    • 不能在 ISR 中使用 time.sleep()、while 等会阻塞 CPU 的操作。

    • 不能在 ISR 中使用常规的锁(Lock)、信号量(Semaphore)等可能阻塞的对象。

  3. 可使用的原子操作

    • 对整数的赋值和布尔状态更新是原子操作(尤其是 32 位整数)。

    • 对于复合操作(如 x += 1),如果不保证原子性,可能会出现竞态。

注意事项:

  • 不可阻塞:ISR 不能调用可能阻塞的函数,如 sleep 或等待其他资源。

  • 不可进行复杂操作:由于 ISR 必须尽快完成,通常不推荐在 ISR 中执行复杂的计算或操作,特别是那些涉及到动态内存分配的操作。

  • 共享资源访问:如果 ISR 访问共享资源,可能会导致数据竞争问题,必须通过互斥锁、原子操作等手段避免。

二、什么是原子操作?

原子操作(Atomic Operation)是指在执行过程中不可被中断、不可被分割的操作,要么全部完成,要么完全不做。

1、原子操作的特性

  • 不可中断,在多任务 / 中断环境下,不会因为中断或任务切换而被打断

  • 一致性,对共享变量的修改是“要么完成,要么不完成”

  • 最小粒度,通常是 CPU 支持的基本操作(读 / 写单个寄存器、加减整数)

2、常见的原子操作示例

1️⃣ 简单变量赋值(在 MCU 上通常是原子)

irq_flag = True
irq_count += 1   # 在某些 32-bit MCU 上单次加法也是原子

条件:

  • 变量大小 ≤ CPU 数据总线宽度(8/16/32 bit)

  • 没有复杂操作(例如 += 包含读 - 改 - 写,需要注意 MCU 架构)

2️⃣ 位操作(单独一条指令)

result = a & b # 按位与(AND)&
result = a | b # 按位或(OR)|
result = a ^ b # 按位异或(XOR)^
result = ~a # 按位取反(NOT)~
result = a << 2 # 左移(Shift Left)<<
result = a >> 2 # 右移(Shift Right)>>
result = a & mask # 掩码操作
packed = (status << 4) | command # 位域(Bit fields)

3️⃣ CPU 特殊指令

通过 machine.mem32 来访问和修改内存地址上的数据

import machine

# 访问指定的内存地址,通常是 CPU 特定寄存器
machine.mem32[0x3FF5A000] = 0x12345678  # 写入特定的寄存器
value = machine.mem32[0x3FF5A000]      # 读取寄存器的值
print(hex(value))

控制寄存器与中断管理

import machine

# 设置一个引脚产生中断
pin = machine.Pin(15, machine.Pin.IN, machine.Pin.IRQ_RISING)

# 中断服务程序
def irq_handler(pin):
    print("Interrupt triggered")

# 设置中断处理函数
pin.irq(trigger=machine.Pin.IRQ_RISING, handler=irq_handler)

处理器状态寄存器

import machine

# 进入深度睡眠模式
machine.deepsleep(5000)  # 等待5秒后恢复

三、MicroPython 提供的 ISR 安全接口

1、Pin 中断

  • Pin.irq() 会将 handler 注册为 ISR。

  • trigger 可选:IRQ_RISING、IRQ_FALLING 或 IRQ_RISING | IRQ_FALLING。

2、micropython.schedule()

  • 用于在 ISR 中“延迟执行”复杂操作。

  • ISR 内只做轻量操作,然后调用 micropython.schedule() 把复杂任务交给主线程执行。

  • 限制:schedule 函数最多只能有 32 个任务排队(具体视 MicroPython 版本)。

  • 参数必须是小整数或小对象,避免大型对象。

import micropython

def deferred_task(arg):
    # 这里可以安全执行复杂操作,如打印、I/O
    print("Deferred task:", arg)

def irq_handler(pin):
    micropython.schedule(deferred_task, 42)

pin = Pin(15, Pin.IN)
pin.irq(trigger=Pin.IRQ_RISING, handler=irq_handler)

3、原子操作指令

  • 整数赋值或状态机切换

  • 可以暂时禁用中断,保证原子性操作。micropython.disable_irq() / micropython.enable_irq()

4、共享数据

  • ISR 内共享数据建议使用整数、布尔量、列表或数组的单个元素。

  • 对于多字节数据,使用 micropython.schedule() 来保证安全。

四、ISR 中不能做,禁止的操作

  • 文件 I/O

  • 网络请求

  • 分配大量内存(避免触发垃圾回收)

  • print()(ESP32 可以少量打印,但不安全)

  • 阻塞锁、事件等待

五、总结

1、可执行操作

类别

指令 / 方法

说明

示例

中断注册

Pin.irq(handler=...)

注册 ISR 处理函数

pin = Pin(15, Pin.IN); pin.irq(trigger=Pin.IRQ_RISING, handler=irq_handler)

延迟执行复杂任务

micropython.schedule(func, arg)

在主线程执行耗时操作,如打印、I/O

micropython.schedule(deferred_task, 42)

原子操作

整数或布尔赋值

直接修改共享状态

flag = True

中断控制

micropython.disable_irq() / micropython.enable_irq(state)

主线程修改共享数据时保护原子性

irq_state = micropython.disable_irq(); counter += 1; micropython.enable_irq(irq_state)

寄存器 / 内存访问

machine.mem32[addr] = value

直接访问硬件寄存器

machine.mem32[0x3FF5A000] = 0x12345678

计数器 / 状态机更新

计数器累加、状态切换

快速修改变量状态

counter += 1 / state = NEXT_STATE

2、禁止操作

类别

操作示例

原因

阻塞操作

sleep(), time.sleep_ms(), while not flag:

阻塞 ISR 会延迟系统中断响应

大量内存分配

创建大对象、列表、字典

可能触发垃圾回收,导致 ISR 异常

I/O 操作

print()、UART / SPI / I2C 传输

可能阻塞或触发异常

锁 / 信号量

Lock.acquire() 等

阻塞操作会导致死锁

网络操作

socket.send()

网络可能阻塞,ISR 不允许

3、共享数据策略

  • 使用整数或布尔值:单次写入通常是原子操作。

  • 复杂对象:使用 micropython.schedule() 延迟处理。

  • 复合操作使用 disable_irq():

irq_state = micropython.disable_irq()
counter += 1
micropython.enable_irq(irq_state)

4、平台特定 ISR 技巧

ESP32

  • 可直接操作寄存器:machine.mem32。

  • 可操作 GPIO、定时器寄存器。

  • 支持 micropython.schedule() 延迟任务。

STM32

  • 可访问 machine.mem32 或 pyb 模块。

  • 可通过 Timer / UART ISR 实现高速采样。

相关文章
在Micropythond中如何判断回调的方法是协程方法?

在Micropythond中如何判断回调的方法是协程方法?

三个函数方法: async def test1(): print(f'async fn') def test2(): print(f'fn') async def test1(arg1: int): print(f'async fn {arg1}') 我们

ISR在Micropyhon学习过程中,各阶段关注点

ISR在Micropyhon学习过程中,各阶段关注点

在嵌入式开发中,ISR(中断服务例程)安全性不是一开始就必须深究的内容,而是随着你对系统理解加深和实际项目需求出现时,才逐步成为重点关注的内容。下面我给你梳理一个学习阶段路线和对应关注点: 阶段 1:入门阶段(硬件和基础语言) 目标<

Micropython中的ISR操作

Micropython中的ISR操作

一、什么是ISR? ISR (Interrupt Service Routine) 是在硬件中断触发时执行的一段代码。中断是硬件事件,它允许处理器暂停当前任务,转而执行对特定事件的响应代码。 主要特点: 触发条件:当某些硬件外设(例如定时器、外部引脚、串口接收数据等)触发中断时,ISR 会被调用。

目录
  • 极客熊
  • 极客熊
  • 极客熊
Copyright © 2026 ArtOS All Rights Reserved. Powered by ArtOS.