|
|
|
@ -25,9 +25,7 @@
|
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
/*
|
|
|
|
|
关于LiteOS中硬件中断处理的部分,涉及了中断的注册、删除、触发、使能、禁止等操作
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "los_hwi_pri.h"
|
|
|
|
|
#include "los_hwi.h"
|
|
|
|
|
#include "los_memory.h"
|
|
|
|
@ -63,7 +61,7 @@ const HwiControllerOps *g_hwiOps = NULL;
|
|
|
|
|
|
|
|
|
|
typedef VOID (*HWI_PROC_FUNC0)(VOID);
|
|
|
|
|
typedef VOID (*HWI_PROC_FUNC2)(INT32, VOID *);
|
|
|
|
|
//OsIrqNestingActive:用于在处理中断期间激活中断嵌套计数器,避免在处理时钟中断时进行抢占
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
|
|
|
|
@ -73,7 +71,7 @@ STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//OsIrqNestingInactive:用于在处理中断结束后禁用中断嵌套计数器
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
|
|
|
|
@ -82,17 +80,17 @@ STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//OsIrqNestingCntGet:获取当前CPU的中断嵌套计数值
|
|
|
|
|
|
|
|
|
|
size_t OsIrqNestingCntGet(VOID)
|
|
|
|
|
{
|
|
|
|
|
return g_intCount[ArchCurrCpuid()];
|
|
|
|
|
}
|
|
|
|
|
//OsIrqNestingCntSet:设置当前CPU的中断嵌套计数值
|
|
|
|
|
|
|
|
|
|
VOID OsIrqNestingCntSet(size_t val)
|
|
|
|
|
{
|
|
|
|
|
g_intCount[ArchCurrCpuid()] = val;
|
|
|
|
|
}
|
|
|
|
|
//InterruptHandle:处理中断的实际函数,根据中断号调用对应的中断处理函数
|
|
|
|
|
|
|
|
|
|
STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm)
|
|
|
|
|
{
|
|
|
|
|
hwiForm->respCount++;
|
|
|
|
@ -116,7 +114,7 @@ STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//OsIntHandle:中断处理入口函数,负责处理中断前的一些准备工作,如调用中断处理前的钩子函数等
|
|
|
|
|
|
|
|
|
|
VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm)
|
|
|
|
|
{
|
|
|
|
|
size_t *intCnt = NULL;
|
|
|
|
@ -150,7 +148,7 @@ VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm)
|
|
|
|
|
OsCpupIrqEnd(hwiNum);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
//OsIntEntry:中断向量入口函数,根据中断号调用对应的中断处理函数
|
|
|
|
|
|
|
|
|
|
VOID OsIntEntry(VOID)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps != NULL) && (g_hwiOps->handleIrq != NULL)) {
|
|
|
|
@ -158,7 +156,7 @@ VOID OsIntEntry(VOID)
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//OsHwiCpIrqParam:根据传入的中断参数结构体分配内存,并将参数信息拷贝到新分配的内存中
|
|
|
|
|
|
|
|
|
|
STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
|
HWI_IRQ_PARAM_S *paramByAlloc = NULL;
|
|
|
|
@ -171,7 +169,6 @@ STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
return (HWI_ARG_T)paramByAlloc;
|
|
|
|
|
}
|
|
|
|
|
#ifndef LOSCFG_SHARED_IRQ
|
|
|
|
|
//OsHwiDel:删除指定的中断处理函数
|
|
|
|
|
STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -193,7 +190,7 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam,
|
|
|
|
|
HWI_UNLOCK(intSave);
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
//OsHwiCreate:创建中断处理函数,并将其添加到中断处理链表中
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
|
|
|
|
|
const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
@ -221,7 +218,6 @@ STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_F
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
#else /* LOSCFG_SHARED_IRQ */
|
|
|
|
|
//函数OsFreeHwiNode:用于释放中断处理函数节点,并在需要时禁止该中断
|
|
|
|
|
STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm, UINT32 irqId)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret = LOS_OK;
|
|
|
|
@ -244,8 +240,7 @@ STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm,
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//OsHwiDel:用于删除硬件中断处理函数,它首先判断中断是否是共享中断
|
|
|
|
|
//如果不是,则直接释放该中断的处理函数节点;如果是共享中断,则遍历链表找到对应的设备ID,然后释放该中断的处理函数节点
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId)
|
|
|
|
|
{
|
|
|
|
|
HwiHandleInfo *hwiFormPrev = NULL;
|
|
|
|
@ -295,8 +290,7 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UIN
|
|
|
|
|
HWI_UNLOCK(intSave);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//OsHwiCreate:用于创建硬件中断处理函数,它首先判断中断是否是共享中断,并检查是否已经存在具有相同设备ID的中断处理函数节点,如果存在则返回错误
|
|
|
|
|
//然后申请内存并初始化新的中断处理函数节点,将其添加到链表中
|
|
|
|
|
|
|
|
|
|
STATIC UINT32 OsHwiCreate(HwiHandleInfo *head, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
|
|
|
|
|
const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
@ -365,9 +359,7 @@ size_t IntActive()
|
|
|
|
|
LOS_IntRestore(intSave);
|
|
|
|
|
return intCount;
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiCreate 函数:用于创建硬件中断处理函数
|
|
|
|
|
//它会注册一个中断处理函数,并将其与指定的硬件中断号相关联
|
|
|
|
|
//可以设置中断的优先级、硬件中断模式和处理函数
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
|
|
|
|
|
HWI_PRIOR_T hwiPrio,
|
|
|
|
|
HWI_MODE_T hwiMode,
|
|
|
|
@ -404,8 +396,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiDelete 函数:用于删除已经创建的硬件中断处理函数
|
|
|
|
|
//通过指定硬件中断号,可以将之前注册的中断处理函数从系统中删除
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
@ -426,8 +417,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqP
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiTrigger 函数:用于手动触发指定的硬件中断
|
|
|
|
|
//调用该函数后,会立即触发对应的硬件中断,使得系统执行相应的中断处理函数
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->triggerIrq == NULL)) {
|
|
|
|
@ -437,8 +427,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->triggerIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiEnable 函数:用于使能指定的硬件中断
|
|
|
|
|
//调用该函数后,系统将允许对应的硬件中断产生,并执行相应的中断处理函数
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->enableIrq == NULL)) {
|
|
|
|
@ -448,8 +437,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->enableIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiDisable 函数:用于禁止指定的硬件中断
|
|
|
|
|
//调用该函数后,系统将阻止对应的硬件中断产生,屏蔽其影响
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->disableIrq == NULL)) {
|
|
|
|
@ -459,8 +447,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->disableIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiClear 函数:用于清除指定的硬件中断
|
|
|
|
|
//在某些平台上,硬件中断发生后可能需要手动清除中断标志位,以便正确处理后续的中断
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->clearIrq == NULL)) {
|
|
|
|
@ -470,8 +457,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->clearIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiSetPriority 函数:用于设置硬件中断的优先级
|
|
|
|
|
//通过指定硬件中断号和优先级,可以调整硬件中断的触发顺序
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->setIrqPriority == NULL)) {
|
|
|
|
@ -482,8 +468,6 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T prio
|
|
|
|
|
return g_hwiOps->setIrqPriority(hwiNum, priority);
|
|
|
|
|
}
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
//LOS_HwiSetAffinity函数:用于设置硬件中断的处理CPU亲和性
|
|
|
|
|
//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来设置中断的处理CPU亲和性
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->setIrqCpuAffinity == NULL)) {
|
|
|
|
@ -493,8 +477,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->setIrqCpuAffinity(hwiNum, cpuMask);
|
|
|
|
|
}
|
|
|
|
|
//LOS_HwiSendIpi函数:用于发送硬件中断处理请求给指定的CPU
|
|
|
|
|
//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来发送中断处理请求
|
|
|
|
|
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->sendIpi == NULL)) {
|
|
|
|
@ -507,8 +490,6 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_LOWPOWER
|
|
|
|
|
//LOS_IntWakeupHookReg函数:用于注册中断唤醒回调函数
|
|
|
|
|
//它将传入的回调函数赋值给全局变量g_intWakeupHook,以便在中断唤醒时调用该回调函数
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook)
|
|
|
|
|
{
|
|
|
|
|
g_intWakeupHook = hook;
|
|
|
|
@ -516,8 +497,6 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Initialization of the hardware interrupt */
|
|
|
|
|
//OsHwiInit函数:用于初始化硬件中断
|
|
|
|
|
//它会调用具体的平台相关函数来进行硬件中断的初始化操作
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID)
|
|
|
|
|
{
|
|
|
|
|
ArchIrqInit();
|
|
|
|
|