📄 int.c
字号:
if(tg_int_global.en_asyn_signal_counter != 0)
tg_int_global.en_asyn_signal_counter--;
if(tg_int_global.en_asyn_signal_counter==0)
{
tg_int_global.en_asyn_signal = true; //异步信号设为使能
__int_contact_asyn_signal();
if(tg_int_global.en_trunk == true)
{
if(pg_event_running != pg_event_ready)
__schedule();
}
}else
{
__int_cut_asyn_signal(); //防止counter>0期间意外(bug)打开
}
return;
}
//----查看异步信号是否允许-----------------------------------------------------
//功能:
//参数:无
//返回:允许返回true,禁止返回false
//-----------------------------------------------------------------------------
bool_t int_check_asyn_signal(void)
{
return tg_int_global.en_asyn_signal;
}
//----保存当前状态并禁止中断线--------------------------------------------------
//功能:本函数是int_restore_line()的姊妹函数,调用本函数使禁止次数增加,调
// 用一次int_restore_line是禁止次数减少。
// 若当前次数为0,增加为1并禁止中断线,不为0时简单地增1
//参数:ufl_line
//返回:无
//------------------------------------------------------------------------------
void int_save_line(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return;
if(tg_int_table[ufl_line].en_counter!=cn_limit_ucpu)//达上限后再加会回绕到0
tg_int_table[ufl_line].en_counter++;
//原算法是从0->1的过程中才进入,但如果在en_counter != 0的状态下
//因故障使中断关闭,将使用户后续调用的en_counter起不到作用
__int_cut_line(ufl_line);
tg_int_global.enable_bit_map[ufl_line/cn_cpu_bits]
&= ~(1<<(ufl_line % cn_cpu_bits));
}
//----恢复保存的中断线状态-----------------------------------------------------
//功能:本函数是int_save_line()的姊妹函数,调用本函数使禁止次数减少,调
// 用一次int_save_line是禁止次数增加。
// 当次数减至0时激活中断线,否则简单减1
//参数:ufl_line
//返回:无
//-----------------------------------------------------------------------------
void int_restore_line(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return;
if(tg_int_table[ufl_line].en_counter != 0)
tg_int_table[ufl_line].en_counter--;
if(tg_int_table[ufl_line].en_counter==0)
{
tg_int_global.enable_bit_map[ufl_line/cn_cpu_bits]
|= 1<<(ufl_line % cn_cpu_bits);
__int_contact_line(ufl_line);
}else
{
__int_cut_line(ufl_line);
}
}
//----直接禁止中断线-----------------------------------------------------------
//功能:本函数是int_enable_line()的姊妹函数,调用本函数使中断线的使能计数器
// 置位,并掐断中断线
//参数:ufl_line
//返回:无
//------------------------------------------------------------------------------
void int_disable_line(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return;
tg_int_table[ufl_line].en_counter = 1;
__int_cut_line(ufl_line);
tg_int_global.enable_bit_map[ufl_line/cn_cpu_bits]
&= ~(1<<(ufl_line % cn_cpu_bits));
}
//----直接允许中断线-----------------------------------------------------------
//功能:本函数是int_disable_line()的姊妹函数,调用本函数使中断线的使能计数器
// 归零,并接通中断线
//参数:ufl_line
//返回:无
//------------------------------------------------------------------------------
void int_enable_line(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return;
tg_int_table[ufl_line].en_counter = 0;
__int_contact_line(ufl_line);
tg_int_global.enable_bit_map[ufl_line/cn_cpu_bits]
|= 1<<(ufl_line % cn_cpu_bits);
}
//----查询中断线使能状态-------------------------------------------------------
//功能:查询中断线是否允许
//参数:ufl_line,欲查询的中断线
//返回:true = 使能,false = 禁止。
//-----------------------------------------------------------------------------
bool_t int_check_line(ufast_t ufl_line)
{
if(tg_int_table[ufl_line].en_counter == 0)
return true;
else
return false;
}
//----查询中断线请求状态-------------------------------------------------------
//功能:查询并清除相应中断线状态,可用于查询式中断程序
//参数:ufl_line,欲查询的中断线
//返回:若中断挂起,返回true,否则返回false
//备注: 与硬件结构相关,有些结构可能不提供这个功能,慎用!
// 本函数是移植关键函数
//-----------------------------------------------------------------------------
bool_t int_query_line(ufast_t ufl_line)
{
ucpu_t ucl_msk;
if(ufl_line>=cn_int_num)
return false;
ucl_msk=1<<ufl_line;
if(pg_int_reg->INTPND & ucl_msk)
{
pg_int_reg->INTPND &= ~ucl_msk; //清除中断状态
return true;
}else
return false;
}
//----允许异步信号嵌套----------------------------------------------------------
//功能: 在ISR函数里调用,以允许中断嵌套,实际上就是允许处于使能状态的异步信号.
//参数: 无
//返回: 无
//注:本函数移植关键
//------------------------------------------------------------------------------
void int_enable_nest_asyn_signal(void)
{
if(tg_int_global.nest_asyn_signal != 0)
__int_contact_asyn_signal();
}
//----禁止异步信号嵌套----------------------------------------------------------
//功能: 在ISR函数里调用,以禁止中断嵌套,实际上就是禁止所有异步信号.中断响应
// 后,系统默认禁止异步信号嵌套,只有在人为打开异步信号嵌套后需要重新关闭,
// 才需要调用本函数
//参数: 无
//返回: 无
//注:本函数移植关键
//------------------------------------------------------------------------------
void int_disable_nest_asyn_signal(void)
{
if(tg_int_global.nest_asyn_signal != 0)
__int_cut_asyn_signal();
}
//----允许实时中断嵌套----------------------------------------------------------
//功能: 在中断处理函数里调用,以允许中断嵌套,实际上就是允许处于使能状态的实时中断.
//参数: 无
//返回: 无
//注:本函数移植关键
//------------------------------------------------------------------------------
void int_enable_nest_real(void)
{
if(tg_int_global.nest_real != 0)
{
int_save_asyn_signal();
__int_contact_trunk();
}
}
//----禁止实时中断嵌套----------------------------------------------------------
//功能: 在中断处理函数里调用,以禁止中断嵌套,实际上就是禁止所有实时中断.中断响应
// 后,系统默认禁止实时中断嵌套,只有在人为打开实时中断嵌套后需要重新关闭,
// 才需要调用本函数
//参数: 无
//返回: 无
//注:本函数移植关键
//------------------------------------------------------------------------------
void int_disable_nest_real(void)
{
if(tg_int_global.nest_real != 0)
{
__int_cut_trunk();
int_restore_asyn_signal();
}
}
//----应答中断,清除相应中断线的中断挂起状态-----------------------------------
//功能:硬件应该有相应的功能,提供清除中断挂起的操作,清除前,不能响应同一中断线
// 的后续中断,清除后,才可以响应后续中断。本函数与该中断线被设置为实时中断
// 还是异步信号无关
//参数:ufast ufl_line,指定应答的中断线号
//返回:无
//备注:有些体系中断响应时硬件应答,本函数为空函数。
// 本函数是移植关键函数
//-----------------------------------------------------------------------------
void int_echo_line(ufast_t ufl_line)
{
pg_int_reg->I_ISPC = 1<<ufl_line;
}
//----激发中断-----------------------------------------------------------------
//功能: 触发一个中断.如果中断本已悬挂,本函数无影响.本函数与该中断线被设置为实时
// 中断还是异步信号无关
//参数:ufast ufl_line,欲触发的中断线号
//返回:如果相应的中断线硬件不提供用软件触发中断功能,返回 false,否则返回 true
//备注: 本函数实现依赖于硬件,有些硬件系统不支持此功能.
// 本函数是移植关键函数
//-----------------------------------------------------------------------------
bool_t int_tap_line(ufast_t ufl_line)
{
pg_int_reg->INTPND |= 1<<ufl_line;
return true; //44b0x支持硬件触发中断的能力.
}
//----应答全部中断,清除全部中断线的中断挂起状态-------------------------------
//功能:硬件应该有相应的功能,提供清除中断挂起的操作,清除前,不能响应后续中断,
// 清除后,可以响应后续中断
//参数:ufast ufl_line,指定应答的中断线号
//返回:无
//备注:有些体系中断响应时硬件应答,本函数为空函数。
// 本函数是移植关键函数
//-----------------------------------------------------------------------------
void __int_echo_all_line(void)
{
pg_int_reg->I_ISPC = cn_int_msk_all_line;
}
//----实时中断引擎-------------------------------------------------------------
//功能:响应实时中断,根据中断号调用用户ISR
//参数:ufast ufl_line,响应的中断线号
//返回:无
// 本函数是移植关键函数
//-----------------------------------------------------------------------------
void __int_engine_real(ufast_t ufl_line)
{
tg_int_global.nest_real++;
tg_int_global.en_trunk= false;
tg_int_global.en_trunk_counter = 1;
// __int_cut_trunk(); //移植提示:若硬件没有关闭总中断,需增加这句
int_echo_line(ufl_line); //中断应答
tg_int_table[ufl_line].ISR(ufl_line); //调用用户中断函数
tg_int_global.en_trunk = true;
tg_int_global.en_trunk_counter = 0;
// __int_contact_trunk(); //移植提示:若硬件没有关闭总中断,需增加这句
tg_int_global.nest_real--;
}
//----异步事件中断引擎---------------------------------------------------------
//功能:响应异步信号,根据中断号调用用户ISR,随后弹出中断线控制块的my_evtt_id
// 成员指定的事件类型,最后在返回前查看是否需要做上下文切换,如需要则切换
// 之。
//参数:ufast ufl_line,响应的中断线号
//返回:无
//备注: 本函数是移植关键函数
//-----------------------------------------------------------------------------
void __int_engine_asyn_signal(ufast_t ufl_line)
{
struct event_script *event;
tg_int_global.nest_asyn_signal++;
//以下几句移植很关键,请用户根据自己的硬件仔细设计,需要使CPU进入这样的状态:
//异步信号被禁止而总开关打开的状态,类似于依序调用 int_save_asyn_signal和
//__int_contact_trunk两个函数,
__int_cut_asyn_signal(); //移植提示:若硬件关闭了异步信号,则无需这句
int_echo_line(ufl_line); //中断应答
tg_int_global.en_asyn_signal = false;
tg_int_global.en_asyn_signal_counter = 1;
__int_contact_trunk(); //移植提示:若硬件没关闭总中断,则无需这句
event = tg_int_table[ufl_line].sync_event;
if(event != NULL) //看同步指针中有没有事件(注:不是同步队列)
{
event->last_status.all = event->event_status.all;
event->event_status.bit.wait_asyn_signal = 0;
__y_event_ready(event); //把该事件放到ready队列
tg_int_table[ufl_line].sync_event = NULL; //解除同步
}
//调用用户中断函数,此时嵌套中断是禁止的,用户如果需要允许嵌套,可以在
//vec_func函数中打开异步信号来达到。
tg_int_table[ufl_line].ISR(ufl_line);
y_event_pop(tg_int_table[ufl_line].my_evtt_id,ufl_line,0,0);
if(tg_int_global.nest_asyn_signal == 1)
{//已经是最后一级中断嵌套了,看看是否要调度
if(pg_event_ready != pg_event_running)
__schedule_asyn_signal(); //执行中断内调度
}
//以下几句移植很关键,请用户根据自己的硬件仔细设计:
//既要调用int_restore_asyn_signal使en_asyn_signal_counter归0,又不能使
//异步信号真的打开,而是要恢复到CPU响应中断后的状态,由中断返回指令打开。
__int_cut_trunk(); //移植提示:若硬件没关闭总中断,则无需这句
tg_int_global.en_asyn_signal = true;
tg_int_global.en_asyn_signal_counter = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -