Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:34 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Line/statement execution and Interrupts

     Page 1 of 2    
Author Message
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 07:52pm 13 Nov 2020
Copy link to clipboard 
Print this post

Hi,
I've looked through the manuals, and searched on the forum, but have not been able to find a definitive answer as to how basic responds to interrupts.

The documentation (and forum) stipulates that interrupts are generally responded to "within 50uS" or "within 100uS" depending on where you read. Some commands/functions delay this, for example some one-wire commands, writing to flash.

How does basic handle interrupts when processing a line?

For example (really simple stupid example, but to illustrate a point):
a$ = a$ + b$ + c$ : a$ = a$ + d$ + e$
a$ = a$ + f$ + g$

An interrupt event happens between concatenating b$ and c$, and the ISR code does:
a$ = a$ + i$

Are interrupts held off while executing a statement, or executing a line, or not disabled at all unless specifically disabled (eg: as they are during the DS18B20 'TEMPR(n)' function)?

So, for the above code, what would I get?
1] ABiCDEFG
2] ABCiDEFG
3] ABCDEiFG

Also, how (or can) interrupts be disabled by basic? The "Getting Started With the Micromite" Version 6 manual says, on page 54, 3rd dot point, talking about nested interrupts : "If you must call a subroutine...must disable the interrupt first...then reinstate it after..."
I know my example is not a nested interrupt, but could I do:
disable interrupts : a$ = .....
..... : enable interrupts

and what is the command to do this, I can't find one... is there one?

Cheers,
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 08:46pm 13 Nov 2020
Copy link to clipboard 
Print this post

You have to disable each individual interrupt. There is no global disable/enable
So for SETTICK:
These interrupts can be disabled by setting ‘period’ to zero (ie, SETTICK 0, 0, 3 will disable tick timer number 3).

When running, interrupts are checked at the end of each line so a one-liner will not get interrupted but can cause interrupts to be delayed.

Jim
VK7JH
MMedit
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 08:56pm 13 Nov 2020
Copy link to clipboard 
Print this post

  TassyJim said  When running, interrupts are checked at the end of each line so a one-liner will not get interrupted but can cause interrupts to be delayed.

Jim


End of each line ? or end of each statement ?

Tom
Edited 2020-11-14 06:56 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 09:13pm 13 Nov 2020
Copy link to clipboard 
Print this post

Interrupts are checked at the end of each statement.  So, in MustardMan's example he will get ABCiDEFG.

Jim is right in that there is no global interrupt disable so you need to disable each interrupt individually (not hard to do).

Geoff
Geoff Graham - http://geoffg.net
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 09:22pm 13 Nov 2020
Copy link to clipboard 
Print this post

  thwill said  
  TassyJim said  When running, interrupts are checked at the end of each line so a one-liner will not get interrupted but can cause interrupts to be delayed.

Jim


End of each line ? or end of each statement ?

Tom


You are right, it get checked after each statement

 SETTICK 1000, ticktock, 1
 PRINT "start "; TIME$
 PAUSE 10000
 PRINT "first pause ended"; TIME$
 SETTICK 0,,1 ' interrupt disabled
 PAUSE 10000
 PRINT "second pause ended"; TIME$
 SETTICK 1000, ticktock, 1 ' interrupt re-enabled
 
DO:LOOP
 
SUB ticktock
 PRINT "tick "; TIME$
END SUB


Jim
VK7JH
MMedit
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 10:47pm 13 Nov 2020
Copy link to clipboard 
Print this post

Thank you all for the quick and informative replies.

My question stems from my assembler background where interrupts can slip in between any instruction, but can't interrupt the instruction itself - although I don't know how it works for "long" instructions like a hardware multiply or divide. I also don't know what happens when a more complex CPU executes a SIMD instruction. The older I get, the more I realise I don't know!

Obviously all higher level languages have to execute multiple machine instructions to execute a 'statement atom' (eg: a = b + c), so knowing the 'statement atoms' can't be jumped into by an interrupt is very useful info.

Thanks everyone!
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 11:22pm 13 Nov 2020
Copy link to clipboard 
Print this post

  MustardMan said  My question stems from my assembler background where interrupts can slip in between any instruction, but can't interrupt the instruction itself

Some CPUs do interrupt mid-instruction e.g. Intel 86 family (read up on LOCK to overcome).

MMBasic is nice in this regard!

John
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 02:38am 14 Nov 2020
Copy link to clipboard 
Print this post

Ouch! SIMD?

I never got into the 8086. I didn't like it one bit (no pun on that one).

I started with Z80, later got into 8051. Both very nice architectures and instruction sets. Later looked at 6502, and compared to what I was used to thought it was rubbish. Then looked seriously at the 8086, but after intel made it so complex it wasn't funny, I'm really glad I steered clear.

Then I started work at a place that used PIC. Expletive!! Let's just say I was not impressed with either the architecture or the instruction set (this was a couple of decades ago before microchip got a clue). Unfortunately all their new stuff has to be compatible with their old stuff, so most of it is still a POS.

Thank god someone put an intense amount of effort (and it must have been intense) into developing a compiler for the PICs. Yes, they have great on-chip peripherals, but the rest!
 
Cyber

Senior Member

Joined: 13/01/2019
Location: Ukraine
Posts: 161
Posted: 04:33am 14 Nov 2020
Copy link to clipboard 
Print this post

Thank you for information!
I want to add more questions for better understanding interrupts.
Quotes from Micromite manual.

  Quote  When inside an interrupt all other interrupts are blocked so your interrupts should be short and exit as soon as possible.


What are the risks if I make an interrup that works long?
My other interrupts will stay in queue and will all be delayed?
Or am I risking that other interrupts will be lost?
Is there a limit of this queue?

And what happens to main program when long interrupt is working? Will the main program just wait for interrupt to end? Or main program and interrupt run in parallel?

  Quote  If you must call a subroutine that is also used by an interrupt you must disable the interrupt.

What if I don't? What will happen?
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 05:34am 14 Nov 2020
Copy link to clipboard 
Print this post

So many questions  

  Cyber said  What are the risks if I make an interrup that works long?

You might miss other interrupts or your main program could get very little time to run.  

A common fault for new programmers is to spend too much time in interrupts and then wonder why their main program has stopped working or is running very slow.  Generally you don't need to worry about an interrupt that occurs once a minute but if you have an interrupt that occurs every millisecond you need to look at it very carefully.

  Cyber said  My other interrupts will stay in queue and will all be delayed?
Or am I risking that other interrupts will be lost?

It depends.  Most interrupts such as timer ticks (SETTICK), serial input, I2C, IR, etc will be held waiting for the current interrupt to finish.  The big exception is interrupt on an I/O pin.  For example, if your interrupt is set to occur when an input pin goes high (say a button press) then it is possible that the voltage will go high then low again while you were wasting time in an interrupt sub and the button press would not be seen and would be lost.

  Cyber said  Is there a limit of this queue?

There is no interrupt queue.  At the end of each BASIC command the interpreter will check all possible interrupt sources in order of priority (page 40 Micromite manual).  When MMBasic returns from the interrupt subroutine that particular interrupt will be cleared.

  Cyber said  And what happens to main program when long interrupt is working?

The the main program will just wait for the current interrupt subroutine to exit.

  Cyber said  
  Quote  If you must call a subroutine that is also used by an interrupt you must disable the interrupt.

What if I don't? What will happen?

If you have called the interrupt sub normally and an interrupt occurs while executing the sub MMBasic will call the sub a second time and any FOR loops, DO loops and static variables in the sub will be corrupted and possibly cause your hair to turn prematurely grey.

Geoff
Edited 2020-11-14 17:01 by Geoffg
Geoff Graham - http://geoffg.net
 
Cyber

Senior Member

Joined: 13/01/2019
Location: Ukraine
Posts: 161
Posted: 09:52am 14 Nov 2020
Copy link to clipboard 
Print this post

Thank you very much for detailed answer, Geoff!
Many things became clear for me.

  Geoffg said  Most interrupts such as timer ticks (SETTICK), serial input, I2C, IR, etc will be held waiting for the current interrupt to finish.

What if another interrupt happens, while one is already being held waiting?
Will they both be waiting? Or is there only one waiting slot?
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 10:40am 14 Nov 2020
Copy link to clipboard 
Print this post

Please - plan not to need the answers!

Write VERY short interrupt routines if you cannot do without them entirely (e.g. Grogster posted the kinds of code that helps not need a COM ISR).

Regard every non-trivial ISR as a disaster waiting to happen & nightmare to debug.

The above applies in assembler, too.

John
Edited 2020-11-14 20:41 by JohnS
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 10:56am 14 Nov 2020
Copy link to clipboard 
Print this post

From my understanding of the PIC32 there are several interrupt slots, but many of them are shared. Without looking at the datasheet I could not say which are the shared ones. However, for the sake of argument say all the serial port peripherals share one interrupt (ie: SPI/I2C/UART). A perfectly valid thing to do, and the way you determine what caused the interrupt is by checking a subset of peripheral flag bits to find out which one (or ones) are causing all the trouble.

The smaller micros often only have a single interrupt and it is therefore necessary to check all the flags (only for the interrupts you are using of course - not the whole lot!)

But that is assembler stuff, and not C or BASIC, so I might be blowing smoke out my...


Interrupts will "queue" up, if they are not shared. For example, a timer interrupt won't be shared with a UART interrupt.

Take the scenario: the UART interrupt goes off, so you respond (execute your UART ISR), but you spend ages and ages in there. The timer interrupt goes off and will be queued to jump into its' ISR the moment you pop out of the UART ISR.

The problem occurs if you get more than one timer tick while you are fooling about in your UART ISR, because the timer interrupt flag only gets set once. Similar things happen with other interrupts too (and has got me several times).
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 11:54am 14 Nov 2020
Copy link to clipboard 
Print this post

If you hit any of those kinds of problems your ISR is WAAAAYYYY TOOOO LOOONNNGGG.

Do the very bare minimum.

John
 
Tinine
Guru

Joined: 30/03/2016
Location: United Kingdom
Posts: 1646
Posted: 02:45pm 14 Nov 2020
Copy link to clipboard 
Print this post

  JohnS said  

Regard every non-trivial ISR as a disaster waiting to happen & nightmare to debug.

John




Ever since I read Charles Petzold's Programming Windows, I have regarded interrupts as a last resort.
 
Cyber

Senior Member

Joined: 13/01/2019
Location: Ukraine
Posts: 161
Posted: 04:51am 17 Nov 2020
Copy link to clipboard 
Print this post

Everybody, thank you very much for all your useful answers!!
They clear up things a lot.

  JohnS said  If you hit any of those kinds of problems your ISR is WAAAAYYYY TOOOO LOOONNNGGG.
No, I did not hit any of these problems. At least yet. ) Currently all my interupts fire rarely and interrupt routines are short. I was asking all my questions for the sake of understanding of how it all works.

  JohnS said  Ever since I read Charles Petzold's Programming Windows, I have regarded interrupts as a last resort.
So you mean if can handle some event just by regulary checking it in main program loop I should do it instead of using interrupt?
I understand it is a good practice, which simplifies code debugging.
But I always thought of interrupts as an advanced and reliable feature, though hard to debug one. In fact many low level system things in PC are built on interrupts.
Edited 2020-11-17 14:58 by Cyber
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:59am 17 Nov 2020
Copy link to clipboard 
Print this post

  Cyber said  So you mean if can handle some event just by regulary checking it in main program loop I should do it instead of using interrupt?

Interrupts to do things that can not wait and set a flag.
The main program loop can then process the events in an orderly manner. This usually helps stop unexpected things happening when a value gets changed mid-process.

We don't have multiple threads in MMBasic although some things can happen in the background which can be similar.

Jim
VK7JH
MMedit
 
Cyber

Senior Member

Joined: 13/01/2019
Location: Ukraine
Posts: 161
Posted: 05:26am 17 Nov 2020
Copy link to clipboard 
Print this post

  TassyJim said  Interrupts to do things that can not wait and set a flag.
The main program loop can then process the events in an orderly manner. This usually helps stop unexpected things happening when a value gets changed mid-process.

Sounds like a golden mean. )
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 07:03am 17 Nov 2020
Copy link to clipboard 
Print this post

  TassyJim said  Interrupts to do things that can not wait and set a flag.

Spot on... although a comma might make it clearer...
Interrupts to do things that can not wait, and [often simply] set a flag.

There are a lot of really good reasons to use interrupts, but you have to think about why you are using interrupts to do it, and if so, think about what/how your main program will respond. It is up to the human behind the code to work through the details...

  JohnS said  Regard every non-trivial ISR as a disaster waiting to happen & nightmare to debug.

It is a very easy trap. I fell into it only last week with my code for reading a serial port... thankfully Grogster set me straight and made me realise I didn't need an interrupt at all!

Changing variables unexpectedly is a common trap. For example: n is a scratchpad number. You use it as a temporary counter in your main code (eg:n=n+1 every time someone touches the touch screen), but the ISR also uses it for looping (eg: FOR n=1 TO 5). Main code is counting presses... interrupt happens... and now your main count is wrong.

But most problems happen when the ISR takes longer than it should, especially when the ISR takes longer than the time between interrupts!

Cheers,
 
Cyber

Senior Member

Joined: 13/01/2019
Location: Ukraine
Posts: 161
Posted: 07:23am 17 Nov 2020
Copy link to clipboard 
Print this post

  MustardMan said  There are a lot of really good reasons to use interrupts


Currently I'm thinking that interrupt is very handy for catching input pin pulse. Because if I check for it in a main program loop, I have a risk to miss it (if pulse is very short, and my main program loop is long). In this case interrupt with flag is a better choice.

On the other hand I'm thinking that using interrupt for catching COM port input might not always be a necessary case. COM port has a buffer, where characters can wait for a while. And in most cases it does not hurt to check this buffer in main program loop.
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025