第一章 一个小案列

任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员

在好几本书上看见类似的话语,好多程序员只能写自己和机器能够理解的代码,往往很多时候只会去说别人代码写的多难理解,却不会优化自己的代码。

书中第一章的案列使用了工厂模式和状态模式进行了优化

不过在我第一次看见代码,感觉如果用策略模式来优化也是一个不错的选择,把计算方法抽象出去

<think>好的,用户现在在询问关于FreeRTOS中configMAX_SYSCALL_INTERRUPT_PRIORITY和configKERNEL_INTERRUPT_PRIORITY的具体使用案例和示例代码。我需要仔细分析他的需求。 首先,用户之前已经问过为什么需要两个宏而不是一个,现在他想要具体的例子来理解这两个宏的实际应用。他可能是在开发嵌入式系统,特别是使用FreeRTOS,遇到了中断优先级配置的问题,需要实际的代码示例来参考。 用户提到了站内引用,其中引用1和2解释了这两个宏的作用,但用户可能需要更具体的实例。他可能已经阅读了理论部分,现在想通过代码来加深理解,或者在实际项目中遇到了配置问题,需要示例来指导。 我需要确保回答包含实际的应用场景和代码示例。考虑到用户可能使用ARM Cortex-M系列微控制器,因为这在FreeRTOS中很常见,所以示例应该基于这个平台。需要展示如何设置这两个宏,以及如何在中断服务例程中应用它们。 另外,用户可能想了解如何区分哪些中断可以调用FreeRTOS API,哪些不能。因此,示例中应该包括不同优先级的中断处理函数,并说明哪些可以安全调用API,哪些不能。同时,要解释代码中的关键部分,比如优先级数值的计算,以及如何避免竞态条件。 还要注意用户的引用中提到优先级0~4是硬件关键中断,数值低于configMAX_SYSCALL_INTERRUPT_PRIORITY,这些中断不能调用FreeRTOS API。因此,在示例代码中需要体现这一点,例如将紧急制动中断的优先级设为高于configMAX_SYSCALL_INTERRUPT_PRIORITY,而其他外设中断(如UART、定时器)的优先级低于该值,可以调用API。 此外,需要解释configKERNEL_INTERRUPT_PRIORITY通常设置为最低优先级,以确保内核任务调度不会抢占高优先级的中断。这可能涉及到SysTick中断的配置,确保其优先级最低,不影响实时任务的响应。 最后,要确保回答结构清晰,分点说明使用场景和代码示例,并附上相关问题,帮助用户进一步理解。可能需要检查示例代码的正确性,比如优先级移位操作是否正确,是否符合Cortex-M的优先级设置规则,避免误导用户。</think>### FreeRTOS 中 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 和 `configKERNEL_INTERRUPT_PRIORITY` 的具体使用案例与示例代码 #### 1. **使用场景与功能对照** 以下是两者在 ARM Cortex-M 平台(如 STM32)中的典型应用场景: | **配置宏** | **典型优先级范围** | **功能说明** | **中断类型示例** | |-------------------------------------|---------------------|-----------------------------------------------------------------------------|---------------------------------| | `configMAX_SYSCALL_INTERRUPT_PRIORITY` | 中等优先级(如 0x40) | 允许调用 FreeRTOS API 的中断优先级上限 | UART 通信、定时器中断 | | `configKERNEL_INTERRUPT_PRIORITY` | 最低优先级(如 0xFF) | 内核调度器中断(如 SysTick)的优先级,确保内核任务调度不被抢占 | SysTick 中断、PendSV 中断 | --- #### 2. **示例代码(基于 ARM Cortex-M)** 以下是一个完整的 FreeRTOS 中断优先级配置案例,包含硬件初始化、中断服务函数和宏定义。 ##### **步骤 1:宏定义与优先级计算** ```c // 假设使用 4 位优先级分组(STM32 常见配置) #define configPRIO_BITS 4 // Cortex-M 优先级位数 #define configMAX_SYSCALL_INTERRUPT_PRIORITY (0x40) // 允许调用 API 的最高优先级 #define configKERNEL_INTERRUPT_PRIORITY (0xFF) // 内核中断的最低优先级 // 优先级计算宏(ARM Cortex-M 优先级左对齐) #define NVIC_PRIORITY_GROUPING(priority) ((priority) << (8 - configPRIO_BITS)) ``` ##### **步骤 2:SysTick 中断(内核中断)配置** ```c // 设置 SysTick 中断优先级为最低(内核级) void vPortSetupTimerInterrupt(void) { SysTick->LOAD = (SystemCoreClock / configTICK_RATE_HZ) - 1; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; NVIC_SetPriority(SysTick_IRQn, NVIC_PRIORITY_GROUPING(configKERNEL_INTERRUPT_PRIORITY)); } ``` ##### **步骤 3:外设中断配置(可调用 FreeRTOS API)** ```c // UART 中断配置(优先级 <= configMAX_SYSCALL_INTERRUPT_PRIORITY) void UART_Init(void) { // 硬件初始化代码... NVIC_SetPriority(UART0_IRQn, NVIC_PRIORITY_GROUPING(0x20)); // 0x20 < 0x40,允许调用 API NVIC_EnableIRQ(UART0_IRQn); } // UART 中断服务函数(可调用 xQueueSendFromISR) void UART0_IRQHandler(void) { if (UART_GetITStatus(UART0, UART_IT_RX)) { char c = UART_ReceiveData(UART0); BaseType_t xHigherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(xUartQueue, &c, &xHigherPriorityTaskWoken); // 安全调用 FreeRTOS API portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } } ``` ##### **步骤 4:硬件关键中断配置(禁止调用 FreeRTOS API)** ```c // 电机紧急制动中断(优先级 > configMAX_SYSCALL_INTERRUPT_PRIORITY) void Motor_Emergency_Init(void) { // 硬件初始化代码... NVIC_SetPriority(EXTI15_10_IRQn, NVIC_PRIORITY_GROUPING(0x00)); // 0x00 < 0x40,但实际为高优先级(数值越小优先级越高) NVIC_EnableIRQ(EXTI15_10_IRQn); } // 紧急制动中断服务函数(禁止调用任何 FreeRTOS API) void EXTI15_10_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line12)) { Motor_StopImmediately(); // 直接操作硬件寄存器 EXTI_ClearITPendingBit(EXTI_Line12); } } ``` --- #### 3. **关键逻辑说明** 1. **优先级数值与硬件关系** - ARM Cortex-M 中,优先级数值 **越小表示优先级越高**(例如 `0x00` 是最高优先级)。 - 但 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 的数值需根据 **左对齐后的优先级字段** 计算。例如,若使用 4 位优先级分组,优先级 `0x40` 对应二进制 `0100 0000`,实际有效优先级为 `4`(前 4 位)。 2. **内核中断的优先级设计** - 将 `configKERNEL_INTERRUPT_PRIORITY` 设为最低优先级(如 `0xFF`),确保内核调度(如任务切换)**不会阻塞高优先级中断**,但也不会被其他中断抢占导致调度延迟[^2]。 3. **中断服务函数的行为限制** - 优先级高于 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 的中断(如电机紧急制动)**禁止调用 FreeRTOS API**,否则可能破坏内核数据结构[^1]。 - 优先级低于或等于 `configMAX_SYSCALL_INTERRUPT_PRIORITY` 的中断(如 UART)可安全调用 `xQueueSendFromISR` 等函数。 --- ### 相关问题 1. **如何验证中断优先级配置是否符合 FreeRTOS 要求?** 2. **在混合优先级分组(如 3 位抢占优先级 + 1 位子优先级)的系统中如何计算这两个宏?** 3. **如果某个中断误用了 FreeRTOS API,系统会如何表现?如何调试此类问题?** [^1]: 优先级 0~4(硬件关键中断)完全不受内核影响,禁止调用 FreeRTOS API。 [^2]: 内核中断需设为最低优先级以保证调度稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值