ucos ii 中断 任务问题

gaowei_7743 2010-04-23 09:51:09
最近在做几个ucos 移植,但是我使用多中断接收和发送,在系统的中断管理里能够中断嵌套,但是在任务中中断接收数据然后中断发送数据,但是现在中断只能够进几次系统就死机了。。。。。

下面是任务。。
static void AppTaskMain(void *p_arg)
{
//#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
// OS_CPU_SR cpu_sr = 0;
//#endif
unsigned char getchar;
while (TRUE) {
BIT_LED_WORK = 1;
OSTimeDly(5);

getchar=USART0_Receive();
USART0_Transmit(getchar);
BIT_LED_WORK = 0;
OSTimeDly(20);
}
}
这是串口接收中断函数
void USART0_RXISR_Handler( void )
{

unsigned char data;
unsigned char tmphead;
_CLI();

/* Read the received data */
data = UDR0;
/* Calculate buffer index */
tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;
USART_RxHead = tmphead; /* Store new index */
if ( tmphead == USART_RxTail )
{
/* ERROR! Receive buffer overflow */
}

USART_RxBuf[tmphead] = data; /* Store received data in buffer */
_SEI();



}
这是串口接收函数
void USART0_TXISR_Handler( void )
{
unsigned char tmptail;
_CLI();
/* Check if all data is transmitted */
if ( USART_TxHead != USART_TxTail )
{
/* Calculate buffer index */
tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
USART_TxTail = tmptail; /* Store new index */

UDR0 = USART_TxBuf[tmptail]; /* Start transmition */
}
else
{
UCSR0B &= ~(1<<UDRIE0); /* Disable UDRE interrupt */
}
_SEI();


}

我在中断服务程序中已经使用汇编调用了:
USART0_RXISR:
PUSH_ALL ; Save all registers and status register
IN R16,SREG ; Save the SREG but with interrupts enabled
SBR R16,BIT07
ST -Y,R16
PUSH_SP ; Save the task's hardware stack pointer onto task's stack

LDS R16,OSIntNesting ; Notify uC/OS-II of ISR
INC R16 ;
STS OSIntNesting,R16 ;

CPI R16,1 ; if (OSIntNesting == 1) {
BRNE USART0_RXISR_1

LDS R30,OSTCBCur ; OSTCBCur->OSTCBStkPtr = Y
LDS R31,OSTCBCur+1
ST Z+,R28
ST Z+,R29 ; }
USART0_RXISR_1:
CALL USART0_RXISR_Handler ; Call tick ISR Handler written in C

CALL OSIntExit ; Notify uC/OS-II about end of ISR

POP_SP ; Restore the hardware stack pointer from task's stack
POP_SREG_INT
POP_ALL ; Restore all registers
RETI


堆栈大小也设定为128字节 我觉得够用了 但是程序运行一段时间,就死机了。。
...全文
1097 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
cd_cherry 2011-06-30
  • 打赏
  • 举报
回复
uCOSII解决中断死机方法:
设置OS_CPU_a.asm中,应设置NVIC_PENDSV_PRI EQU 0xFFFF0000 ; 软件中断和系统节拍中断(都为最低,0xff).
先前设置成了NVIC_PENDSV_PRI EQU 0x00000000 ;
进入中断后不久就死机,而且死机的时间是不确定的。改后就OK了
但有个问题是我用的是串口接收中断,当一次发送的数据太大,我的是208字节,接收一次后就死了,但如果设置得少一些,就OK了
cd_cherry 2011-06-30
  • 打赏
  • 举报
回复
我解决的方法是在os_cpu_a.asm中,设置
NVIC_PENDSV_PRI EQU 0xFFFF0000; PendSV priority value (lowest)
原先我设置的是
NVIC_PENDSV_PRI EQU 0x00000000,进入串口中断后不久就死机,而且死机时间不确定,改后就可以正常运行而不死机了。
youjunzi 2011-05-14
  • 打赏
  • 举报
回复
发送同样的数据,试问:每次都是固定位置死机么??
gaowei_7743 2010-04-28
  • 打赏
  • 举报
回复
还是没有完全解决问题的啊。
Peasant_Lee 2010-04-23
  • 打赏
  • 举报
回复
频繁中断,中断嵌套,频繁压入栈,会不会造成堆栈溢出呢?我对ucos2刚学不久,也不敢确定,呵呵。

ucos在任务切换之前,处理就绪列表的时候是关中断的,切换的时候才用中断机制。虽然中断很多,都有不同优先级,也就有先后,应该不会出问题吧? 我怀疑是中断嵌套过多造成堆栈溢出。死机很多都是因为这个,呵呵。

我不是ucos高手,不懂,只是怀疑,呵呵!
gaowei_7743 2010-04-23
  • 打赏
  • 举报
回复
我怀疑是中断嵌套的问题,是在任务切换的时候,来了中断,但是系统时钟节拍也进入中断。 系统走到OSTimeDly(20) 处 死机的。。。。。


请高人多多帮忙。。 在线等待。。。。。
kevinyujm 2010-04-23
  • 打赏
  • 举报
回复
1. 为了保证它的调度是受控的
-->为了保证OS的调度功能是受控的。
kevinyujm 2010-04-23
  • 打赏
  • 举报
回复
ucos之所以管理中断:
1. 为了保证它的调度是受控的
2. 为了方便在中断服务函数中也能使用操作系统功能,但是要特别小心!
3. 在可控的情况下,可以有不受操作系统管理的中断。

如果想了解更多,请看此书:
基于嵌入式实时操作系统的程序设计技术,周航慈、吴光文著,北航出版。
gaowei_7743 2010-04-23
  • 打赏
  • 举报
回复
#pragma vector=USART0_RXC_vect
__interrupt void USART0_RX_interrupt( void )
)
{

unsigned char data;
unsigned char tmphead;
_CLI();

/* Read the received data */
data = UDR0;
/* Calculate buffer index */
tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;
USART_RxHead = tmphead; /* Store new index */
if ( tmphead == USART_RxTail )
{
/* ERROR! Receive buffer overflow */
}

USART_RxBuf[tmphead] = data;
_SEI();

TCNT2 = 0;
TIFR |= (1 << 7);
TIMSK_OCIE2 = 1;
tmr_count = 0;

}
这个函数在不写中断服务函数的情况下,是完全可以使用的,但是这个中断根本没有达到由ucos系统来管理,
在实时要求上,能达到吗, ucos 系统是不是失去了他的根本意义。
kevinyujm 2010-04-23
  • 打赏
  • 举报
回复
干嘛要搞这么复杂,中断能不嵌套就不嵌套,嵌套要处理很多潜在的问题!

27,373

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧