LPC2478 RESETANDO E TRAVANDO.

Software e Hardware para linha ARM

Moderadores: 51, guest2003, Renie, gpenga

LPC2478 RESETANDO E TRAVANDO.

Mensagempor die6o » 03 Jan 2011 11:03

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 ?
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Re: LPC2478 RESETANDO E TRAVANDO.

Mensagempor Rodrigo_P_A » 03 Jan 2011 11:26

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 ?


geralmente isso acontece qdo vc acessa uma região de memória que não existe, ou tenta escrever na flash usando um ponteiro, pelo menos era isso que acontecia comigo.

se vc tiver usando ponteiros ou rtos, dá uma verificada no uso da RAM e dos ponteiros, pois o erro deve estar aí!
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2237
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Mensagempor mastk » 03 Jan 2011 11:27

Nao teria um interrupção nao tratada?
Avatar do usuário
mastk
Dword
 
Mensagens: 4407
Registrado em: 14 Out 2006 20:43

Mensagempor Rodrigo_P_A » 03 Jan 2011 11:38

mastk escreveu:Nao teria um interrupção nao tratada?


não, é dataabort

faça um teste, crie um ponteiro, e coloque um endereço inexistente nele, depois tente lêr, vc vai ver que esta int será gerada.

depois, crie um ponteiro, aponte para a flash, e tente escrever nele, vc verá que esta int será gerada.
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2237
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Mensagempor die6o » 03 Jan 2011 12:18

Nossa muito estranho isso.

Código: Selecionar todos
   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
 
}


Eu analisei o código, e não, não existem ponteiros que são carregados com endereços inesistentes.
Esta muito muito muito estranho isso.
A unica coisa que poderia causar agum erro, ou a rotina à cima.
Ou a rotina a baixo.

Código: Selecionar todos
   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

  }   


Lembrando que a rotina esta segunda rotina "drive". É um pooling, que vai ficar lendo um spin knob, e o touch screem. A velocidade dele é de 200hz.


As outras rotinas com toda certeza não estão causando problemas. Pois o problema iniciou após eu trabalhar com interrupção da serial, e piorou após colocar o pooling..

Abraços
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Mensagempor Red Neck Guy » 03 Jan 2011 13:11

Será que quando o teu buffer circular está dando a volta não está com um erro de offset e aí está dando esse data abort? Já me aconteceu isso uma vez...
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Mensagempor fanl » 03 Jan 2011 16:14

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.



Escreva uma função em assemble que externe ao usuário o endereço, então vá no disassembler e veja quem foi o culpado.

Att
fanl
Bit
 
Mensagens: 46
Registrado em: 02 Out 2009 00:26

Mensagempor die6o » 04 Jan 2011 06:41

HOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO !!!!

Não sabia que tinha estes regs no arm... rs
Agora comecei a ler sobre os outros R´s, e os outros REG´s, e descobri uma pá de coisa, que vai ajudar muito no desenvolvimento de outros sw´s !!!

Valeu irmãozinho !!! Muito obrigado !!!
Pessoal que ajudou também, muitissimo obrigado pela força !!
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Mensagempor tcpipchip » 04 Jan 2011 16:24

poo meu, nao brincou nem um pouquinho com Assemby :)
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor die6o » 05 Jan 2011 06:48

Nossa que coisa estranha.
Ontem continuava os travamentos, eu pegava o R14, ia no desassembly, etc. Ele trava em um local imbecil, e que não tenta acessar nenhum local de memoria, etc..
comentei varias partes do codigo e ainda travando.

Resetei a placa, cortando alimentação etc. Liguei a placa, coloquei um timer pra eu olhar no display o ultimo horario que ele escreveu antes de travar. Cheguei agora de manhã, e não travou...

Eu estava imaginando, por eu estar com o Jtag espetado no 2478, estar sempre gravando, debugando etc. Isso pode fazer alguma sugeira nos regs do arm, a ponto de travar ? ........

Pois desliguei a alimentação, liguei novamente, e funcionou perfeitamente, sem travar...
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Mensagempor die6o » 05 Jan 2011 07:01

esqueçam, travou agora....


Código: Selecionar todos
 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)



conforme o postado pelo amigo, peguei o valor de R14 do user/system, subtrai 8. toda vez que o arm trava, pelo debug vai sempre para a linha indicada com "<<<<<<<<<<<<<<<<<" acima..

Lembrando que:
A rotina LIMPA, é isso aqui.

Código: Selecionar todos
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;

  }
 }


esta rotina é simples, ela faz a setagem das ints da região da ram qeu é a matriz de video, 320*240*(int).
Esta região, inicia em 0xA0000000.....

ou seja, é memoria externa, tem 32MB, eu uso apenas 320*240 INTS, o que esta muito abaixo do maximo valor que eu posso tentar ler e escrever...

Alguém esta vendo alguma coisa errada ai encima ?
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Mensagempor die6o » 05 Jan 2011 08:16

Bom, eu analisei o código.
Não existe reentrancia, não existe tentativa de acesso a região inexistente ou proibida.. etc..
Unica coisa, é que o uC fica recebendo constantemente 375Bps pela serial, e é tratado por interrupção, e dentro a int ele fica fazendo o scan de bytes especiais de cabeçalho.
E simultaneo com isso o pooling, de 5mS, para ler o encoder e os butões.

Será que esta existindo uma incompatibilidade?
Digo, como o polling é de 5mS, e a serial recebe constantemente 375 bytes por segundo... Poderia estas interrupções quase que simulataneas estar causando estes problemas ?

Abraços
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Mensagempor die6o » 06 Jan 2011 06:43

Para conhecimento da humanidade, eletronica.

Despois de esgotarem as possibilidades de erro em fw, e hw.

Eu resolvi ir anotando sobre as IRQ´s, e fazendo comparações etc.

O timer 0 estava no barramento 9.
A serial estava no barramento 3.

Os outros perifericos que fazem uso do IRQ estavam espalhados, e a interrupção não estava sendo usada por eles, pois estão desligados. USB, SDinterface, etc....

Eu resolvi acertar todos os barramentos, certinho, nos seus respectivos lugares.

Timer0 = IRQ0
Serial3= IRQ1
......
SPI = IRQ8

Eis que a placa esta ligada desde ontem a tarde, com serial e pooling, e mais a escrita de frases randonicas em posições randonicas no TFT.
Esta resolvido o problema de dabt... Não travou mais, e esta tudo funcionando perfeitamente.

Eu não sei por qual o motivo, mais barramento de IRQ, para dados perifericos, devem ser priorisados, caso contratio, o PC se perde, e faz caquinha até sobre escrevendo RAM....

Muito obrigado a todos pela ajuda!!
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26

Mensagempor fanl » 09 Jan 2011 09:40

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.
fanl
Bit
 
Mensagens: 46
Registrado em: 02 Out 2009 00:26

Mensagempor die6o » 10 Jan 2011 06:47

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.


Então, eu não em "C" estou lendo nenhum ponteiro......

ERRES:
R1- Trava dentro da interrupção da serial.
R2- sei lá, acho que o keil ta colocando aquilo..
R3- Tudo 32 bits.. nada de thumb..
R4- Sim, ele trava dentro da int, da serial..
R5- olha, como assim, desabilitando? Você diz o bit da int que esta sendo configurada ? Se sim, sim, habilito sempre depois de mexer nos regs vic.
R5- olha, com certeza. acontece interrupção em paralelo de serial e timer0 do pooling de 333hz.

Abraços
die6o
Nibble
 
Mensagens: 71
Registrado em: 07 Mar 2007 13:26


Voltar para ARM

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x