5、FreeRTOS - 中断

中断,在任务函数运行的过程中,出现了特定的中断触发条件(中断源,其实就是识别到中断标志位发生改变),让 CPU 打断原本正在运行的程序,转而去处理紧急事件(ISR),执行中断服务函数,处理完后又返回原来被暂停的位置继续运行。

 

中断的执行机制:(从触发中断到结束的过程)

 中断请求:外设产生中断请求(GPIO外部中断、定时器中断等)

        ↓

响应中断:CPU停止执行当前程序,转而去执行中断处理程序(ISR)

        ↓

退出中断:执行完毕,返回被打断的程序处,继续往下执行

 

中断优先级:

当有多个中断源同时申请中断时,CPU 会根据中断源的优先级大小来进行裁决,决定哪个中断优先执行。中断优先级数值越小,越先执行,跟 FreeRTOS 任务优先级相反,任务优先级是越大越优先执行。

 

 ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器,所以中断优先级配置范围在 0~255,可配置的中断优先级范围很大。跟 ARM Cortex-M 相比,STM32 只用了中断优先级配置寄存器的高4位 [7 : 4](即 8 位寄存器中只用了 4~7 这4位,不使用低四位 0~3),所以STM32提供了最大16级(即 0~15)的中断优先等级,如下图

05a367153b844da18ad93d9d28d29afc.png

 

 STM32 的中断优先级可分为抢占优先级和子优先级:

抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断。

 

子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行。

 

两者区别:子优先级高的并不能打断正在执行的其他任务的,只能等待任务执行完才能轮到他。类似排队做核酸,子优先级高的是直接插入准备做核酸的下一位,而抢占优先级高的是直接把核酸做一半的人赶走,自己来做。

 

中断优先级共有5种优先级分组方式:(根据中断优先级配置寄存器的4位的不同配置来分组)

NVIC_PriorityGroup_0:0个bit 用于抢占优先级,4个bit 用于子优先级

NVIC_PriorityGroup_1:1个bit 用于抢占优先级,3个bit 用于子优先级

NVIC_PriorityGroup_2:2个bit 用于抢占优先级,2个bit 用于子优先级 

NVIC_PriorityGroup_3:3个bit 用于抢占优先级,1个bit 用于子优先级

NVIC_PriorityGroup_4:4个bit 用于抢占优先级,0个bit 用于子优先级

补充:在 STM32 中,用 NVIC 来专门管理所有中断(所有中断分配的工作都交给了NVIC,给不同的中断分配中断优先级的),是内核的一个外设,用来减轻 CPU 的负担。NVIC 总共有 16 个中断优先等级(0~15,由用户自己分配决定),为了处理不同形式的优先级, STM32 的 NVIC 对中断优先级进行了分组,分为了五组。

FreeRTOS 用的是 NVIC_PriorityGroup_4

 

FreeRTOS 中断优先级的特点:

1、低于 configMAX_SYSCALL_INTERRUPT_PRIORITY 优先级(即大于等于5的优先级,在5~15之间)的中断里才允许调用FreeRTOS 的API函数。

中断优先级要 >= 5,这样在中断函数里调用 FreeRTOS 的 API 函数才能用,因为 FreeRTOS 所管理的最高中断优先级大于 5 的(中断优先级里是越低越高)。

 

2、建议将所有优先级位指定为抢占优先级位(即 NVIC_PriorityGroup_4),方便FreeRTOS管理。

 

3、中断优先级数值越小越优先,任务优先级数值越大越优先。

### 关于 FreeRTOS-Plus-TCP 的使用指南 #### 配置 FreeRTOS-Plus-TCP 是一个专为嵌入式系统设计的 TCP/IP 协议栈,适用于资源受限的设备。为了成功配置该协议栈,需完成以下几个方面的设置工作: 1. **硬件初始化**:确保目标平台上的网络接口已正确初始化,并且驱动程序支持必要的功能(如发送和接收数据包)。这一步骤通常涉及调用特定函数来启动网卡以及分配内存缓冲区用于存储待处理的数据帧[^1]。 2. **IP 地址及相关参数设定**:通过 API 函数 `vIPv4AddressSet` 或者其他方式指定静态 IP 地址、子网掩码、默认网关等基本信息。如果希望动态获取这些值,则可以启用 DHCP 客户端服务[^3]。 3. **堆栈大小调整**:根据实际应用场景需求合理规划任务优先级及其对应的堆栈尺寸。过小可能导致溢出错误而过大则浪费有限资源[^2]。 4. **中断向量表映射**:对于某些架构而言还需要手动修改中断向量表以便正确响应来自物理层事件的通知信号。 --- #### 示例代码 下面给出一段简单的服务器监听循环作为参考实例之一: ```c #include "FreeRTOS.h" #include "task.h" #include "socket.h" void vSimpleServerTask(void *pvParameters){ struct freertos_socket_t* pxSocket; /* 创建套接字 */ if( (pxSocket = socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP)) != NULL ){ /* 绑定到本地地址 */ struct freertos_sockaddr bindAddr; memset(&bindAddr,0,sizeof(bindAddr)); bindAddr.sin_family=FREERTOS_AF_INET; bindAddr.sin_port=htons((uint16_t)80); int iResult = bind(pxSocket,(struct sockaddr*)&bindAddr,sizeof(bindAddr)); if(iResult==pdPASS){ listen(pxSocket,BACKLOG_QUEUE_LENGTH); while(TRUE){ struct freertos_socket_t* newClientConnection; /* 接受连接请求 */ newClientConnection=accept(pxSocket,NULL,PASSIVE_BACKLOG_TIME_MS); if(newClientConnection!=NULL){ // 处理客户端交互逻辑... closesocket(newClientConnection); } } } closesocket(pxSocket); } } ``` 此代码展示了如何创建一个基本的服务端应用程序框架,在其中等待客户建立连接之后再一步执行具体业务流程[^3]。 --- #### 相关文档下载链接 官方提供了详尽的技术手册帮助开发者深入了解产品特性及最佳实践方法论。可以从以下位置访问更多资料: - GitHub 主页: [https://github.com/FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS)[^1] - GitCode 存储库: [https://gitcode.com/gh_mirrors/fr/FreeRTOS-Plus-TCP](https://gitcode.com/gh_mirrors/fr/FreeRTOS-Plus-TCP) 另外还有专门针对初学者编写的入门教程可供查阅学习---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值