0x06 LiteOS内核详解--中断接管机制(上)
摘要:中断管理一般有两种方式,第一种就是STM32 Hal库提供的回调函数,当发生中断时,跳转到对应中断向量处,执行之前存放好的中断处理函数。第二种就是LiteOS提供的中断接管管理的方式,将所有的中断统一管理,除了几个重要的中断外,其余中断都用osInterrupt函数在其中断向量处占位,最终无论发生什么中断首先进入到osInterrupt函数中判断,根据中断是否使能、优先级等等信息来调用相应函数进行处理。
一、STM32Hal库处理中断的方式
在STM32CubeMX生成的工程文件中,都含有一个STM32xxxx_startup.S汇编文件,一般我们都叫它“启动文件”,里面通过DCD分配了一片连续的空间,实现了中断向量表,在每个中断处理函数上用weak来修饰,意思就是我们可以在其他文件,例如.c文件中重写这个处理函数。
当发生特定中断时,例如外部中断15_10 (EXTI15_10_IRQHandler)时,就会跳转到stm32xxx_it.c文件中的void EXTI15_10_IRQHandler (void)函数中处理,在该函数中又调用了Hal库中的stm32xxx_hal_gpio.c文件中的void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)函数。
① 查询中断触发的中断的中断线是否和我们要处理的中断的中断线是一致的。
② 清除中断
③ 调用我们实现的中断处理函数
二、使能中断接管机制
我们在生成好了LiteOS工程文件后,可以进到工程目录下的OS_CONFIG目录中的target_config.h文件中配置LOSCFG_PLATFORM_HWI宏和LOSCFG_PLATFORM_HWI_LIMIT宏。
LOSCFG_PLATFORM_HWI宏配置为YES,代表使能硬件中断接管机制。(这个宏在los_hwi.c文件中被使用)
LOSCFG_PLATFORM_LIMIT宏配置最大支持的硬件中断数。(这个宏可能暂时没有什么作用)最大支持的中断数应该取决于los_hwi.h文件中的OS_HWI_MAX_NUM宏。
三、中断接管机制涉及到的文件
1. 几条中断相关的汇编指令
CPSIE I 开启所有中断
CPSID I 关闭所有可以关闭的中断
2. los_hwi.h和los_hwi.c文件
它们分别位于iot_link\os\liteos\arch\arm\arm-m\src和iot_link\os\liteos\arch\arm\arm-m\include目录中。
① 如果我们不使用“接管中断”的方式,这意味着SysTick_Handler函数还是使用原来Hal库方式提供的,我们如果需要获取系统时钟,只能采用los_tick.ph和los_tick.c中提供的LOS_SysClockGet函数来获取。
根据内核的型号进行默认最大中断数的配置,看到这里,所以我推断出上面的LOSCFG_PLATFORM_LIMIT宏暂时没有使用。
配置中断默认支持的优先级,最高优先级为0最低为7。
配置当发生时中断时,调用中断处理函数默认不传递参数。
根据上面配置的中断处理函数被调用时,是否传参,来设置中断处理函数的函数指针类型。
该函数用于创建中断,最终被注册进OSAL层,当我们调用int osal_int_connect(int intnum, int prio, int mode, fn_interrupt_handle callback, void *arg);函数时,实际上就是调用本函数。
参数:
uwHwiNum:硬件中断号,可以在stm32xxx.h文件中查看或者直接使用,假设我们要创建看门狗中断,就是填入 WWDG_IRQn即可。
usHwiPrio:中断优先级,按照默认配置为0-7,数字越小代表该中断的优先级越高。
usMode:暂时没有使用,填入0即可。
pfnHandler:中断处理函数指针,我们需要按照上面说说的中断处理函数指针的类型的定义处理函数指针,并把指针值填到这里。
uwArg:我们如果没有使能OS_HWI_WITH_ARG为YES,则该项可以填写NULL。
返回值:我们在调用创建中断函数之后应该去接收返回值判断是否创建成功,并且可以根据返回值来判断是何种错误导致的创建失败。
OS_ERRNO_HWI_PROC_FUNC_NULL:未传入中断处理函数指针。
OS_ERRNO_HWI_NUM_INVALID:中断号无效。
OS_ERRNO_HWI_NO_MEMORY:内存不足导致无法创建。
OS_ERRNO_HWI_ALREADY_CREATED:该中断号已经被创建过了
LOS_OK:中断被成功创建。
该函数和创建中断函数相反,用于删除创建好的中断。
参数:
uwHwiNum:中断号
返回值:
OS_ERRNO_HWI_NUM_INVALID:我们删除了没有创建过中断的中断号,就会产生该错误。
LOS_OK:删除成功。
当发生中断时,可以用该函数获取中断号,从而判断是何种中断。因为除了前面的内核相关中断外,其他中断的向量表处都被放置了osInterrupt()函数,所以在osInterrupt()函数内,我们需要调用osIntNumGet()来获取当前的中断号,从而能调用对应中断处理函数来处理。
开启和关闭所有可屏蔽中断,主要用于临界区访问或者进行一些重要的配置,防止被突发的中断打断,本质上就是修改PRIMASK寄存器中的值,来发到屏蔽中断的目的。
恢复PRIMASK寄存器中的值。
总结:上述三个函数LOS_IntLock()、LOS_IntUnLock()、LOS_IntRestore()一般的使用方法是在配置好了所有系统相关信息和中断后,调用LOS_IntUnLock()开启中断;在进入临界区处理时,调用uvIntSave = LOS_IntLock();在关闭中断之前将PRIMASK寄存器中的值读到uvIntSave变量中保存,退出临界区时,使用LOS_IntRestore(uvIntSave);恢复。
- 点赞
- 收藏
- 关注作者
评论(0)