Moderadores: 51, guest2003, Renie, gpenga
die6o escreveu:Pessoal.
Estou enfrentando um problema muito estranho.
O Software esta rodando tranquilamente, como sempre deveria estar.
Derrepente ele trava, e cai no reset, porém não reseta.
Digo, ele cai na região de startups, e simplesmente fica preso nesta linha aqui.
"DAbt_Handler B DAbt_Handler".
Eu estou deixando o debug rodar, F5, e quando trava, eu mando parar e visualizo onde o PC esta parado. E sempre nesta linha.
Estou utilizando o uVision 4.1, e Ulink2. Alguém saberia me dizer o que é esta linha ?
mastk escreveu:Nao teria um interrupção nao tratada?
void UART3_Isr(void) __irq
{
INENABLE;
U3LSRValue = U3LSR;
// Copia valor LINE STATUS REGISTER para buffer
IIRValue = U3IIR;
// Copia valor INTERRUPT IDENTIFICATION REGISTER para buffer
IIRValue = (IIRValue >> 1)&0x07;
// Posiciona os 3 bits indicadores de origem da INT = LSB's
if ( IIRValue == 0x01 )
// Se INT causada por transmissão de caracter
{
INDISABLE;
VICVectAddr = 0;
return;
// Cancela solicitação desta interrupção e retorna
}
if(U3LSRValue & (0x02|0x04|0x08|0x10|0x80)) // Verifica erros no buffer de recepção
//h02- OE Overrun error. Um byte de dados foi perdido porque foi sobreescrito sem ter sido lido.
//h04-Houve um erro de paridade
//h08- Framing error: Erro de enquadramento. Foi lido zero quando o stop-bit (sempre 1) era esperado.
//h10-Break Interrupt: Acontece quando RX fica em 0 durante mais tempo que um caractere inteiro.
//h80- Erro na fila de recebimento.
{
ErrorBuffer = dado;//obrigatório
// Move dado errado para Buffer temporário, cancelando flag de sinalização de dado recebido
contador=0;
//coloca ponteiro de recepção em zero novamente
VICVectAddr = 0;
//cancela interrupção
erro=0xff;
//sinaliza erro para processos
// Retorna sem processar o caracter recebido
new =0;
bytes=0x00;
INDISABLE;
VICVectAddr = 0;
return;
}
if (U3LSRValue & 0x01)
// Se buffer de recepção contém um caracter, bit 0, então trata.
// Esta rotina só é executada se não houve nenhum erro na serial.
{
dado = U3RBR;
//Lê dado recebido no registrador fifo de recepção, byte 0.
if((dado&0x01)==1 || trig){
buff_circular[contador]=dado;
contador++;
trig=1;
if(contador ==5){
valor =240-(buff_circular[2]/2);
put_line(oldx,oldy,indice,valor,verde);
oldx = indice;
oldy = valor;
indice++;
//put_pixel(indice++,240-(buff_circular[2]/3), PRETO);
if(indice==319){indice=1;oldx=1;/*oldy=180;*/}
limpa(indice, 113,1,126, PRETO);
trig=0;
contador=0;
}
}
if(captura){//Se for para capturar dados,!!
recebido[bytes] = dado;
bytes++;
}
if((bytes==2)){
if((recebido[0]==0x01) && ((recebido[1]&0x81)==0x81)){
frame = 0xff;
// IOSET0 = 1<<25;
}else{bytes=0;frame=0;}
}
if(frame & (bytes==125)){
new=0xff;
captura = 0x00;
frame = 0x00;
bytes=0;
IOCLR0 = 1<<25;
}
INDISABLE;
VICVectAddr = 0;
return;
// Cancela solicitação desta interrupção
}
INDISABLE;
VICVectAddr = 0;
return;
}
//==================================================================================================//
// //
// INTERRUPÇÃO DA UART3 (Porta RS232) //
// ======================================== //
//==================================================================================================//
void Config_UART3(void)
{
//unsigned long Clock_Div=0;
// Prepara variável para cálculo do Baudrate
init_vars();
//inicializa variaveis para 0,
PCONP |= 1<<25;
//liga clock para USART3
IODIR0 |= (1<<25);
IODIR0 &= ~(1<<26);
PINSEL1 |= (1<<21|1<<20/*|1<<19|1<<18*/);
// Define P0.25 = TXD3 e P0.26 = RXD3 respectivamente
U3LCR = 0x83;
//Padrão 8N1, abilita escrita regs de configuração de baud
U3DLL = 0x7D;
U3DLM = 0x00;
U3FDR = 0x87;
U3LCR &= 0x73;
// Desabilita acesso aos divisores U0DLL e U0DLM (DLAB=0)
U3FCR = 0x07;
// Habilita RX e TX FIFO's. Define interrupção a cada
//caracter recebido
U3IER = 0x07;
// Habilita interrupções TX e RX da UART3
VICVectPriority29 = 0x20 | 6;
// Habilita o Slot... 6 para determinar UART3
VICVectAddr29 = (unsigned )&UART3_Isr;
// Endereço para execução dos serviços da interrupção da UART3
VICIntEnable |= 1<<29;
// Habilita a interrupção uart3
}
void touch_handler (void) __irq
{
T0IR = 1; /* clear interrupt flag */
INENABLE;
if(!(porta_pen & pino_pen)){//se pino PEN=0, então houve toque na tela do touch screem
//as rotinas de leitura de LCD serão invocadas aqui de dentro
//sera colocado o valor absoluto de PIXEL-X/Y, em duas vars
//e setado um flag universal, este flag indica para o drive lógico da GUI
//que houve um toque no touch, e o drive fica responsável pelo tratamento lógico
if(IOPIN1&1<<13)
IOPIN1 &= ~(1<<13);
else
IOPIN1 |= 1<<13;
/* if(IOPIN1&1<<13)
IOPIN1 &= ~(1<<13);
else
IOPIN1 |= 1<<13; */
}
INDISABLE;
VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
void start_touch(void){
PINSEL4 &= ~(1<<23 | 1<<22);//port 2, pino 11, como IO
FIO2DIR &= ~(1<<11); // port 20,11 pino 11, como entrada
VICVectPriority4 = (int )9; l
// Habilita o Slot... 6 para determinar UART3
VICVectAddr4 = (unsigned )&touch_handler;
// Endereço para execução dos serviços da interrupção da UART3
VICIntEnable |= 1<<4;
// Habilita a interrupção uart3
T0TCR = 0; //desliga timer para executar as configurações
T0MR0 = (PCLCK/(1000/TMP_INT))-1; //(Valor aqui = PCLK/frequencia)-1
T0MCR = 3; // habilita interrupção no math0, e zera timer na interrupção!!!
T0PR = 0x00; //preescaler = 0;
T0TCR = 1; //liga timer para executar as configurações
}
de: http://www.keil.com/support/docs/3080.htm
This is the default Data Abort exception handler. Your application is trying to read or write an illegal memory location. You can calculate the illegal memory location using by subtracting 8 from the value in R14 (link register). Subtracting 8 adjusts for the instruction queue giving you the address of the instruction that caused this exception.
252: limpa(indice, 113,1,126, PRETO);
253:
0x00009C80 E3A03000 MOV R3,#tolls(0x00000000)
0x00009C84 E58D3000 STR R3,[R13]
0x00009C88 E3A0307E MOV R3,#0x0000007E
0x00009C8C E3A02001 MOV R2,#0x00000001
0x00009C90 E3A01071 MOV R1,#0x00000071
0x00009C94 E59F021C LDR R0,[PC,#0x021C]
0x00009C98 E5900000 LDR R0,[R0]//<<<<<<<<<<<<<<<<<<<<
0x00009C9C EBFFFF3C BL limpa(0x00009994)
void limpa(int pos_x, int pos_y,int length_x,int length_y, int colour){
//tempo de duração aproximado 72uS @ CPUCLK 72mhz
int *pos=0;
int i=0,e=0;
pos = 0;
pos = ( int *)0xA0000000;
pos += (pos_y * 320);
pos += pos_x;
for(e=0;e<length_y;e++){
for(i=0;i<length_x;i++){
*pos = colour;
pos++;
}
pos += 320;
pos -= length_x;
}
}
fanl escreveu:A rotina que tranca é de acesso á memória, read de ram. (LDR)
1. 0x00009C94 E59F021C LDR R0,[PC,#0x021C]
2. 0x00009C98 E5900000 LDR R0,[R0]//<<<<<<<<<<<<<<<<<<<<
1-> Carrega no R0 o dado do endereço PC + 0x021C.
2-> Carrega no R0 o dado do endereço do R0
Como logo depois vem a função LIMPA, R0 é o primeiro argumento dessa função.
Certamente você está lendo um apontador, minha pergunta é, por que diabos você quer ler um apontador baseado no endereço do PC?
Você tem que descobrir mais sobre isso:
- Quem é a função que trava.
- O Apontador é seu ou do JTAG?
- Qual o modo de operação da CPU nesse trecho ?
- Está dentro de alguma interrupção?
- Você está desabilitando IRQ antes de alterar os registradores do VIC?
- Você está chamando interrupção dentro de interrupção? (Fortemente não aconselhável)
Att.
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante