📄 int.c
字号:
//----------------------------------------------------
//Copyright (C), 2004-2009, lst.
//版权所有 (C), 2004-2009, lst.
//所属模块:中断模块
//作者:lst
//版本:V1.0.0
//文件描述: 与中断相关的代码,包含异步信号与实时中断
//其他说明:
//修订历史:
// 2. ...
// 1. 日期:
// 作者:
// 新版本号:
// 修改说明:
//------------------------------------------------------
#include "inc_os.h"
extern void (*user_irq)(ufast_t ufl_line); //在脚本中定义
extern void (*user_fiq)(ufast_t ufl_line); //在脚本中定义
struct hard_reg_int volatile * const pg_int_reg
= (struct hard_reg_int *)0x1e00000;
struct int_line tg_int_table[cn_int_num]; //定义中断线控制数据结构
struct int_master_ctrl tg_int_global;
//cpsr的IF位清0,允许全部ARM7内核中断
#define int_enable_arm_int() \
do{ \
register ucpu_t xr0; \
asm volatile \
( \
"MRS %0, CPSR \n\t" \
"bic %0,%0,%1 \n\t" \
"MSR CPSR_cxsf, %0 \n\t" \
:"=r"(xr0) \
:"i"(cn_noint) \
:"cc" \
); \
}while(0)
//cpsr的IF位置1,禁止ARM7内核全部中断
#define int_disable_arm_int() \
do{ \
register ucpu_t xr0; \
asm volatile \
( \
"MRS %0, CPSR \n\t" \
"ORR %0,%0,%1 \n\t" \
"MSR CPSR_cxsf, %0 \n\t" \
:"=r"(xr0) \
:"i"(cn_noint) \
:"cc" \
); \
}while(0)
//cpsr的I位置1,禁止ARM7内核irq中断
#define __int_disable_irq() \
do{ \
register ucpu_t xr0; \
asm volatile \
( \
"MRS %0, CPSR \n\t" \
"ORR %0,%0,%1 \n\t" \
"MSR CPSR_cxsf, %0 \n\t" \
:"=r"(xr0) \
:"i"(cn_noirq) \
:"cc" \
); \
}while(0)
//cpsr的I位清0,允许ARM7内核irq中断
#define __int_enable_irq() \
do{ \
register ucpu_t xr0; \
asm volatile \
( \
"MRS %0, CPSR \n\t" \
"bic %0,%0,%1 \n\t" \
"MSR CPSR_cxsf, %0 \n\t" \
:"=r"(xr0) \
:"i"(cn_noirq) \
:"cc" \
); \
}while(0)
//cpsr的F位置1,禁止ARM7内核fiq中断
#define int_disable_fiq() \
do{ \
register ucpu_t xr0; \
asm volatile \
( \
"MRS %0, CPSR \n\t" \
"ORR %0,%0,%1 \n\t" \
"MSR CPSR_cxsf, %0 \n\t" \
:"=r"(xr0) \
:"i"(cn_nofiq) \
:"cc" \
); \
}while(0)
//cpsr的F位清0,允许ARM7内核irq中断
#define int_enable_fiq() \
do{ \
register ucpu_t xr0; \
asm volatile \
( \
"MRS %0, CPSR \n\t" \
"bic %0,%0,%1 \n\t" \
"MSR CPSR_cxsf, %0 \n\t" \
:"=r"(xr0) \
:"i"(cn_nofiq) \
:"cc" \
); \
}while(0)
//----接通异步信号开关---------------------------------------------------------
//功能:接通异步信号开关,如果总开关接通且中断线开关接通,该中断将被允许
// 1.当有独立的硬件开关时,把该开关接通即可
// 2.如果没有独立硬件开关,则接通所有被允许的异步信号的线开关.
// 3.44b0x属于第二中情况,把符合条件的中断线在rINTMSK相应位清0.
//参数:无
//返回:无
//备注:这是内部函数,只允许模块内调用,移植关键
//-----------------------------------------------------------------------------
void __int_contact_asyn_signal(void)
{
//INTMSK中异步信号且中断线被使能的位被清0
pg_int_reg->INTMSK &= ~((~tg_int_global.property_bit_map[0])
& tg_int_global.enable_bit_map[0]);
}
//----断开异步信号开关---------------------------------------------------------
//功能:断开异步信号开关,所有的异步信号将被禁止
// 1.当有独立的硬件开关时,把该开关断开即可
// 2.如果没有独立硬件开关,则断开所有异步信号的线开关.
// 3.44b0x属于第二中情况,把所有异步信号线在rINTMSK相应位置1.
//参数:无
//返回:无
//备注:这是内部函数,只允许模块内调用,移植关键
//-----------------------------------------------------------------------------
void __int_cut_asyn_signal(void)
{
register ucpu_t msk;
msk = (~tg_int_global.property_bit_map[0]) & cn_int_msk_all_line;
pg_int_reg->INTMSK |= msk;
}
//----接通总中断开关-----------------------------------------------------------
//功能:接通总中断开关,所有cpu都会有一个总开关,直接操作该开关即可.
//参数:无
//返回:无
//备注:这是内部函数,只允许模块内调用,移植关键
//-----------------------------------------------------------------------------
void __int_contact_trunk(void)
{
__int_enable_irq();
}
//----断开总中断开关---------------------------------------------------------
//功能:断开总中断开关,所有cpu都会有一个总开关,直接操作该开关即可.
//参数:无
//返回:无
//备注:这是内部函数,只允许模块内调用,移植关键
//-----------------------------------------------------------------------------
void __int_cut_trunk(void)
{
__int_disable_irq();
}
//----接通单个中断线开关-------------------------------------------------------
//功能:接通单个中断线开关,该中断是否允许还要看后面的开关状态
//参数:无
//返回:无
//备注:这是内部函数,只允许模块内调用,移植关键
//-----------------------------------------------------------------------------
void __int_contact_line(ufast_t ufl_line)
{
//如果硬件提供独立的总中断开关和异步信号开关,则不需要做以下判断,直接
//允许该中断线就可以了.
if(tg_int_table[ufl_line].int_type == cn_asyn_signal)
{//如果该中断线属于异步信号,且异步信号开关允许,允许该中断线
if(tg_int_global.en_asyn_signal == true)
pg_int_reg->INTMSK &= ~(1<<ufl_line);
}else if(tg_int_global.en_trunk == true)
//如果该中断属于实时中断,且中断总开关允许,允许该中断线
pg_int_reg->INTMSK &= ~(1<<ufl_line);
}
//----断开单个中断线开关-------------------------------------------------------
//功能:断开单个中断线开关,无论总中断和异步信号开关状态如何,该中断线被禁止
//参数:无
//返回:无
//备注:这是内部函数,只允许模块内调用,移植关键
//-----------------------------------------------------------------------------
void __int_cut_line(ufast_t ufl_line)
{
register ucpu_t ucl_msk = 1<<ufl_line;
pg_int_reg->INTMSK |=ucl_msk;
}
//----保存总中断状态并禁止总中断--------------------------------------------
//功能:本函数是int_restore_trunk()的姊妹函数,调用本函数使禁止次数增1,调用一
// 次int_restore_trunk使禁止次数减1。
// 若当前次数为0,增加为1并禁止总中断,不为0时简单地增1
//参数:无
//返回:无
//------------------------------------------------------------------------------
void int_save_trunk(void)
{
if(tg_int_global.en_trunk_counter != cn_limit_ucpu)//达上限后再加会回绕到0
tg_int_global.en_trunk_counter++;
//原算法是从0->1的过程中才进入,但如果在en_trunk_counter != 0的状态下因故障
//使中断关闭,将使用户后续调用的int_save_trunk起不到作用
__int_cut_trunk();
tg_int_global.en_trunk =false;
return;
}
//----恢复保存的总中断状态---------------------------------------------------
//功能:本函数是int_save_trunk()的姊妹函数,调用本函数使禁止次数减1,调用
// 一次int_save_trunk使禁止次数增1,
// 当次数减至0时激活总中断,否则简单减1
//参数:无
//返回:无
//------------------------------------------------------------------------------
void int_restore_trunk(void)
{
if(tg_int_global.en_trunk_counter != 0)
tg_int_global.en_trunk_counter--;
if(tg_int_global.en_trunk_counter == 0)
{
tg_int_global.en_trunk = true;
__int_contact_trunk();
if(tg_int_global.en_asyn_signal == true)
{
if(pg_event_running != pg_event_ready)
__schedule();
}
}else
{
__int_cut_trunk();
}
return;
}
//----查看总中断是否允许-----------------------------------------------------
//功能:
//参数:无
//返回:允许返回true,禁止返回false
//-----------------------------------------------------------------------------
bool_t int_check_trunk(void)
{
if(tg_int_global.en_trunk == true)
return true;
else
return false;
}
//----保存当前状态并禁止异步信号------------------------------------------------
//功能:本函数是int_restore_asyn_signal()的姊妹函数,调用本函数使禁止次数增加,
// 调用一次int_restore_asyn_signal()使禁止次数减少。
// 若当前次数为0,增加为1并禁止异步信号,不为0时简单地增1
//参数:无
//返回:无
//------------------------------------------------------------------------------
void int_save_asyn_signal(void)
{
//达上限后再加会回绕到0
if(tg_int_global.en_asyn_signal_counter != cn_limit_ucpu)
tg_int_global.en_asyn_signal_counter++;
//原算法是从0->1的过程中才进入,但如果在en_asyn_signal_counter != 0的状态下
//因故障使中断关闭,将使用户后续调用的en_asyn_signal_counter起不到作用
__int_cut_asyn_signal();
tg_int_global.en_asyn_signal =false;
return;
}
//----复位异步信号开关------------------------------------------------
//功能:把异步信号开关恢复到初始状态,即en_asyn_signal_counter=1的状态,初始化
// 中断系统后,还要做大量的模块初始化工作才能启动多事件调度,在启动多事件
// 调度前调用本函数复位异步信号状态,可以防止模块初始化代码的bug意外修改
// 了异步信号使能状态。
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void __int_reset_asyn_signal(void)
{
__int_cut_asyn_signal();
tg_int_global.en_asyn_signal =false;
tg_int_global.en_asyn_signal_counter =1;
return;
}
//----恢复保存的异步信号状态----------------------------------------------------
//功能:本函数是int_save_asyn_signal()的姊妹函数,调用本函数使禁止次数减少,调用
// 一次int_save_asyn_signal()是禁止次数增加。
// 当次数减至0时激活异步信号,否则简单减1
//参数:无
//返回:无
//------------------------------------------------------------------------------
void int_restore_asyn_signal(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -