Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
学习笔记
【rtthread学习笔记系列】第二篇:中断
发布于 2021-05-11 21:15:50 浏览:2855
订阅该版
[tocm] # 一、中断的概念 ## 1.1 rtthread中断处理过程 rtthread将中断分为三个过程:前导程序、中断服务程序、后续程序。 * 前导程序:保存cpu中断现场,m3核该部分由硬件完成,关于保存现场的寄存器有 PSR、 PC、 LR、 R12、 R3-R0。之后通知内核处理中断。 * 中断服务程序:在中断触发后要执行的用户操作。 * 后续程序:通知内核中断处理完成,恢复cpu现场。 ## 1.2 中断栈 rtthread会在中断的前期处理中切换栈指针到预先留出的中断栈空间,等中断退出时恢复用户的栈指针。 ## 1.3 中断低半部处理 低半部处理用于处理耗时长的操作,举一种使用信号量完成低半部的例子:线程demo_nw_thread阻塞在等待nw_bh_sem,在中断服务程序中释放nw_bh_sem信号让demo_nw_thread线程处理中断的低半部。 ``` rt_sem_t nw_bh_sem; /* 数 据 读 取、 分 析 的 线 程 */ void demo_nw_thread(void *param) { /* 首 先 对 设 备 进 行 必 要 的 初 始 化 工 作 */ device_init_setting(); /*.. 其 他 的 一 些 操 作..*/ /* 创 建 一 个 semaphore 来 响 应 Bottom Half 的 事 件 */ nw_bh_sem = rt_sem_create("bh_sem", 0, RT_IPC_FLAG_FIFO); while(1) { /* 最 后, 让 demo_nw_thread 等 待 在 nw_bh_sem 上 */ rt_sem_take(nw_bh_sem, RT_WAITING_FOREVER); /* 接 收 到 semaphore 信 号 后, 开 始 真 正 的 Bottom Half 处 理 过 程 */ nw_packet_parser (packet_buffer); nw_packet_process(packet_buffer); } } int main(void) { rt_thread_t thread; /* 创 建 处 理 线 程 */ thread = rt_thread_create("nwt",demo_nw_thread, RT_NULL, 1024, 20, 5); if (thread != RT_NULL) rt_thread_startup(thread); } void demo_nw_isr(int vector, void *param) { /* 当 network 设 备 接 收 到 数 据 后, 陷 入 中 断 异 常, 开 始 执 行 此 ISR */ /* 开 始 Top Half 部 分 的 处 理, 如 读 取 硬 件 设 备 的 状 态 以 判 断 发 生 了 何 种 中 断 */ nw_device_status_read(); /*.. 其 他 一 些 数 据 操 作 等..*/ /* 释 放 nw_bh_sem, 发 送 信 号 给 demo_nw_thread, 准 备 开 始 Bottom Half */ rt_sem_release(nw_bh_sem); /* 然 后 退 出 中 断 的 Top Half 部 分, 结 束 device 的 ISR */ } ``` # 二、中断api 要使用中断,首先需要装载一个中断,当中断触发时,就会进入中断处理函数处理。 * 可以通过rt_hw_interrupt_mask屏蔽指定中断号的中断,避免再次触发的中断对本次中断处理的影响。 * rtthread提供全局中断的打开和关闭api,这是rtthread线程同步的基础,利用全局中断的打开和关闭可以实现对临界区的保护。 ``` //装载中断 /* vector:中断号 handle:中断服务程序 param:中断服务程序的参数 name:中断的名称 */ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, char *name); //屏蔽中断:可避免再次触发的中断对正在处理的中断的影响 /* vector:中断号 */ void rt_hw_interrupt_mask(int vector); //取消屏蔽中断 /* vector:中断号 */ void rt_hw_interrupt_umask(int vector); //关闭全局中断 /* 返回函数执行前的中断状态 */ rt_base_t rt_hw_interrupt_disable(void); //打开全局中断,与关闭全局中断配合使用,保护临界区的效率比互斥锁高,对实时性影响较大。 /* level:中断状态 */ void rt_hw_interrupt_enable(rt_base_t level); //中断通知:修改中断深度 rt_interrupt_nest void rt_interrupt_enter(void); void rt_interrupt_leave(void); ``` # 三、中断与轮询 轮询模式采用顺序执行的方式:查询到相应的事件对其进行处理。这种方式在实时操作系统中存在的问题是低优先级的线程得不到cpu的使用权,所以通常情况下,RTOS使用中断来驱动外设。 对于低速的情况,中断模式非常好,cpu可以在等待数据到来前处理其它任务。但对于高速设备,由于操作系统切换上下文有8us的事件,如果处理一个25us的任务,数据带宽为8/(25+8)=75.8%,采用轮询模式不存在上下文切换的问题,数据带宽为100%。 # 四、示例 本示例的线程通过全局中断开关来保护全局变量。 ``` /* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first version */ /* 程序清单:关闭中断进行全局变量的访问 */ #include
#include
#define THREAD_PRIORITY 20 #define THREAD_STACK_SIZE 512 #define THREAD_TIMESLICE 5 /* 同时访问的全局变量 */ static rt_uint32_t cnt; void thread_entry(void *parameter) { rt_uint32_t no; rt_uint32_t level; no = (rt_uint32_t) parameter; while (1) { /* 关闭中断 */ level = rt_hw_interrupt_disable(); cnt += no; /* 恢复中断 */ rt_hw_interrupt_enable(level); rt_kprintf("protect thread[%d]'s counter is %d\n", no, cnt); rt_thread_mdelay(no * 10); } } int interrupt_sample(void) { rt_thread_t thread; /* 创建thread1线程 */ thread = rt_thread_create("thread1", thread_entry, (void *)10, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (thread != RT_NULL) rt_thread_startup(thread); /* 创建thread2线程 */ thread = rt_thread_create("thread2", thread_entry, (void *)20, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (thread != RT_NULL) rt_thread_startup(thread); return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(interrupt_sample, interrupt sample); ```
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
happycode999
这家伙很懒,什么也没写!
文章
28
回答
6
被采纳
0
关注TA
发私信
相关文章
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部