📄 int.c
字号:
__int_contact_asyn_signal(); //移植提示:若硬件没关闭异步信号,则无需这句
tg_int_global.nest_asyn_signal--;
}
void __int_engine_all(ufast_t ufl_line)
{
if(tg_int_table[ufl_line].int_type == cn_real)
__int_engine_real(ufl_line); //是实时中断
else
__int_engine_asyn_signal(ufl_line); //是异步信号
}
//----把指定中断线设置为异步信号--------------------------------------------
//功能:把指定中断线设置为异步信号,若中断正在响应,则当前中断返回后生效
//参数:ufast ufl_line,指定被设置的中断线号
//返回:true=成功,false=失败
//-----------------------------------------------------------------------------
bool_t int_setto_asyn_signal(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return false;
tg_int_table[ufl_line].int_type = cn_asyn_signal; //中断线类型
tg_int_global.property_bit_map[ufl_line/cn_cpu_bits]
&= ~(1<<(ufl_line % cn_cpu_bits)); //设置位图
return true;
}
//----把指定中断线设置为实时中断--------------------------------------------
//功能:把指定中断线设置为实时中断,若中断正在响应,则当前中断返回后生效
//参数:ufast ufl_line,指定被设置的中断线号
//返回:true=成功,false=失败
//-----------------------------------------------------------------------------
bool_t int_setto_real(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return false;
if(tg_int_table[ufl_line].sync_event != NULL)
return false; //有线程在等待这个中断,不能设为实时中断
tg_int_table[ufl_line].int_type = cn_real; //中断线类型
tg_int_global.property_bit_map[ufl_line/cn_cpu_bits]
|= 1<<(ufl_line % cn_cpu_bits); //设置位图
return true;
}
//----设定嵌套优先级-----------------------------------------------------------
//功能: 设定指定中断线的嵌套优先级,本函数严重依赖硬件功能。如果硬件不支持,可
// 保持空函数。
//参数:ufast ufl_line,指定被设置的中断线号
//返回:无
//注: 本函数移植关键
//-----------------------------------------------------------------------------
void int_set_nest_prio(ufast_t ufl_line)
{
}
//----设定子优先级-----------------------------------------------------------
//功能: 设定指定中断线的子优先级,本函数严重依赖硬件功能。如果硬件不支持,可
// 保持空函数。
//参数:ufast ufl_line,指定被设置的中断线号
//返回:无
//注: 本函数移植关键
//-----------------------------------------------------------------------------
void int_set_sub_prio(ufast_t ufl_line)
{
}
//----关联中断线与ISR----------------------------------------------------------
//功能:为指定中断线指定中断响应函数,该函数为普通函数,
//参数:ufl_line,需要设置的中断线号
// isr,中断响应函数,由用户提供,原型:void isr(ufast_t)
//返回:无
//-----------------------------------------------------------------------------
void int_isr_connect(ufast_t ufl_line, uint32_t (*isr)(ufast_t))
{
if(ufl_line>=cn_int_num)
return;
if(isr == NULL)
tg_int_table[ufl_line].ISR = (uint32_t (*)(ufast_t))NULL_func;
else
tg_int_table[ufl_line].ISR = isr;
return;
}
//----关联中断线与事件类型-----------------------------------------------------
//功能:为指定该中断线指定一个事件类型id,如果是异步信号,则在返回主程序前弹出
// 事件类型为该id的事件,如果是实时中断,则不弹出事件。
//参数:ufl_line,需要设置的中断线号
// my_evtt_id,事件类型id
//返回:无
//-----------------------------------------------------------------------------
void int_evtt_connect(ufast_t ufl_line,uint16_t my_evtt_id)
{
if(ufl_line>=cn_int_num)
return;
tg_int_table[ufl_line].my_evtt_id = my_evtt_id;
return;
}
//----断开中断线与中断响应函数的关联-------------------------------------------
//功能:断开指定中断线指定中断响应函数的关联,代之以空函数
//参数:ufl_line,需要设置的中断线号
//返回:无
//-----------------------------------------------------------------------------
void int_isr_disconnect(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return;
tg_int_table[ufl_line].ISR = (uint32_t (*)(ufast_t))NULL_func; //指向空函数
return;
}
//----断开中断线与事件类型的关联-----------------------------------------------
//功能:断开指定中断线指定事件类型的关联,代之以cn_invalid_evtt_id
//参数:ufl_line,需要设置的中断线号
//返回:无
//-----------------------------------------------------------------------------
void int_evtt_disconnect(ufast_t ufl_line)
{
if(ufl_line>=cn_int_num)
return;
tg_int_table[ufl_line].my_evtt_id = cn_invalid_evtt_id;
return;
}
//----设定中断同步-------------------------------------------------------------
//功能: 阻塞正在处理的事件的线程,直到指定的中断线的中断发生、响应并返回后才激活,
//参数: ufl_line,等待的目标中断线
//返回: false = 该中断已经被其他线程等待,直接返回。
// true = 该中断发生返回。
//备注: 1.中断是一种临界资源,不宜在中断函数中太多的事情,故中断同步的功能比较简
// 单,每条中短线同一时刻只能有一个线程等待,也不允许设置超时等待
// 2.秉承djyos一贯风格,中断同步函数只能把自己置入等待状态,而不能控制别的
// 线程,故函数原型不能是 bool_t int_sync(ufast_t line,uint16_t event_id)
// 3.实时中断设置等待无效,调用本函数时,如果line已经被设置为实时中断,则
// 直接返回false,如果调用本函数后,line不能被设置为实时中断。
//----------------------------------------------------------------------------
bool_t int_asyn_signal_sync(ufast_t ufl_line)
{
bool_t result;
if(ufl_line>=cn_int_num)
return false;
if( !y_query_sch())
{ //禁止调度,不能进入闹钟同步状态。
y_error_login(enum_knl_cant_sched,NULL);
return false;
}
int_save_asyn_signal(); //在操作就绪队列期间不能发生中断
//实时中断不能设置同步,一个中断只接受一个同步事件
if((tg_int_table[ufl_line].int_type == cn_real)
|| (tg_int_table[ufl_line].sync_event != NULL))
{
result = false; //实时中断或已经有同步事件
}else
{
//以下三行从就绪链表中取出running事件
__y_cut_ready_event(pg_event_running);
pg_event_running->next = NULL;
pg_event_running->previous = NULL;
pg_event_running->last_status.all
= pg_event_running->event_status.all;
pg_event_running->event_status.bit.wait_asyn_signal = 1;
tg_int_table[ufl_line].sync_event = pg_event_running;
result = true;
}
int_restore_asyn_signal();
return result;
}
//特注: 不提供周期性中断同步功能,因为djyos不提供无条件休眠或者挂起的功能,已周
// 期性时钟中断为例,一次时钟中断把线程触发进入ready后,到下次时钟中断到来
// 之前,该线程要么还在ready态(可能被其他线程抢占),此时不需要再次触发,
// 要么在等待其他触发条件,比如等待内存分配、等待延时到、等待信号量等,此时
// 若被时钟中断触发,则破坏了软件的结构。周期性中断同步可用多次调用单次同步
// 的方法完成,即每次触发后,线程完成了必要的工作以后重新再次调用单次同步
// 函数,这样,程序的每一步都有明确的目标,而不是无目的的休眠或挂起
//----周期性中断同步-----------------------------------------------------------
//功能: 当前正在执行的线程进入等待状态,待被等待的中断发生后再调度,只要发生中断
// 就触发,直到调用int_sync_quash解除同步
//参数: ufl_line,等待的目标中断线
//返回: false = 该中断已经被其他线程等待,直接返回。
// true = 该中断发生返回。
//备注: 1.中断是一种临界资源,不宜在中断函数中太多的事情,故中断同步的功能比较简
// 单,每条中短线同一时刻只能有一个线程等待,也不允许设置超时等待
// 2.秉承djyos一贯风格,中断同步函数只能把自己置入等待状态,而不能控制别的
// 线程,故函数原型不能是 bool_t int_sync(ufast_t line,uint16_t event_id)
// 3.实时中断设置等待无效,调用本函数时,如果line已经被设置为实时中断,则
// 直接返回false,如果调用本函数后,line不能被设置为实时中断。
//----------------------------------------------------------------------------
//bool_t int_sync_cycle(ufast_t ufl_line)
//{
// bool_t result;
// if(ufl_line>=cn_int_num)
// return false;
// int_save_asyn_signal(); //在操作就绪队列期间不能发生中断
// if(tg_int_table[ufl_line].uf_flags.bits.type == cn_real)
// result = false;
// else
// {
// //以下三行从就绪链表中取出running事件
// if(pg_event_running == pg_event_ready)
// pg_event_ready = pg_event_ready->next;
// pg_event_ready->previous=pg_event_running->previous;
// pg_event_running->previous->next=pg_event_ready;
// pg_event_running->next = NULL;
// pg_event_running->previous = NULL;
// pg_event_running->last_status.all
// = pg_event_running->event_status.all;
// pg_event_running->event_status.bit.wait_asyn_signal = 1;
// tg_int_table[line].sync_event = pg_event_running;
// tg_int_table[line].sync_cycle = true;
// result = true;
// }
// int_restore_asyn_signal(); //在上下文切换期间不能发生中断
// return result;
//}
//----解除周期性中断同步-------------------------------------------------------
//功能: 解除中断线与当前正在执行的线程的周期性同步状态,这个状态是经调用
// int_sync_cycle函数进入的。
//参数: ufl_line,等待的目标中断线
//备注: 1.中断是一种临界资源,不宜在中断函数中太多的事情,故中断同步的功能比较简
// 单,每条中短线同一时刻只能有一个线程等待,也不允许设置超时等待
// 2.秉承djyos一贯风格,中断同步函数只能把自己置入等待状态,而不能控制别的
// 线程,故函数原型不能是 bool_t int_sync(ufast_t line,uint16_t event_id)
// 3.实时中断设置等待无效,调用本函数时,如果line已经被设置为实时中断,则
// 直接返回false,如果调用本函数后,line不能被设置为实时中断。
//----------------------------------------------------------------------------
//void int_sync_quash(ufast_t ufl_line)
//{
// if(ufl_line>=cn_int_num)
// return false;
// if(tg_int_table[ufl_line].sync_event != NULL) //同步指针中有事件
// {
// tg_int_table[ufl_line].sync_event = NULL;
// }
//}
//----初始化中断硬件相关部分---------------------------------------------------
//功能: 如标题
//参数: 无
//返回: 无
//注: 移植关键,与硬件相关,也与软件策略有关
//-----------------------------------------------------------------------------
void __int_init_hard(void)
{
int_disable_arm_int(); //禁止中断
//打开44b的中断管理器总开关,总是允许,djyos使用irq做总开关
pg_int_reg->INTMSK &= ~cn_int_en_trunk;
//中断管理器的I位总是允许,F位总是禁止,44b0x的中断管理器有缺陷,除非只允许一
//个中断配置为fiq,否则fiq检出中断线的过程使得fiq实际比irq慢,故不使用fiq,
//不管异步信号还是实施中断,均使用irq实现。
//全部设置为向量模式
pg_int_reg->INTCON = 0x1;
pg_int_reg->INTMOD=0; //设置所有中断线为IRQ中断
user_irq=__int_engine_all;
}
//----初始化中断---------------------------------------------------------------
//功能:初始化中断硬件,初始化中断线数据结构
// 2.异步信号保持禁止,它会在虚拟机启动引擎中打开.
// 3.总中断允许,
// 用户初始化过程应该遵守如下规则:
// 1.系统开始时就已经禁止所有异步信号,用户初始化时无须担心异步信号发生.
// 2.初始化过程中如果需要操作总中断/实时中断/异步信号,应该成对使用.禁止使
// 异步信号实际处于允许状态(即异步和总中断开关同时允许).
// 3.可以操作中断线,比如连接、允许、禁止等,但应该成对使用.
// 4.建议使用save/restore函数对,不要使用enable/disable函数对.
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void __int_init(void)
{
ufast_t ufl;
__int_init_hard();
__int_echo_all_line();
for(ufl=0;ufl<cn_int_num;ufl++)
{
__int_cut_line(ufl);
tg_int_table[ufl].en_counter = 1; //禁止中断,计数为1
tg_int_table[ufl].int_type = cn_asyn_signal;
//所有中断函数指针指向空函数
tg_int_table[ufl].ISR = (uint32_t (*)(ufast_t))NULL_func;
tg_int_table[ufl].sync_event = NULL;
tg_int_table[ufl].my_evtt_id = cn_invalid_evtt_id;
}
for(ufl=0; ufl < cn_int_bits_words; ufl++)
{
//属性位图清零,全部置为异步信号方式
tg_int_global.property_bit_map[ufl] = 0;
//中断使能位图清0,全部处于禁止状态
tg_int_global.enable_bit_map[ufl] = 0;
}
tg_int_global.en_asyn_signal = false;
tg_int_global.en_asyn_signal_counter = 1; //异步信号计数
__int_cut_asyn_signal();
tg_int_global.en_trunk = true;
tg_int_global.en_trunk_counter = 0; //总中断计数
__int_contact_trunk(); //接通总中断开关
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -