Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:13 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 : CMM2: Bug/unexpected behaviour wien Sub called by SetTick

     Page 1 of 2    
Author Message
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 06:00pm 09 Jul 2021
Copy link to clipboard 
Print this post

Possibly this is "by design", but

> 480MHz Colour Maximite 2 G2
MMBasic Version 5.07.00
Copyright 2011-2021 Geoff Graham
Copyright 2016-2021 Peter Mather

> list "bug.bas"
Option Explicit

SetTick 1000, foo
Do : Loop

Sub foo(a%)
 Print a%
End Sub

> run "bug.bas"
Error in line 7: A is not declared


I would have expected parameter a% to have the value 0 as it would if "foo" were called without any arguments from elsewhere in the code.

This isn't a made up case, I was hoping to reuse the "foo" function with non-zero arguments elsewhere.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 06:11pm 09 Jul 2021
Copy link to clipboard 
Print this post

What an interesting test case!

John
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 06:15pm 09 Jul 2021
Copy link to clipboard 
Print this post

Despite the thread title "... behaviour wein Sub ..." this is not a question about Vienna, I would have capitalised it if that were the case
Edited 2021-07-10 04:19 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 06:16pm 09 Jul 2021
Copy link to clipboard 
Print this post

  JohnS said  What an interesting test case!

John


It beat the 700 lines of actual code - not all within the SetTick/interrupt I hasten to add.

Best wishes,

Tom
Edited 2021-07-10 04:16 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: 07:33pm 09 Jul 2021
Copy link to clipboard 
Print this post

Thanks for the report.

That does not seem correct.  I cannot check it at this time as I am away for most of the month but when I get back I will look into it and report back.

In the meantime could you try it without the brackets in the definition, ie:
Sub foo a%

It should not make any difference.

Geoff
Edited 2021-07-10 05:39 by Geoffg
Geoff Graham - http://geoffg.net
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 07:48pm 09 Jul 2021
Copy link to clipboard 
Print this post

  Geoffg said  It should not make any difference.


It didn't make a difference, the same error is reported.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 09:52pm 09 Jul 2021
Copy link to clipboard 
Print this post

A workaround so Geoff can continue his holiday in peace:
  Quote  OPTION EXPLICIT

SETTICK 1000, fooX
DO : LOOP

SUB fooX
foo
END SUB

SUB foo(a%)
PRINT a%
END SUB


Jim
VK7JH
MMedit
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1132
Posted: 10:39pm 09 Jul 2021
Copy link to clipboard 
Print this post

So you want an interrupt to call a subroutine that is also called by the main code.

What do you think will happen if the program flow is in this routine when the timer interrupt triggers?
Visit Vegipete's *Mite Library for cool programs.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 10:49pm 09 Jul 2021
Copy link to clipboard 
Print this post

  vegipete said  So you want an interrupt to call a subroutine that is also called by the main code.

What do you think will happen if the program flow is in this routine when the timer interrupt triggers?


I do it often.
Use SETTICK to set up the main calls and then use a direct call to run the SUB the first time instead of waiting 10 seconds (or more) for something to happen.

Jim
VK7JH
MMedit
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 11:01pm 09 Jul 2021
Copy link to clipboard 
Print this post

Thanks Jim, I was already using that workaround before you posted.

@Vegipete my understanding is that these interrupts can only happen between statements so in theory it should be possible to concoct some sort of lock to prevent the interrupt running the body of foo() if the main thread of control is already in there. I say "in theory" because I have spent my evening trying to do just that and don't think I succeeded. I will need to experiment some more on Sunday.

Best wishes,

Tom
Edited 2021-07-10 09:02 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2640
Posted: 01:54am 10 Jul 2021
Copy link to clipboard 
Print this post

"I do it often.
Use SETTICK to set up the main calls and then use a direct call to run the SUB the first time instead of waiting 10 seconds (or more) for something to happen."

Ditto.
To get data from sensors etc. in the setup before the main loop.
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1132
Posted: 05:52am 10 Jul 2021
Copy link to clipboard 
Print this post

  Quote  I do it often.

Sounds to me that you have ensured that no clash will occur because you do not access the routines once the ISR is running.

Here's a silly contrived example that shows the occasional clash (at least on my 400MHz CMM2.)
> list
dim s,a(50)
settick 499, foo
do
  foo
  if s mod 50 <> 0 then print s
  pause 1
loop

sub foo
  local i
  s = 0
  for i = 1 to 50
    a(i) = a(i) + 1
    s = s + a(i)
  next i
end sub

No surprise really. Seems like some sort of 2 stage flag could solve this. Foo must not run from the ISR if it is currently running from the main routine. Instead, the ISR request needs to be held until after foo returns to the main routine.

Alas, I can't think of a suitable interlock this evening... maybe I'll dream a solution.
Visit Vegipete's *Mite Library for cool programs.
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 06:05am 10 Jul 2021
Copy link to clipboard 
Print this post

The recommended way of using interrupts is to keep them short.
Just set a flag and let the main program loop handle the work.

That way, having the flag set by two different triggers will not cause any grief.

If the timing is slow, a long sub is OK but for rapid timing, having the main loop get the sequence right is better.

Jim
VK7JH
MMedit
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 06:48am 10 Jul 2021
Copy link to clipboard 
Print this post

I'm using the "interrupt" to flash a cursor but need to handle the main "thread" moving the cursor after it has been drawn but before it has been restored.

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7937
Posted: 08:19am 10 Jul 2021
Copy link to clipboard 
Print this post

How about just toggling a "cursor lit" flag in the ISR, Tom? Don't do anything else - you really need to handle the cursor in the main body of the program anyway. You can temporarily disable the ISR & force the cursor on or off while you do something specific then re-enable the ISR.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 08:45am 10 Jul 2021
Copy link to clipboard 
Print this post

  Mixtel90 said  How about just toggling a "cursor lit" flag in the ISR, Tom? Don't do anything else - you really need to handle the cursor in the main body of the program anyway. You can temporarily disable the ISR & force the cursor on or off while you do something specific then re-enable the ISR.


Hi Mick,

I don't see any particular reason why I can't handle rendering of the cursor in the ISR, otherwise my approach is similar to that you suggest.

For me this has now become less about the final result, there are other ways to achieve that, and more about learning how to protect against race conditions between the main "thread" and ISRs, which basically means determining what can be used atomically to implement a guard. It is also possible I have already implemented the guard correctly, but missed somewhere in my code that it needed to be checked/cleared.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 08:45am 10 Jul 2021
Copy link to clipboard 
Print this post

  Mixtel90 said  How about just toggling a "cursor lit" flag in the ISR, Tom? Don't do anything else - you really need to handle the cursor in the main body of the program anyway. You can temporarily disable the ISR & force the cursor on or off while you do something specific then re-enable the ISR.


Hi Mick,

I don't see any particular reason why I can't handle rendering of the cursor in the ISR, otherwise my approach is similar to that you suggest.

For me this has now become less about the final result, there are other ways to achieve that, and more about learning how to protect against race conditions between the main "thread" and ISRs, which basically means determining what can be used atomically to implement a guard. It is also possible I have already implemented the guard correctly, but missed somewhere in my code that it needed to be checked/cleared.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7937
Posted: 09:10am 10 Jul 2021
Copy link to clipboard 
Print this post

So good it got posted twice?  :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 10:18am 10 Jul 2021
Copy link to clipboard 
Print this post

Generally you should not call interrupt subs from the main code.  It is OK if you are sure that the interrupt will not fire while you are doing that - like calling a SETTICK sub straight after starting the SETTICK.

If you do call an interrupt sub from the main code and the interrupt fires strange things can happen.  This includes corrupted STATICs, LOCALs, FOR loops, DO loops, etc as well as turning your hair prematurely grey.

On re reading the CMM2 manual I discovered that this warning is missing from it (it is in the Micromite manuals).  I will fix this omission on the next release.

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

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 10:31am 10 Jul 2021
Copy link to clipboard 
Print this post

I was using a STATIC to implement a lock under the misapprehension that they were implemented as strangely scoped globals.

Geoff could you clarify what operations can be considered to be atomic and what can be interrupted by an ISR ?

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025