problem ILLEGAL_BP mc9s12xdp512

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem ILLEGAL_BP mc9s12xdp512

Jump to solution
2,627 Views
Claire
Contributor I

Hi,

 

I must create a programm that generate signal from bus CAN data with timer interrupt (ECT). But when I send frame (in debug) I have Illegal_bp in command windows.

 

I don't know how to correct this error. Can you help me ? If you have any question ask me.

I programm this:

 

void timer_counter () {

    TIOS = 0xFF;         //  timer output compare register

  TCNT = 0x0000;       //timer count register

  TSCR1 = 0x80;        //timer system control register

  TSCR2 = 0x05;        //timer system control register 2

//  TCTL1 = 0x55;        //timer control register output mode

  TCTL2 = 0x55;

  TIE = 0x0F;          //timer interupt enable

  TFLG1 = 0x0F;        //main timer interrupt flag

}

 

void interrupt 8 TOC0_ISR () {
  DisableInterrupts;

 

  TFLG1 = TFLG1_C0F_MASK ;    // rabaisse le flag de l'interruption
  buffer_empty1 = buffer_lenght - buffer_full1;
 
if (buffer_empty1 == buffer_lenght) {
    PORTB =0b00000100  ;
     sendOnCanEmpty ()   ; 
}
  if ( read_buffer_wheel1 < buffer_lenght ){                    //test taille de la memoire
     TC0 = TC0 + wheel1[read_buffer_wheel1] ;                //lecture des donnees
     read_buffer_wheel1 ++    ; //incrementation compteur lecture
      } else{
         read_buffer_wheel1 = 0    ;                           //rebouclage memoire   .
         TC0 = TC0 + wheel1[read_buffer_wheel1] ;                //lecture des donnees
     }                                                         

  EnableInterrupts ;   
}

 

 

Thank you !!

Labels (1)
Tags (1)
0 Kudos
1 Solution
1,853 Views
RadekS
NXP Employee
NXP Employee

This way:

#pragma CODE_SEG NON_BANKED

void interrupt 8 TOC0_ISR () {

}

#pragma CODE_SEG DEFAULT

These commands are dedicated for linker. This way linker know where you want place your code. There are different ways how to do it, but this is simply and comfortable.

Similar commands:

#pragma DATA_SEG – for variables

#pragma CONST_SEG – for constants


View solution in original post

0 Kudos
20 Replies
1,853 Views
RadekS
NXP Employee
NXP Employee

Illegal_bp could means almost anything (any unexpected behaviour), but in most of the cases it presents unexpected interrupt.

I have for you few tips for you:

  1. TCNT register is not writable in normal mode
  2. You enables 4 output compare interrupts  (TC0, TC1, TC2, TC3; command TIE = 0x0F;). If you don’t have defined TC1..TC3 interrupt routines (interrupts 9..11), this will be probably root cause of your issue.
  3. Commands DisableInterrupts; and EnableInterrupts ; inside interrupt routine is not necessary. I bit is set automatically when MCU enter into interrupt and RTI (return from interrupt) instruction restore I bit during interrupt routine leave.
  4. Do you have enabled interrupts for CAN modules? Do you have interrupt routines for CAN interrupts?
  5. Example code below contains Interrupt catcher. This code you can use for detection of unexpected interrupts or directly in your code for handle unexpected interrupts.

volatile unsigned int number_of_ISR = 0;

volatile unsigned char sc0_data_in;

void Unimplemented_ISR(void)

{

  asm nop;         //insert breakpoint here. If the code stops here, check the "number_of_ISR"

}

#pragma CODE_SEG NON_BANKED

interrupt              1              void       ISR_1     (void)    {number_of_ISR = 1       ;               Unimplemented_ISR();}

interrupt              2              void       ISR_2     (void)    {number_of_ISR = 2       ;               Unimplemented_ISR();}

…//please fill

interrupt              19           void       ISR_19  (void)    {number_of_ISR = 19     ;               Unimplemented_ISR();}

//interrupt          20           void       ISR_20  (void)    {number_of_ISR = 20     ;               Unimplemented_ISR();}

interrupt              21           void       ISR_21  (void)    {number_of_ISR = 21     ;               Unimplemented_ISR();}

…//please fill

interrupt              119         void       ISR_119  (void)    {number_of_ISR = 119  ;               Unimplemented_ISR();}

#pragma CODE_SEG DEFAULT

//==============================================================================

//Example of SCI0 Interrupt routine

//==============================================================================

#pragma CODE_SEG NON_BANKED

interrupt 20 void SCI0_Isr(void)

//your SCI routine

}

#pragma CODE_SEG DEFAULT

//==============================================================================



1,853 Views
Claire
Contributor I

ok I try.

For the CAN I programm this :

//---------initMSCAN------------------------------------------------------                 
                  
void initMSCAN () {    
    int c2=0;          
    int c1=0;     
     
  while (!CAN2CTL1_INITAK) {   // tant que le module ne confirme pas le mode init

c1++;
  }


  CAN2CTL1 |= CAN2CTL1_CANE_MASK;      // activation du module CAN (inactif par défaut)
 
  CAN2CTL1 &= (~CAN2CTL1_LISTEN_MASK);    // Désactivation du mode lecture seule      
  CAN2BTR0 = 0x40; // Prescaler = 1 et Synchronisation jump width = 2    
  CAN2BTR1 = 0xA3;    // TSEG1=4tq er TSEG2=3tq (voir calcul doc calcul_bit_rate.pdf v3.1)
                   //Bit 7 SAMP = 1 3 échantillon par bit
  CAN2IDMR0 = 0xFF;          //accepte tous les messages
  CAN2IDMR1 = 0xFF;
  CAN2IDMR2 = 0xFF;
  CAN2IDMR3 = 0xFF;
  CAN2IDMR4 = 0xFF;
  CAN2IDMR5 = 0xFF;
  CAN2IDMR6 = 0xFF;
  CAN2IDMR7 = 0xFF;
                     
  CAN2CTL0 &= (~CAN2CTL0_INITRQ_MASK);    // demande de sortie du mode initialization
 
  while (CAN2CTL1_INITAK) { //test sortie d'init

c2++;
    
  }
}
 
  //---------------SendOnCan-------------------------------------------------

void sendOnCan (){
 
  unsigned char txbuffer;
  while (!CAN2TFLG){        //test tampon de libre
   ;
  }
 
   CAN2TBSEL=CAN2TFLG;             //selection du buffer ayant la plus petite adresse
   txbuffer = CAN2TBSEL;
    CAN2TXDLR = 0x04 ;   //Détermine la lenght de la trame de donnée.
    CAN2TXIDR0 = 0xD3;   //IDE = Détermine l’identificateur du message ID recu 69E
    CAN2TXIDR1 = 0xC0;  

    CAN2TXDSR0 = buffer_full1;   // Insertion des données que l’on souhaite transmettre.
    CAN2TXDSR1 = buffer_empty1  ;
    CAN2TXDSR2 = write_buffer_wheel1;
    CAN2TXDSR3 = read_buffer_wheel1;
    //CAN2TXDSR7 = 0xFF;
   
  CAN2TFLG = txbuffer;
 
  while ((CAN2TFLG & txbuffer) != txbuffer) {     //attendre la fin de la transmissin
  ;
  }
}

//------receiveOnCan-----------------------------------------

void receiveOnCan (){

  unsigned char lenght, index;
 
  DisableInterrupts;  

  if (CAN2RFLG & CAN2RFLG_RXF_MASK) {  //message disponible
   
     lenght = ( CAN2RXDLR & 0x0F);     //prend en compte la taille max du message (message = 8 octets max)

    PORTB = 0b00001000;
   
  for (index = 1 ; index < lenght; index++) {                          
    receive_data [index] = *(&CAN2RXDSR0 + index);  // Transfert du message vers un tampon
  }
 
  buffer1 =  write_buffer_wheel1 - read_buffer_wheel1 ;
  buffer2 =  buffer_lenght + buffer1 ;
  buffer_full1 = buffer2 % buffer_lenght;

//ecriture memoire roue 1 et test memoire pleine wheel1 ------------------

    if (buffer_full1 == 0) {
   
      PORTB =0b00000001  ;
      sendOnCanFull ()   ;
    } 
   
    if (write_buffer_wheel1< buffer_lenght)  {           //test de la taille de la memoire
              wheel1 [write_buffer_wheel1]= receive_data[1] + (256*receive_data[0]) ;      //ecriture dans la memoire
              write_buffer_wheel1 ++;                   //incrementation du compteur ecriture
                        
    }  else {
             write_buffer_wheel1 = 0;                  //rebouclage de la memoire
              wheel1 [write_buffer_wheel1]= receive_data[1] + (256*receive_data[0]) ; 
          }
   sendOnCan();

CAN2RFLG = 0x01;          //flag lors de la reception d'un message

    EnableInterrupts;

  

   }

0 Kudos
1,853 Views
Claire
Contributor I


I suppose I have a problem in CAN config because now I have no Illegal_bp but my programm don't exit of Interrupt.

I think it's more easier if you see all the programm but I don't know how to join document.

0 Kudos
1,853 Views
RadekS
NXP Employee
NXP Employee

try switch to "Use advanced editor" - blue text in right upper corner.

0 Kudos
1,853 Views
Claire
Contributor I

You can see the document ?

0 Kudos
1,852 Views
kef
Specialist I

void interrupt 8 TOC0_ISR () {

        TFLG1 = TFLG1_C0F_MASK ;    // rabaisse le flag de l'interruption

...

void interrupt 9 TOC1_ISR ()  {   //adresse de la deuxième interruption périodique

  TFLG1 = TFLG1_C1F_MASK ;    // rabaisse le flag de l'interruption

void interrupt 10  TOC2_ISR ()  {   //adresse de la troisième interruption périodique

TFLG1 = TFLG1_C3F_MASK ;    // rabaisse le flag de l'interruption

void interrupt 11  TOC3_ISR ()  {   //adresse de la quatrième interruption périodique

TFLG1 = TFLG1_C4F_MASK ;    // rabaisse le flag de l'interruption

...

C2F flag is never serviced, TOC2_ISR exits and immediately reenters until COP reset occurs and you see ILLEGAL_BP

Please, instead of using "magic" numbers 8, 9, etc, open header file for your derivative and use instead defines like VectorNumber_Vtimch0, VectorNumber_Vtimch1 etc.

0 Kudos
1,852 Views
Claire
Contributor I

Yes I don't see the TFLG2's error.

And for the header file what is signification of  VectorNumber_Vtimch0. I write just like that writing 8 but I don't know his signification.

0 Kudos
1,851 Views
kef
Specialist I

claire delange wrote:

And for the header file what is signification of  VectorNumber_Vtimch0. I write just like that writing 8 but I don't know his signification.

It is bad coding practice to use weird numbers you know today and forget tomorrow. How do I know that 8 in your case is right number for timer channel 0 vector number? I don't remember this number to find a clue why your code isn't working, I would need to open datasheet or other document to verify that your 8 is right. VectorNumber_Vtimch0 would save me some work, also will save you the same work later, when you cam back to your code few years later.

It is similar with code like TIE = 0x0F;. OK if you know perfectly that 0xF stands for bits 0,1,2 and 3 set. But you could write the same like this

TIE = (1<<3) | (1<<2) | (1<<1) | (1<<0);

, which compiles the same like TIE = 0x0F;

I don't say this ^^ is much better, but for more hard bit patterns like 0xDB, it would be much much easier to decifier what bits did you want to set. Though it doesn't matter when compiler supports binary patterns like 0b00001111, if you do smth like this

#define CHARGE_CHANNEL 2

#define DISCHARGE_CHANNEL 4

TIE = (1<<CHARGE_CHANNEL) | (1<<DISCHARGE_CHANNEL);

.. then later you will say yourself a lot of "thank you" in case you need to swap some timer channels or do something like this. With good coding it is very easy to do such tasks. It is nightmare to do the same with code full of 0x45 0x0F 0xF0...

1,852 Views
Claire
Contributor I

Interruptions don't accept VectorNumber_Vtimch0. I think (if I remenber correctly) The number decide where I save interruption.

And I prefere stay in hexa for my regsister It's easier for me. If I will must return on my programm I will must read the doc an other time.

Now I replay my programm and I have many problem. One time I see Illegal_bp, an other time the interrpution aren't activate and an other time I stay in interruption. For the same programm. :smileycry:

0 Kudos
1,852 Views
RadekS
NXP Employee
NXP Employee

I shortly look at your code and I have for you few points:

  1. Eduard has true. In TOC2_ISR you should clear flag by TFLG1_C2F_MASK and not by TFLG1_C3F_MASK. The same valid for TOC3_ISR – you should use TFLG1_C3F_MASK instead of TFLG1_C4F_MASK.
  2. In TOC2_ISR interrupt routine you used code “TC0 = TC0 + whe...” I suppose that there should be TC2…
  3. Main possible issue: Interrupt vectors contains only 16bit addresses, therefore all interrupt routines have to be placed in non banked memory. Please add command #pragma CODE_SEG NON_BANKED before your interrupt routines and command #pragma CODE_SEG DEFAULT at end of ISRs. Note: Better practice is hold these commands for every interrupt routine.


0 Kudos
1,852 Views
Claire
Contributor I


You say, for one interruption : I must do this ? What is signification of #pragma CODE_SEG DEFAULT and #pragma CODE_SEG NON_BANKED ?

void interrupt 8 TOC0_ISR () {

#pragma CODE_SEG NON_BANKED 

  TFLG1 = TFLG1_C0F_MASK ;    // rabaisse le flag de l'interruption
  buffer_empty1 = buffer_lenght - buffer_full1;
 
if (buffer_empty1 == buffer_lenght) {
    PORTB =0b00000100  ;
     sendOnCanEmpty ()   ; 
}
  if ( read_buffer_wheel1 < buffer_lenght ){                    //test taille de la memoire
     TC0 = TC0 + wheel1[read_buffer_wheel1] ;                //lecture des donnees
     read_buffer_wheel1 ++    ; //incrementation compteur lecture
      } else{
         read_buffer_wheel1 = 0    ;                           //rebouclage memoire   .
         TC0 = TC0 + wheel1[read_buffer_wheel1] ;                //lecture des donnees
     }

#pragma CODE_SEG DEFAULT

}

0 Kudos
1,852 Views
Claire
Contributor I

I programm like your suggestion but now the message Illegal_bp is return. I don't understand what causes this error.

0 Kudos
1,854 Views
RadekS
NXP Employee
NXP Employee

This way:

#pragma CODE_SEG NON_BANKED

void interrupt 8 TOC0_ISR () {

}

#pragma CODE_SEG DEFAULT

These commands are dedicated for linker. This way linker know where you want place your code. There are different ways how to do it, but this is simply and comfortable.

Similar commands:

#pragma DATA_SEG – for variables

#pragma CONST_SEG – for constants


0 Kudos
1,852 Views
Claire
Contributor I

I corrected my program but the message Illegal_bp still appears.

Do you want I'll send the new program ?

0 Kudos
1,852 Views
Claire
Contributor I


I don't see : When I did debug, I have message "segment pragma has not handled" for the second interrupt.

0 Kudos
1,852 Views
Claire
Contributor I

I don't see (again) I 'm not comment this line  "CAN2RIER = 0x01;" in receive on CAN. This line create en error.

Now It's OK my program run !!

I just have last question : the message "illegal_bp" is corrected by #pragma CODE_SEG NON_BANKED and #pragma CODE_SEG DEFAULT ? Why ?

(if I encounter this error again I want to be able to fix it without help)

0 Kudos
1,852 Views
kef
Specialist I

Don't ignore linker warnings and you will be warned about missing __NON_BANKED.

These #pragma CODE_SEG are required to place interrupt handlers in non banked memory. On interrupts page isn't switched, vector table entry is nonbanked address, so you need to force interrupt handlers to non banked memory.

0 Kudos
1,853 Views
Claire
Contributor I

Ook , so I always get the message " pragma CODE_SEG NON_BANKED has not handled" that appears. only for the second interruption. why ? I haven't this message for the first.

0 Kudos
1,853 Views
RadekS
NXP Employee
NXP Employee

Yes, I will check the code tommorow.

0 Kudos
1,853 Views
Claire
Contributor I

Ok, thank you very much !!  I try to find the solution for a week.

0 Kudos