static void __CAN_IntInit(uint8_t byCanNo) { //挂中断线 if(byCanNo==0) { //发送中断线 Int_Register(CN_INT_LINE_CAN1_RX0); Int_SetClearType(CN_INT_LINE_CAN1_RX0,CN_INT_CLEAR_AUTO); Int_IsrConnect(CN_INT_LINE_CAN1_RX0,CAN_ISR_Handler); Int_SettoAsynSignal(CN_INT_LINE_CAN1_RX0); Int_ClearLine(CN_INT_LINE_CAN1_RX0); Int_RestoreAsynLine(CN_INT_LINE_CAN1_RX0); //发送中断线 Int_Register(CN_INT_LINE_CAN1_RX1); Int_SetClearType(CN_INT_LINE_CAN1_RX1,CN_INT_CLEAR_AUTO); Int_IsrConnect(CN_INT_LINE_CAN1_RX1,CAN_ISR_Handler); Int_SettoAsynSignal(CN_INT_LINE_CAN1_RX1); Int_ClearLine(CN_INT_LINE_CAN1_RX1); Int_RestoreAsynLine(CN_INT_LINE_CAN1_RX1); //发送中断线 Int_Register(CN_INT_LINE_CAN1_SCE); Int_SetClearType(CN_INT_LINE_CAN1_SCE,CN_INT_CLEAR_AUTO); Int_IsrConnect(CN_INT_LINE_CAN1_SCE,CAN_ISR_Handler); Int_SettoAsynSignal(CN_INT_LINE_CAN1_SCE); Int_ClearLine(CN_INT_LINE_CAN1_SCE); Int_RestoreAsynLine(CN_INT_LINE_CAN1_SCE); } // else // { // //发送中断线 // Int_Register(CN_INT_LINE_CAN2_RX0); // Int_SetClearType(CN_INT_LINE_CAN2_RX0,CN_INT_CLEAR_AUTO); // Int_IsrConnect(CN_INT_LINE_CAN2_RX0,CAN_ISR_Handler); // Int_SettoAsynSignal(CN_INT_LINE_CAN2_RX0); // Int_ClearLine(CN_INT_LINE_CAN2_RX0); // Int_RestoreAsynLine(CN_INT_LINE_CAN2_RX0); // // //发送中断线 // Int_Register(CN_INT_LINE_CAN2_RX1); // Int_SetClearType(CN_INT_LINE_CAN2_RX1,CN_INT_CLEAR_AUTO); // Int_IsrConnect(CN_INT_LINE_CAN2_RX1,CAN_ISR_Handler); // Int_SettoAsynSignal(CN_INT_LINE_CAN2_RX1); // Int_ClearLine(CN_INT_LINE_CAN2_RX1); // Int_RestoreAsynLine(CN_INT_LINE_CAN2_RX1); // // //发送中断线 // Int_Register(CN_INT_LINE_CAN2_SCE); // Int_SetClearType(CN_INT_LINE_CAN2_SCE,CN_INT_CLEAR_AUTO); // Int_IsrConnect(CN_INT_LINE_CAN2_SCE,CAN_ISR_Handler); // Int_SettoAsynSignal(CN_INT_LINE_CAN2_SCE); // Int_ClearLine(CN_INT_LINE_CAN2_SCE); // Int_RestoreAsynLine(CN_INT_LINE_CAN2_SCE); // } }
//----异步事件中断引擎--------------------------------------------------------- //功能:响应异步信号,根据中断号调用用户ISR,随后弹出中断线控制块的my_evtt_id // 成员指定的事件类型,最后在返回前查看是否需要做上下文切换,如需要则切换 // 之。 //参数:ufast ufl_line,响应的中断线号 //返回:无 //----------------------------------------------------------------------------- void __Int_EngineAsynSignal(ufast_t ufl_line) { struct tagEventECB *event; u32 isr_result; tg_pIntSrcTable = malloc(tg_IntUsedNum * sizeof(struct tagIntLine)); if(tg_pIntSrcTable == NULL) return; // tg_int_global.en_asyn_signal_counter = 1; g_bScheduleEnable = false; // tg_int_global.en_asyn_signal = false; tg_int_global.nest_asyn_signal++; if(tg_pIntSrcTable[ufl_line].enable_nest == true) //允许嵌套的情况 { Int_DisableAsynLine(ufl_line); //不禁止,可能会形成无限循环 __int_enable_irq(); //L138中异步信号用irq实现,响应中断时,ARM把Ibit关闭了。 } if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].clear_type == CN_INT_CLEAR_PRE) Int_ClearLine(ufl_line); //中断应答, if(tg_pIntSrcTable[ufl_line].ISR != NULL) isr_result = tg_pIntSrcTable[ufl_line].ISR(ufl_line); else { if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].clear_type == CN_INT_CLEAR_USER) Int_ClearLine(ufl_line); //中断应答, } if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].clear_type == CN_INT_CLEAR_POST) Int_ClearLine(ufl_line); //中断应答, if(tg_pIntSrcTable[ufl_line].enable_nest == true) //支持嵌套的情况 { __int_disable_irq(); Int_EnableAsynLine(ufl_line); } event = tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].sync_event; if(event != NULL) //看同步指针中有没有事件(注:单个事件,不是队列) { event->event_result = isr_result; __Djy_EventReady(event); //把该事件放到ready队列 tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].sync_event = NULL; //解除同步 } if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].my_evtt_id != CN_INVALID_EVTT_ID) { Djy_EventPop(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].my_evtt_id, NULL,0,(ptu32_t)isr_result, (ptu32_t)ufl_line,0); } tg_int_global.nest_asyn_signal--; if(tg_int_global.nest_asyn_signal == 0) { // tg_int_global.en_asyn_signal = true; // tg_int_global.en_asyn_signal_counter = 0; if(g_ptEventReady != g_ptEventRunning) __Djy_ScheduleAsynSignal(); //执行中断内调度 g_bScheduleEnable = true; } }
//----实时中断引擎------------------------------------------------------------- //功能?响应实时中断?根据中断号调用用户ISR //参数?ufast ufl_line?响应的中断线号 //返回?无 //----------------------------------------------------------------------------- void __Int_EngineReal(ufast_t ufl_line) { tg_int_global.nest_real++; //本if语句与移植敏感?跟cpu的中断管理器的几个特性有关: //1、异步信号是否有独立的开关?例如cortex-m3、omapl138等是有的?2440、2416、 // 2410等是没有的。如果没有独立开关?则在打开总中断前须断掉异步信号线开关 //2、异步信号和实时中断都处于开启状态的情况下?异步信号是否可能抢占实时中断。 // 如果可以,是不能实现实时中断嵌套的。 //3、实时中断响应后?是否自动关闭实时中断 //4、该具体实现是否支持实时中断嵌套 //5、本实现支持实时中断嵌套?故整个注释掉 // if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].enable_nest == true) // { // real_save_asyn = Int_LowAtomStart(); // Int_ContactTrunk(); // } Int_ClearLine(ufl_line); //中断应答 if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].ISR != NULL) tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].ISR(ufl_line); //调用用户中断函数 //如果该实现支持实时中断嵌套?启用以下4句 tg_int_global.nest_real--; }
// ============================================================================= // 功能: 初始化UART对应的中断线,并初始化中断入口函数 // 参数:SerialNo,串口号 // 返回: 无 // ============================================================================= static void __UART_IntInit(u32 SerialNo) { u8 IntLine; if(SerialNo == CN_UART0) IntLine = CN_INT_LINE_UART0_RX_TX; else if(SerialNo == CN_UART1) IntLine = CN_INT_LINE_UART1_RX_TX; else if(SerialNo == CN_UART2) IntLine = CN_INT_LINE_UART2_RX_TX; else if(SerialNo == CN_UART3) IntLine = CN_INT_LINE_UART3_RX_TX; else if(SerialNo == CN_UART4) IntLine = CN_INT_LINE_UART4_RX_TX; else if(SerialNo == CN_UART5) IntLine = CN_INT_LINE_UART5_RX_TX; else return; if(true == Int_Register(IntLine)) { Int_IsrConnect(IntLine,UART_ISR); Int_SetClearType(IntLine,CN_INT_CLEAR_AUTO); Int_SettoAsynSignal(IntLine); Int_ClearLine(IntLine); Int_RestoreAsynLine(IntLine); } }
// ============================================================================= // 功能: IIC中断配置函数 // 参数: IntLine,中断线 // isr,中断服务函数指针 // 返回: 无 // ============================================================================= static void __IIC_IntConfig(u32 IntLine,u32 (*isr)(ufast_t)) { Int_IsrConnect(cn_int_line_TWII,__IIC_ISR); Int_SettoAsynSignal(cn_int_line_TWII); Int_ClearLine(cn_int_line_TWII); //清掉初始化产生的发送fifo空的中断 Int_RestoreAsynLine(cn_int_line_TWII); }
// ============================================================================= // 功能: IIC中断配置函数 // 参数: IntLine,中断线 // isr,中断服务函数指针 // 返回: 无 // ============================================================================= static void __IIC_IntConfig(u32 IntLine,u32 (*isr)(ptu32_t)) { Int_Register(IntLine); Int_IsrConnect(IntLine,isr); Int_SettoAsynSignal(IntLine); Int_ClearLine(IntLine); //清掉初始化产生的发送fifo空的中断 Int_RestoreAsynLine(IntLine); }
// ============================================================================= // 功能: SPI中断配置函数 // 参数: IntLine,中断线 // 返回: 无 // ============================================================================= static void __SPI_IntConfig(u8 IntLine) { //中断线的初始化 Int_Register(IntLine); Int_SetClearType(IntLine,CN_INT_CLEAR_AUTO); Int_IsrConnect(IntLine,SPI_ISR); Int_SettoAsynSignal(IntLine); Int_ClearLine(IntLine); Int_RestoreAsynLine(IntLine); }
// ============================================================================= // 函数功能:module_init_timer // SHARC21469的GP timer初始化 // 输入参数: // 输出参数: // 返回值 : // 说明 : // ============================================================================= void GPTimer_ModuleInit(void) { struct tagTimerChip Sharc21469GPtimer; Int_IsrConnect(cn_int_line_GPTMR0I,__GPTimer0_ISR); Int_SettoAsynSignal(cn_int_line_GPTMR0I); Int_ClearLine(cn_int_line_GPTMR0I); //清掉初始化产生的发送fifo空的中断 Int_RestoreAsynLine(cn_int_line_GPTMR0I); Int_IsrConnect(cn_int_line_GPTMR1I,__GPTimer1_ISR); Int_SettoAsynSignal(cn_int_line_GPTMR1I); Int_ClearLine(cn_int_line_GPTMR1I); //清掉初始化产生的发送fifo空的中断 Int_RestoreAsynLine(cn_int_line_GPTMR1I); *pTM0CTL = TIMODEPWM | PRDCNT | IRQEN; // configure the timer0 *pTM0W = 1; // timer0 width *pTM1CTL = TIMODEPWM | PRDCNT | IRQEN; // configure the timer1 *pTM1W = 1; // timer1 width register Sharc21469GPtimer.chipname = "SHARC21469GPTimer"; Sharc21469GPtimer.timerhardalloc = __GPTimer_Alloc; Sharc21469GPtimer.timerhardfree = __GPTimer_Free; Sharc21469GPtimer.timerhardctrl = __GPTimer_Ctrl; TimerHard_RegisterChip(&Sharc21469GPtimer); // =============下面代码仅做测试使用=================================== /* struct tagGPTimerHandle *testTimer; //step1:分配一个定时器 testTimer=__GPTimer_Alloc(30000000, __GPTimer0_ISR); //step2:设置定时周期 // __GPTimer_SetCycle(testTimer, 30000000); //step3:使能中断 __GPTimer_EnInt(testTimer); //开始计数 __GPTimer_StartCount(testTimer); */ }
// ============================================================================= // 功能: SPI中断配置函数 // 参数: IntLine,中断线 // 返回: 无 // ============================================================================= static void __SPI_IntConfig(void) { u8 IntLine = cn_int_line_espi; //中断线的初始化 Int_Register(IntLine); Int_IsrConnect(IntLine,SPI_ISR); Int_SettoAsynSignal(IntLine); Int_SetLineTrigerType(IntLine,EN_INT_TRIGER_HIGHLEVEL); Int_ClearLine(IntLine); Int_RestoreAsynLine(IntLine); }
//----异步事件中断引擎--------------------------------------------------------- //功能?响应异步信号?根据中断号调用用户ISR?随后弹出中断线控制块的my_evtt_id // 成员指定的事件类型?最后在返回前查看是否需要做上下文切换?如需要则切换 // 之。 //参数?ufast ufl_line?响应的中断线号 //返回?无 //----------------------------------------------------------------------------- void __Int_EngineAsynSignal(ufast_t ufl_line) { struct tagEventECB *event; u32 isr_result; g_bScheduleEnable = false; tg_int_global.nest_asyn_signal=1; if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].clear_type == CN_INT_CLEAR_PRE) Int_ClearLine(ufl_line); //中断应答, if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].ISR != NULL) isr_result = tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].ISR(ufl_line); else { if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].clear_type == CN_INT_CLEAR_USER) Int_ClearLine(ufl_line); //中断应答, } if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].clear_type == CN_INT_CLEAR_POST) Int_ClearLine(ufl_line); //中断应答, event = tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].sync_event; if(event != NULL) //看同步指针中有没有事件(注?单个事件?不是队列) { event->event_result = isr_result; __Djy_EventReady(event); //把该事件放到ready队列 tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].sync_event = NULL; //解除同步 } if(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].my_evtt_id != CN_EVTT_ID_INVALID) { Djy_EventPop(tg_pIntSrcTable[tg_int_lookup_table[ufl_line]].my_evtt_id, NULL,0,(ptu32_t)isr_result, (ptu32_t)ufl_line,0); } tg_int_global.nest_asyn_signal = 0; if(g_ptEventReady != g_ptEventRunning) __Djy_ScheduleAsynSignal(); //执行中断内调度 g_bScheduleEnable = true; return; }
// ============================================================================= // 功能:DM9000中断初始化。DM9000中断引脚接到CPU的GPIO引脚,因此需将该引脚配置为外部 // 中断,并配置触发电平;同时需连接中断线到中断系统 // 参数:无 // 返回值 : // ============================================================================= void DM9000_IntInit(void) { //配置外部引脚EINT7/GPF7 pg_gpio_reg->GPFCON &= ~(3<<14); pg_gpio_reg->GPFCON |= (2<<14); //配置为输入 pg_gpio_reg->EXTINT0 &= ~(7<<28); pg_gpio_reg->EXTINT0 |= (4<<28); //配置上升沿触发 pg_gpio_reg->EINTPEND |= (1<<7); pg_gpio_reg->EINTMASK &= (~(01<<7)); u32 DM9000_ISR_Handler(ufast_t IntLine); //DM9000的中断引脚输出中断信号到CPU的EINT7 Int_IsrConnect(cn_int_line_eint4_7,DM9000_ISR_Handler); Int_SettoAsynSignal(cn_int_line_eint4_7); Int_ClearLine(cn_int_line_eint4_7); Int_RestoreAsynLine(cn_int_line_eint4_7); }
//----初始化uart对应的中断----------------------------------------------------- //功能: 初始化uart对应的中断线,并初始化中断入口函数 //参数:SerialNo,串口号 //返回: 无 //----------------------------------------------------------------------------- void __UART_IntInit(u32 SerialNo) { uint32_t int_line; if(SerialNo == CN_UART0) int_line = CN_INT_LINE_UART0; else if(SerialNo == CN_UART1) int_line = CN_INT_LINE_UART1; else if(SerialNo == CN_USART0) int_line = CN_INT_LINE_USART0; else int_line = CN_INT_LINE_USART1; Int_SetClearType(int_line,CN_INT_CLEAR_PRE); Int_IsrConnect(int_line,UART_ISR); Int_SettoAsynSignal(int_line); Int_ClearLine(int_line); Int_RestoreAsynLine(int_line); }
//----设定中断同步------------------------------------------------------------- //功能: 阻塞正在处理的事件的线程,直到指定的中断线的中断发生、响应并返回,然后才 // 激活线程。调用前确保该中断线被禁止,调用本函数将导致中断线被使能(是直接 // 使能,不是调用int_save_asyn_line),并在返回后恢复禁止状态。 //参数: ufl_line,等待的目标中断线 //返回: false = 该中断已经被其他线程等待,直接返回。 // true = 成功同步,并在该中断发生后返回。 //备注: 1.中断是一种临界资源,不宜在中断函数中太多的事情,故中断同步的功能比较简 // 单,每条中断线同一时刻只能有一个线程等待,也不允许设置超时等待 // 2.秉承djyos一贯风格,中断同步函数只能把自己置入等待状态,而不能控制别的 // 线程,故函数原型不能是 bool_t int_sync(ufast_t line,uint16_t event_id) // 3.实时中断设置等待无效,调用本函数时,如果line已经被设置为实时中断,则 // 直接返回false,如果调用本函数后,line不能被设置为实时中断。 // 4.为正确实现功能,须在调用前确保该中断线是被禁止的。 //----------------------------------------------------------------------------- bool_t Int_AsynSignalSync(ufast_t ufl_line) { if( (ufl_line > CN_INT_LINE_LAST) || (tg_pIntLineTable[ufl_line] == NULL) ) return false; if( !Djy_QuerySch()) { //禁止调度,不能进入异步信号同步状态。 Djy_SaveLastError(EN_KNL_CANT_SCHED); return false; } Int_SaveAsynSignal(); //在操作就绪队列期间不能发生中断 //实时中断不能设置同步,一个中断只接受一个同步事件 if((tg_pIntLineTable[ufl_line]->int_type == CN_REAL) || (tg_pIntLineTable[ufl_line]->sync_event != NULL)) { Int_RestoreAsynSignal(); return false; //实时中断或已经有同步事件 }else { if(Int_QueryLine(ufl_line) == true) //中断已经发生,同步条件达到 { Int_ClearLine(ufl_line); Int_RestoreAsynSignal(); return true; } //以下三行从就绪链表中取出running事件 __Djy_CutReadyEvent(g_ptEventRunning); g_ptEventRunning->next = NULL; g_ptEventRunning->previous = NULL; g_ptEventRunning->event_status = CN_STS_WAIT_ASYN_SIGNAL; tg_pIntLineTable[ufl_line]->sync_event = g_ptEventRunning; } Int_EnableAsynLine(ufl_line); Int_RestoreAsynSignal(); //调用本函数将引发线程切换,正在处理的事件被 //挂起。 Int_DisableAsynLine(ufl_line); g_ptEventRunning->wakeup_from = CN_STS_WAIT_ASYN_SIGNAL; g_ptEventRunning->event_status = CN_STS_EVENT_READY; return true; }