Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Program seems to reboot itself

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
autoguider

Bascom Member



Joined: 24 Sep 2007
Posts: 57
Location: Aachen

germany.gif
PostPosted: Tue Sep 25, 2018 2:54 pm    Post subject: Program seems to reboot itself Reply with quote

Dear All,
I found the strange behaviour in my program that I experience the first time.

The ÁC is a AVR 168 @ 6.144 MHz running on a Pollin evaluation board. External power supply.
Rectifier is on board of the evaluation board.
PC6 is configured as RESET. As far as I can see there is no pull up resistor on the evaluaion board for PC6
Here a short schematic of the program

Definitions & declarations like dim, config ...

Goto main

code of subroutines
sub 1
sub 2
sub init()
sub evaluate_strings()
.
.
main:

call init


do
call evaluates_strings
call Evaluate keys
.
.
loop

Code ISR_1
Code ISR_2

ISR are serving events stimulated by timer0 and timer2.
The subroutines mainly send messages via RS232 as anwers to the evaluation of the input string.
Input and output are buffered.

From time to time after going through as short anwering routine the init procedure gets started. I get it indicated by a message via UART.
That drives me to the conlusion that the AVR is rebooting unexpectedly.

I am running a main timer that produces a cycle with 20 ms period. This timer calculates the on times and the off times for two RC servos.
Execution takes 69 cycles = 11 Ás
The timer producing the signals for the 2 servos is called 4 times within the 20 ms frame. 1 execution takes 45 cycles. = 7Ás

Is there an event that may cause the controller to rebboot. Overflow ?, Timeouts ?
The reboot happens irregular but alwas after requesting an anwers to an input string.

Please let me have your advice.

best regards
Christian

(BASCOM-AVR version : 2.0.8.1 )
Back to top
View user's profile
i.dobson

Bascom Expert



Joined: 05 Jan 2006
Posts: 1534
Location: Basel, Switzerland

switzerland.gif
PostPosted: Tue Sep 25, 2018 3:24 pm    Post subject: Reply with quote

Hi,

How large are your stacks (SW,HW,FRAME)?

Regards
Ian Dobson

_________________
Home of AVRTimer, the Bascom timer value calculator.
http://www.planet-ian.com

Walking on water and writing software to specification is easy if they're frozen.
Back to top
View user's profile Visit poster's website
autoguider

Bascom Member



Joined: 24 Sep 2007
Posts: 57
Location: Aachen

germany.gif
PostPosted: Tue Sep 25, 2018 5:32 pm    Post subject: Reply with quote

Hi Ian,
here the data;
$lib "mcs.lbx"
$regfile = "m168def.dat"
$prog &HFF , &HE7 , &HDF , &HF8 ' generated. Take care that the chip supports all fuse bytes.
$crystal = 6144000 ' used crystal frequency 0 error in UART
$baud = 19200 ' used baud rate
$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 20 ' default use 10 for the SW stack
$framesize = 64

Here the usage of the stack for a ISR

push r15 'r 15 to Stack
in r15,sreg 'Read Statusregister R15
push r15 'Statusregister to Stack
push r20 'r 20 to Stack
push r19 'r 19 to Stack
push r28 'Y Register
push r29
push r30 'Z- Register
push r31

ISR should not be nested. To my information the interrupt that is just about to be executed blocks the execution of other interrupts.

In the evaluate_strings subroutine the subroutines to answer re addressed via call subroutine.
There are no parameters that are transferrred to the subroutines. Basically it is like using global variables only.

best regards

Christian
Back to top
View user's profile
i.dobson

Bascom Expert



Joined: 05 Jan 2006
Posts: 1534
Location: Basel, Switzerland

switzerland.gif
PostPosted: Tue Sep 25, 2018 6:25 pm    Post subject: Reply with quote

Hi,

What happens if you use pushall/popall in your ISR. If that works then you'll Need to look at the ISR more closely.

On AVR's Interrupts are not nested (when an ISR is active it won't be interrupted by a new Interrupt, unless you Play with asm cli,sei).

You you post all the code, rather than just Little bits.

Regards
Ian Dobson

_________________
Home of AVRTimer, the Bascom timer value calculator.
http://www.planet-ian.com

Walking on water and writing software to specification is easy if they're frozen.
Back to top
View user's profile Visit poster's website
hgrueneis

Bascom Member



Joined: 04 Apr 2009
Posts: 859
Location: A-4786 Brunnenthal

austria.gif
PostPosted: Wed Sep 26, 2018 7:07 am    Post subject: Reply with quote

Install a 10K pullup on PC6 and increase the stack.
Regards
Hubert
Back to top
View user's profile
autoguider

Bascom Member



Joined: 24 Sep 2007
Posts: 57
Location: Aachen

germany.gif
PostPosted: Thu Sep 27, 2018 10:00 pm    Post subject: Program seems to reboot itself Reply with quote

Dear All,
thanks for replying.
I installed the pull-up resistor on the evaluation board. It will definetely help to have clear conditions on the board.
In the meantime i did some research and found that one of my ISRs causes the trouble.
To my opinion it has someting to do with the handling of portC. C6 is tzhe reset !

here some excerpt code of the old ISR that causes trouble:
Code:


Servopuls_isr_t2:                       'Creates pulses for the servos


   $asm

      push r20                          'Statusregister in r 30
      in r20,sreg                       'Statusregister to Stack
      push r20                          'Servonr
      push r19                          'adressieren der Ausgńnge, allg variable

      in r19,portC                      'Load status from PortC; C.1 and C.2 are for the servos

     AndI r19, &b11111001               'Mask to reset all servo pins
     ori r19, &b01000000


      !Out Portc , R19                  'Set servo outputs to 0
      Loadadr B_servonr , X
      Ld r20 , X                        'ServoNr in r20; Start Value =0
      inc r20                           'Increment servoNr

      cpi r20,1                         'Equal to 1 ?
      brne Rest1                        'if not fill rest of period

      ' ServoNr =1 1st "on" time

      st X , R20                        'store incremented B_ServoNr
      in r19,portc                      'Load status of PortC
      OrI r19, &b00000010               'Set C.1 to 1
      AndI r19,&b11111011               'update
      !Out Portc , R19                  'Set pins of PortC
      SBI portc,1
      Loadadr B_impulsdauer(3) , X      'Load duration of switch on phase
      ld r19,x
      !Out Ocr2a , R19                   'Set value for next ocr2a interrupt
      ldi r19,0
      !out tccr2, r19                    'Set counter value of timer to 0
      jmp Endeasm


I have the strong assumption that the acces to port C causes a reset. The init procedure was statred again and again.
Could you confirm that for some reason Port c.6 can be brought to 0 and then causes a reset ▀

Now the "new " code with comments in English language.

Code:

Servopuls_isr_t2:                       'Creates pulses for the servos


   $asm

      push r20                          'save content r20 to stack
      in r20,sreg                       'load statusregister in r 20
      push r20                          'save status register to stack
      push r19                          'save content r19 to stack

      cbi portc,1                       'Clear C1 = Pulse Servo 1 =0
      cbi Portc,2                       'Clear C1 = Pulse Servo 2 =0

      Loadadr B_servonr , X
      Ld r20 , X                        'ServoNr in r20; Start Value =2
      inc r20                           'Increment B_servoNr

     '--------------- "ON" time servo 1

         cpi r20,3                      'Equal to 1 ?
         brne OFF_time_servo_1          'if value =4
         st X , R20                     'store incremented B_ServoNr
         SBI portc,1                    'set pin c1 =1. "ON" time servo 1
         Loadadr B_impulsdauer(3) , X   'Load duration of switch "on" phase
         ld r19,x
         !Out Ocr2a , R19               'Set value for next ocr2a interrupt
         ldi r19,0
         !out tccr2, r19                'Set counter value of timer2 to 0

      jmp End_ISR_t2                    'JMP to exit procedure ISR

    '---------------- OFF time servo 1

    Off_time_servo_1:                   'Fill time gap so that servos get their signals in the 20ms frame

     cpi r20,4                          'check if value =4
     brne ON_Time_Servo_2               'Goto "HIGH" phase servo 2

     st x , r20                         'store value 4 to B_servonr
     Loadadr B_impulsdauer(4) , X       'load value for filling remaining time gap
     ld r19,x
     !Out Ocr2a , R19
     ldi r19,0
     !out tccr2, r19                    'Set counter value of timer2 to 0


    jmp End_ISR_t2



   On_time_servo_2:

     cpi r20,5                          'Check if value =5
     brne OFF_time_servo_2              'Goto OFF time servo 2

  '--------------- "ON" time servo 2

     st x , r20                         'store value 5 to B_servonr

     sbi portc,2                        'set pin c1 =2. "ON" time servo 2
     Loadadr B_impulsdauer(5) , X       'Load duration of switch "on" phase servo 2
     ld r19,x
     !Out Ocr2a , R19                   'Set value for "ON" time servo 2
     ldi r19,0
     out tccr2, r19                     'Set counter value of timer to 0
     jmp End_ISR_t2                     'JMP to exit procedure ISR


 Off_time_servo_2:

     cpi r20,6                          'Check if value =6
     brne Reset_Servo_Count             'jmp if b_servonr has normally value 7
     st x , r20                         ' B_Bervonr = 6; Save value
     Loadadr B_impulsdauer(6) , X       'Fetch value for "OFF" time servo 2
     ld r19,x                           'load value for "OFF" time servo 2 to r19
     !Out Ocr2a , R19                   'Set timer register to OFF time value
     ldi r19,0
     !out tccr2, r19                    'Set counter value of timer2 to 0
     jmp End_ISR_t2                     'JMP to exit procedure ISR


Reset_servo_count:

     Loadadr B_servonr , X
     ldi r20,2
     st x ,r20                          'Set B_Servonr to 2; Is prepared for the next cycle of this ISR
     ldi r19, 0
     !Out Tccr2b , R19                  'Timer2 is stopped
     !out tcnt2 , r19                   'Timer 2 counter register =0



 End_isr_t2:
      pop r19
      pop r20                           'X Register High to Stack
      !out sreg,r20
      pop r20

 $end Asm

Return
 


Here the code of the timer ISR that takes care of the 20ms frame

Code:
20ms_Timer0_isr:                        'Starts 20ms frame

$asm
      push r15                          'r 15 to Stack
      in r15,sreg                       'Read Statusregister  R15
      push r15                          'Statusregister to Stack
      push r20                          'r 20 to Stack
      push r19                          'r 19 to Stack
      push r28                          'Y Register
      push r29
      push r30                          'Z- Register
      push r31


      Loadadr B_impulsdauer(3) , Z      'Duration of "ON" phase addressed via Z register
      ld r20,z                          'Duration in r20
      Loadadr B_fahrzustand(2) , Y      'Y adresses mode of movement
      ld r19 ,y                         'value in r19
      ADD r20,r19                       'Addition, result in r20
      st z,r20                          'save in Impulsdauer(3)

      ldi r19,254                       'Calculate time gap to meet 20ms frame servo 1
      !Sub R19 , R20
      st z+1,r19                        'Save in Impulsdauer(4)

      ld r19,y+1                        'R 19 contains Fahrzustand(3)
      ld r20,z+2                        'R 20 contains Impulsdauer(5) = ON time servo 2
      add r20,r19                       'Addition Ergebnis in R20
      st z+2,r20                        'store new value of "ON" time servo 2 in Impulsdauer(5)

      ldi r19,254                       Calculate new value for "OFF" time servo 2
      !SUB R19 , R20
      st z+3,r19


     ' Noadd:
     '    Loadadr B_anfangsdelay,z
'         ld r20,z
'         inc r20
'         st z,r20

      ldi r20,3                         'R20 nun als allg Variable nutzen
      !Out Ocr2a , R20                  'Set OCR2A to 3 to have a time distance between ISRs
      ldi r20,0
      !out tcnt2,r20                    'Set Counter register to 0 setzen
      ldi r20,&B00000011                'Configuration Timer 2 with pre scale etc..
      Out Tccr2b , R20                  'Load Timer2 register Starts Timer 2

      'LDI Ocr2a,1                       'Schwellwert auf 2 gesetzt damit ISR schnell ausgel÷st wird
      'LDI Tcnt2, 0                      'Counter 2 auf 0 gesetzt
      'LDI Tccr2b, &B00000011


      Pop r31                           'Stack aufrńumen
      Pop r30
      Pop r29
      Pop r28
      Pop r19
      Pop r20
      Pop r15
      Out Sreg , R15
      pop r15


'Executed operations
'B_Impulsdauer(3) = B_Impulsdauer(2) + B_Fahrzustand(2)
'B_Impulsdauer(5) = B_Impulsdauer(3) + B_Fahrzustand(3)
                  'startet Timer 2
'Dauer ca 11 us , 69 takte
     'reti
 $end Asm

 Return


It is a bit a tricky game between 2 interrupt service routines.

Let me share my idea how these ISR cooperate:

' The program serves 2 RC servos.
''

' Angular position of the servo is coded by the pulse width of control pulse.
' Working position is reached with pulse width of 2500 Ás.

' Initial position is both servos at 0 position. Pulse width 500Ás.
' Every 20 ms a 500Ás pulse is given to each servo.
' Timer 0 creates the 20 ms frame and calculates the length of each pulse,
' Servo 1 get its pulse at t=0; Servo 2 gets its pulse at t=2500Ás
' This means that Timer 0 calculates the ON time of the pulse at also the remaining time (=OFF time) until the next pulse for the second servo.
' In total there are 20000Ás/2500Ás= 8 servos possible to handle in the 20 ms frame.
' Timer 0 starts Timer 2.
' Timer 2 creates consecutively the pulses for servo 1 and servo 2.
' In the main loop it is watched that the values for the timers stay in the permitted range.
'.
'
' There are 3 kinds of movement for the servos which is coded in following numbers:
' forward = Angle increasing Value:1; standing ' The program serves 2 RC servos.
'
' Definition of Filter 1 = Normalop; Filter 2 = Focussin; Filter 3 = Illumclr
'

' Angular position of the servo is coded by the pulse width of control pulse.
' Working position is reached with pulse width of 2500 Ás.

' Initial position is both servos at 0 position. Pulse width 500Ás.
' Every 20 ms a 500Ás pulse is given to each servo.
' Timer 0 creates the 20 ms frame and calculates the length of each pulse,
' Servo 1 get its pulse at t=0; Servo 2 gets its pulse at t=2500Ás
' This means that Timer 0 calculates the uptime of the pulse at also the remaining time until the next pulse for the second servo.
' In total there are 20000Ás/2500Ás= 8 servos possible to handle in the 20 ms frame.
' Timer 0 starts Timer 2.
' Timer 2 creates consecutively the pulses for servo1 and servo 2.
' In the main loop it is watched that the values for the timers stay in the permitted range.
'.
'
' There are 3 kinds of movement for the servos which is coded in following numbers:
' forward = Angle increasing Value:1; standing value 0; back value FF ( corresponds to -1┤ in 2'complement)
' These values are in the array B_Fahrzustand.

'


' ####################### Function Timer 0

' Timer 0 creates the periodic 20 ms frame and calculates the duration of the ON-phase and the OFF phase of the control pulses.

' By adding the value of B_Fahrzustand to the value for the trigger value of the timer event the pulse width gets modified.
' Addition of 0 (=standing) does not change the value and consequently not the pulse width, Angular position is unchanged.
' Addition of von "forward" ( value=1) increases the pulse width.
' Addition of "back" (value = -1) decreases pulse width.


' Values are stored in the array B_Impulsdauer(6) by Timer 0 ISR
' Index 1 not used
' Index 2 not used
' Index 3 Servo 1 "ON"time
' Index 4.Servo 1 "OFF" time
' Index 5 Servo 2 "ON" time
' Index 6.Servo 2 "OFF" time
' "ON" time+"OFF" time add up to appr. 2500Ás

' Then Counter register TCNT2 is set to 0 and OCR2A to the value 3 so that the interrupt of Timer 2 is executed with a short delay.
' Counter 2 is started.
'Here I need to test to come closer to the limits.

' Values of the pulse widths is performed every 20 ms. This results in a desired slow movement of the servos.
'.

' ####################### Function Timer 2

' In the Servopuls_ISR (Timer2) both ouputs for the servos will be brought to 0.
' OCR2A is loaded with the uptime value for servo 1. Output is set to 1.ISR is finished.
' When the timer reaches the "ON"ptime value the ISR is started again.
' Both servo outputs are set to 0.
' Then the value for servo 1 "OFF" time is send to OCR2a.. TCNT2 is set to 0. ISR finished.
' When Timer has reached the value of OCR2a the ISR is started again.
' OCR 2a now receives the value for servo 2 uptime. When counter reaches the value of OCR2a the ISR is started again.
' Both output pins are set to 0. OCR2A receives the value for the OFF-time of servo 2.
' Next execution of the ISR stops timer 2. No further pulses are created until timer 0 initiates start of timer 2

I will be testing the new code.
Some good advice is always welcome.

best regards
Christian
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 677

poland.gif
PostPosted: Fri Sep 28, 2018 6:38 am    Post subject: Reply with quote

Why dont you save R26 and R27 if your Loadadr loads data into X?

Such short code:
Code:
$regfile = "m168def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 32
$framesize = 128

Dim B_impulsdauer(3) As Byte

Loadadr B_impulsdauer(3) , X

End


Is translated into:
Code:
14:       Loadadr B_impulsdauer(3) , X
000000A4: E0A2     LDI       R26, $02            
000000A6: E0B1     LDI       R27, $01      


So X is blurred for sure because you dont save and restore it (no Push and Pop R26,R27).

You must also know that Buffered Input/Output causes additional interrupts. With buffered output you have Interrupt on every char that must be sent.
Back to top
View user's profile Visit poster's website
autoguider

Bascom Member



Joined: 24 Sep 2007
Posts: 57
Location: Aachen

germany.gif
PostPosted: Fri Sep 28, 2018 11:04 am    Post subject: Reply with quote

Many thanks for the advice.
I modified the ISR with saving the X register.
I also changed the UART to non buffered in both directions. Communication to the PC via RS232 runs well.

best regards
Christian
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum