在RTX5里面,自定义GPIO中断服务函数无法进入问题
MCU用的是华大HC32L110(M0+内核),裸奔程序测试成功,但是弄到RTX5里面,发现无法进入中断服务函数了。1、自定义中断服务函数如下:void Gpio_IRQHandler( uint8_t u8Param )
{
if( 3 == u8Param )
{
if( TRUE == Gpio_GetIO( 3, 3 ) )
{
Gpio_ClearIrq( 3, 3 );
///< 端口P03设置为低电平(LED点亮)
Gpio_SetIO( 0, 3, FALSE );
delay1ms( 1000 );
///< 端口P03设置为高电平(LED关闭)
Gpio_SetIO( 0, 3, TRUE );
}
}
}
2、GPIO Port3 中断处理函数(it文件内)如下:
void PORT3_IRQHandler(void)
{
Gpio_IRQHandler(3);
}
3、测试程序如下:
int main( void )
{
// System Initialization
SystemCoreClockUpdate(); //add include "system_hc32l110.h" in HC32L110C.h
EventRecorderInitialize( EventRecordAll, 1 ); // initialize and start Event Recorder
//RCH 24MHz
Clk_SetRCHFreq( ClkFreq24Mhz );
Clk_SwitchTo( ClkRCH );
//Clk_SetPeripheralGate( ClkPeripheralGpio, TRUE ); //GPIO外设时钟使能,下面两个InitIO函数也强制使能了,可以省略
//初始化外部GPIO P03为输出、上拉、开漏,P03端口外接LED3
Gpio_InitIOExt( 0, 3, GpioDirOut, TRUE, FALSE, TRUE, FALSE );
//配置P33(SW2)为中断输入端口,下降沿触发
Gpio_InitIOExt( 3, 3, GpioDirIn, TRUE, FALSE, FALSE, 0 );
//开启GPIO中断
Gpio_ClearIrq( 3, 3 );//Port3, Pin3
Gpio_EnableIrq( 3, 3, GpioIrqFalling ); //配置P33为下降沿中断,外部初始化为上拉
EnableNvic( PORT3_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE ); //< 使能端口P33系统中断
osKernelInitialize(); // Initialize CMSIS-RTOS
osThreadNew( worker1, NULL, &worker_attr_1 );
osThreadNew( worker2, NULL, &worker_attr_2 );
osThreadNew( worker3, NULL, &worker_attr_3 );
mutex_id = osMutexNew( &Thread_Mutex_attr );// use attributes from defined structure
osKernelStart(); // Start thread execution
for( ;; ) {}
}
4、故障现象:
A.debug run后,一直在PORT3_IRQHandler函数(见2)打转,并且无法step in Gpio_IRQHandler(3)函数(debug时直接跳过)。
B.在Gpio_IRQHandler(3)函数上go to definition,能够跳转至自定义服务函数(见1)。
C.只要屏蔽EnableNvic那行,三个线程都可以正常运作,说明异常肯定和中断有关。
D.其他中断服务处理(证实过AD)也是同样现象,真是怪异。
5、bing了硬汉的示例,没发现类似例子,按钮大都是check方式实现,所以发帖请教并留存了,呵呵。
先把你的中断里面的延迟删除了,这个是不规范的做法。 你说得对,只是测试而已。
RTX5官方也建议中断服务函数里面发送个信号出来,尽快撤离。
现在问题是进不去这个服务函数,并且一直处于触发状态,造成整个系统直接拖死,太怪异了。 你说得对,也仅仅测试而已。
RTX官方也建议最好在中断服务函数里面发送个信号出来,然后尽快撤离。
但是目前的问题是无法进入这个函数,实际现象还频频触发,直接把系统拉死。
真是有点怪异。 sellen 发表于 2019-12-18 11:57
你说得对,也仅仅测试而已。
RTX官方也建议最好在中断服务函数里面发送个信号出来,然后尽快撤离。
但是 ...
RTX5进去中断需求特别设置,直接使用即可。
你可以这样排查下,当前这个工程里面main函数全部注释掉,然后测试GPIO中断是否正常。
然后再将所有外设初始化不要放在main函数里面,放在你的第1个启动任务里面初始化。 1、第一个测试:大幅精简main其他语句,如下:
int main( void )
{
SystemCoreClockUpdate();
//初始化外部GPIO P03为输出、上拉、开漏,P03端口外接LED3
Gpio_InitIOExt( 0, 3, GpioDirOut, TRUE, FALSE, TRUE, FALSE );
//配置P33(SW2)为中断输入端口,下降沿触发
//初始化外部IO P33
Gpio_InitIOExt( 3, 3, GpioDirIn, TRUE, FALSE, FALSE, 0 );
//开启GPIO中断
Gpio_ClearIrq( 3, 3 );//Port3, Pin3
Gpio_EnableIrq( 3, 3, GpioIrqFalling ); //配置P33为下降沿中断,外部初始化为上拉
EnableNvic( PORT3_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE ); //< 使能端口P33系统中断
while(1);
}
测试结果:同样故障。
2、第二个测试,初始化放在线程中实现。
__NO_RETURN void worker1( void *argument )
{
( void )argument;
//初始化外部GPIO P03为输出、上拉、开漏,P03端口外接LED3
Gpio_InitIOExt( 0, 3, GpioDirOut, TRUE, FALSE, TRUE, FALSE );
//配置P33(SW2)为中断输入端口,下降沿触发
//初始化外部IO P33
Gpio_InitIOExt( 3, 3, GpioDirIn, TRUE, FALSE, FALSE, 0 );
//开启GPIO中断
Gpio_ClearIrq( 3, 3 );//Port3, Pin3
Gpio_EnableIrq( 3, 3, GpioIrqFalling ); //配置P33为下降沿中断,外部初始化为上拉
EnableNvic( PORT3_IRQn, DDL_IRQ_LEVEL_DEFAULT, TRUE ); //< 使能端口P33系统中断
while( 1 )
{
osDelay( 1000U ); // block mutex for 1s
}
}
int main( void )
{
SystemCoreClockUpdate();
osKernelInitialize();
osThreadNew( worker1, NULL, &worker_attr_1 );
osThreadNew( worker2, NULL, &worker_attr_2 );
osThreadNew( worker3, NULL, &worker_attr_3 );
osKernelStart();
for( ;; ) {}
}
测试结果:同样故障。 sellen 发表于 2019-12-18 12:55
1、第一个测试:大幅精简main其他语句,如下:
int main( void )
{
从1个测试可以看出,你的程序有问题,已经跟RTX5没有关系了。找下原因什么造成的。 嗯嗯,晚上换个方法,直接从裸奔程序再添加CMSIS,看看情况。
页:
[1]