![]() |
Forum Index : Microcontroller and PC projects : 'flags' in interrupt routine
Page 1 of 2 ![]() ![]() |
|||||
Author | Message | ||||
58kk90 Regular Member ![]() Joined: 14/06/2023 Location: United KingdomPosts: 59 |
Another 'numpty' question from a newbie. I have started playing with pin change interrupts on the Pico, and as the manual says the idea is to have as little going on in the actual intetrupt routine as possible, generally just set a flag to indicate something changed etc. In previous micro's (going back to 8048 / 8051 and then PIC and Arduino ) I would have a byte called for example 'flags' then set individual bits to indicate the event, i'd set each bit in the interrupt routine and then clear it in the main code. In Pico basic, there doesn't seem to be a byte variable type, which is fine, but how do you folks flag that something has changed in the interupt routine without using a 64bit variable for each event, which seems quite wasteful to me. Obviously I coud do this Dim PinChanged as integer PinChanged = 0 then in the interrupt routine set PinChanged to '1' and then act on it in the main program and set it back to zero, but I feel there must be a better and more efficient way that uses less variable space as it is only using a single 'bit' out of each 64 bit integer variable, if there are lots of different flags does that not use up valuable ram space? Or is there enough variable space that I need not worry about it and do it the way I suggested above? Tony |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1526 |
Hi Tony, one possibility would be to use 1-byte strings (actually 2 bytes = Dim myflag$ string LENGTH 1). The decoding effort would probably cancel out the benefit. I wouldn't worry about the memory consumption for integers at first, only for very large projects. Regards Michael I recently considered using the individual bits of an integer as flags for selected files in the file manager, but that's not worth the extra effort. Edited 2025-03-06 01:16 by twofingers causality ≠ correlation ≠ coincidence |
||||
lizby Guru ![]() Joined: 17/05/2016 Location: United StatesPosts: 3309 |
As Michael suggests, other than for exceptionally large programs, it is a waste of valuable programmer time to try to save extraordinarily cheap bits in MMBasic. So don't sweat the small stuff, and save your effort for the main chance. (As a one-time Z80 programmer, I understand the compulsion--if it drives you to save those bits, Cap'n Boing has routines on FruitOfTheShed ( FOTS ).) PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4249 |
Hi @twofingers, I've not explicitly checked the PicoMite firmware but I don't think that works the way you think it does. All memory allocation in MMBasic is in 256 byte blocks and as a result all (scalar) strings take 256 bytes from the heap, the LENGTH specifier only applies when allocating arrays of strings. I *think* that Peter added a hack to the Colour Maximite 2 firmware that allows very small strings 1 - 7 (or maybe 8) characters to be stored with the variable storage rather than on the heap but I don't think that hack is present on the PicoMite ... Peter may correct me. In answer to the OP you can use PEEK and POKE to access single bytes of an INTEGER or engage in bit twiddling, e.g. https://github.com/thwill1000/mmbasic-sptools/blob/master/src/splib/bits.inc or whatever the Captain has posted on https://fruitoftheshed.com. Best wishes, Tom Edited 2025-03-06 02:02 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
twofingers Guru ![]() Joined: 02/06/2014 Location: GermanyPosts: 1526 |
@Tom, Thanks for the hint, I think you're right, I vaguely remember. ![]() The manual doesn't help here either. Best regards Michael causality ≠ correlation ≠ coincidence |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1139 |
For efficient serial binary transfers, I set bits: dim integer a a=a or 1 a=a or 2 a=a or 4 a=a or 8 a=a or 16 a=a or 32 a=a or 64 a=a or 128 'a now equals 255 if a and 2 then a = a xor 2 ' reset the flag end if 'a now equals 253 |
||||
58kk90 Regular Member ![]() Joined: 14/06/2023 Location: United KingdomPosts: 59 |
Thank you to all who replied, I guess it's use a single variable for each flag bit then. @PhenixRising that is probably very close to how I would have eventually done it had I used a single variable for all flags, I wondered if there was something along the line of flags.1 for bit 1 or flags.2 for bit 2 and so on and it just wasn't documented, but I guess that would require 'flags' to be a byte variable, which we don't have. Tony. |
||||
ville56 Senior Member ![]() Joined: 08/06/2022 Location: AustriaPosts: 216 |
I usually define bitmasks as constants with meaningful names. AND and OR operators do the setting and testing. So i can use a single integer as an eventflag cluster for up to 64 flags. Regards Gerald 73 de OE1HGA, Gerald |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1139 |
Sure but unlike a compiler, the constants are not replaced with literals and so the interpreter loses time finding the value of those constants, right? I haven't heard much about MMReplace but from what I understand, it's a post-processor(?) where constants and long variable names can be replaced just prior to sending to the Mite(?) |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2137 |
like this? https://fruitoftheshed.com/wiki/doku.php?id=mmbasic:bit_manipulation_functions I use these routines (and my timer pack) ***EXTENSIVELY*** in my code. actually the ones I use are really optimised for speed. I can post that if you want Edited 2025-03-06 05:47 by CaptainBoing |
||||
ville56 Senior Member ![]() Joined: 08/06/2022 Location: AustriaPosts: 216 |
Sure you can either optimize runtime or memory consumption. Variable names are hashed as i understood to speed up the lookup. But it still is an interpreter. 73 de OE1HGA, Gerald |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1139 |
@CaptainBoing So we OR followed by XOR to clear a bit whose state is not known. In other BASICs I can use AND NOT to achieve the same. Doesn't work in MMBasic though. |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3996 |
Unless you're desperate for every byte of memory just (KISS) use one variable per flag. Easy to read, easy to write, easy to maintain, easy to reuse. It'll be much faster than some of the stuff just posted, too, especially in the interrupt routine. John |
||||
ville56 Senior Member ![]() Joined: 08/06/2022 Location: AustriaPosts: 216 |
use INV instead of NOT. e.g. Flag=Flag and inv (1<<b) should work this way .... 73 de OE1HGA, Gerald |
||||
PhenixRising Guru ![]() Joined: 07/11/2023 Location: United KingdomPosts: 1139 |
I don't believe so (away from my PicoMite) If the flag is already zero and I want to set to zero, INV will make it a one. Using OR and XOR works because OR will always set the flag to a one, no matter the existing state. |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3996 |
Looks OK. PRINT HEX$(INV (1<<b)) can be used to check. John |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2414 |
Yes. > a=3 : b=4 : c=0 'a, b = individual flags, c = 64 bit combined flags > c = c or (1<<a) :? bin$(c,64) 'set flag a in c 0000000000000000000000000000000000000000000000000000000000001000 > c = c or (1<<b) :? bin$(c,64) 'set flag b in c 0000000000000000000000000000000000000000000000000000000000011000 > c = c and (inv (1<<a)) :? bin$(c,64) 'reset flag a 0000000000000000000000000000000000000000000000000000000000010000 > c = c and (inv (1<<a)) :? bin$(c,64) 'repeat to check that flag a doesn't invert 0000000000000000000000000000000000000000000000000000000000010000 > But as previously mentioned it saves very little. More could be saved by putting a number of short strings in one string with mid$(). |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4851 |
I do not know your application. But if speed is some form of important, use 64bit integers. The math the ARM must do to execute most commands is peanuts compared to the time it takes the interpreter to decode the basic command. In general: fewer basic commands = higher speed. so a%=pin(gp0) if a% then is so much faster than manipulating bits in a 64 bit integer. Volhout PicomiteVGA PETSCII ROBOTS |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
Agreed. Especially in an interrupt routine where you don't want to hang about. You can do bit twiddling elsewhere, but I wouldn't recommend it in interrupts. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3996 |
Yes, at the cost of a slower interrupt routine. I'd go for an integer flag to keep the interrupt routine short, simple and fast. Saving maybe 7 bytes doesn't seem vital. Using a string has memory overheads, too, so I'd go for bits within an integer if I was absolutely desperate for RAM space (which seems vanishingly unlikely to this extent). John |
||||
Page 1 of 2 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |