PIC32下,finsh调试,多次函数调用,程序会死掉
在debug和非debug模式都会出现这个问题。开来要应用到产品中,还是要调试稳定了再说。 用过N个小rtos,后来发现ucos才能稳定的跑 回复【1楼】powercxz
用过n个小rtos,后来发现ucos才能稳定的跑
-----------------------------------------------------------------------
和pic32平台有关系,stm32应用rtt还是很稳定的吧,看以前讨论的主题多与stm32有关。
现在通过反汇编elf文件,跟踪调试信息发现,程序有可能跳到 _general_exception_handler了,但有时pc显示的是0xbfc023a4。 那个PIC32串口两次中断问题是因为什么呢?网口,aozima也说存在这个问题?难道PIC32总是会在后面多出一次中断?
感觉有些不应该 回复【3楼】ffxz
那个pic32串口两次中断问题是因为什么呢?网口,aozima也说存在这个问题?难道pic32总是会在后面多出一次中断?
感觉有些不应该
-----------------------------------------------------------------------
对于pic32的uart 进入中断后要先处理数据,再快出中断时再清除中断标志位,否则就会产生两次中断。
按照这个推理,网口应该也要这样操作才行。 就是说需要在中断中把数据都读取完,然后清中断就不会出现问题?
网口的接收中断能够直接关闭吗?等接收完毕后再打开中断? 回复【5楼】ffxz
就是说需要在中断中把数据都读取完,然后清中断就不会出现问题?
网口的接收中断能够直接关闭吗?等接收完毕后再打开中断?
-----------------------------------------------------------------------
应该是清除中断标志位 PIC32的串口收/发有8级的FIFO,进入中断后要第一时间清中断标志位或关其它中断。不然会发生中断套嵌或中断重复
void __attribute__((__interrupt__)) _U1RXInterrupt(void)
{
IFS0bits.U1RXIF = 0; // reset UART receive flag
//关其它中断
用户程序
//开其它以关闭的中断
}
(错别字修改) 回复【7楼】piccode
pic32的串口收/发有8级的fifo,进入中断后要第一时间清中断标志位或关其它中断。不然会发生中断套嵌或中断重复
void __attribute__((__interrupt__)) _u1rxinterrupt(void)
{
ifs0bits.u1rxif = 0; // reset uart receive flag
//关其它中断
用户程序
//开其它以关闭的中断
}
(错别字修改)
-----------------------------------------------------------------------
而且照你这种做法发送和error都处理同一个 用户程序 ? 回复【7楼】piccode
-----------------------------------------------------------------------
修改了一下驱动,在读数据前,判断一下RXDA(严格来讲只是读取了一下状态寄存器),
发现就不会再重复进中断了.
好像并不需要关闭中断,这里先这样测试着,后面好好研究一下.
// UART 1 interrupt handler
// it is set at priority level 2
void __ISR(_UART1_VECTOR, ipl2) IntUART1Handler(void)
{
struct rt_uart_pic32 *uart_device = &uart1_device;
// Is this an RX interrupt?
if(INTGetFlag(INT_SOURCE_UART_RX(uart_device->uart)))
{
while( U1STAbits.URXDA )
{
/* Receive Data Available */
uart_device->rx_buffer = UARTGetDataByte(uart_device->uart);//UARTGetDataByte(UART1);
uart_device->save_index ++;
if (uart_device->save_index >= RT_UART_RX_BUFFER_SIZE)
{
uart_device->save_index = 0;
}
}
/* invoke callback */
if(uart_device->parent.rx_indicate != RT_NULL)
{
rt_size_t length;
if (uart_device->read_index > uart_device->save_index)
{
length = RT_UART_RX_BUFFER_SIZE - uart_device->read_index + uart_device->save_index;
}
else
{
length = uart_device->save_index - uart_device->read_index;
}
if( length )
{
uart_device->parent.rx_indicate(&uart_device->parent, length);
}
}
// Clear the RX interrupt Flag
INTClearFlag(INT_SOURCE_UART_RX(uart_device->uart));
} // Is this an RX interrupt?
// We don't care about TX interrupt
if ( INTGetFlag(INT_SOURCE_UART_TX(uart_device->uart)) )
{
INTClearFlag(INT_SOURCE_UART_TX(uart_device->uart));
}
}
回复【楼主位】flor独臂老人
在debug和非debug模式都会出现这个问题。
开来要应用到产品中,还是要调试稳定了再说。
-----------------------------------------------------------------------
原因查明为:
rt_thread_switch_interrput_flag 切换完成后忘记清0了.
造成第二次中断中切换时,并不会保存 rt_interrupt_from_thread
此处可能需要探讨:
是否要判断 rt_thread_switch_interrput_flag 不为0才执行切换,
CoreSW0Handler会在rt_hw_context_switch_interrupt中被触发,
rt_hw_context_switch_interrupt中同时会把rt_thread_switch_interrput_flag置1.
主要防止 CoreSW0Handler 被误触发.不过想应该没有这可能.
修改方法:
CoreSW0Handler:
.. SAVE_ALL ..
la k0, rt_thread_switch_interrput_flag
sw zero, 0(k0) /* clear flag */
.. switch to the new thread ..
.. RESTORE_ALL_AND_RET ..
代码已提交,欢迎测试. 回复【9楼】aozima
-----------------------------------------------------------------------
哇,你查问题的速度蛮快的啊!
谢谢了!
明天再测试!
页:
[1]