X2 program slots

thunderace7

New Member
Hi. Can someone explain X2 program slots to me, please?
In the X2 product briefing it says that there are up to 4 internal slots, each of which can contain around 1000 program lines.
My 40X2 program has around 1200 lines and reports it's syntax check as 3910 bytes of 4048 used. Presumably this means that is all contained within 1 program slot (slot 0?) and there are 3 more I could use?
The product briefing also states that subroutines cannot be shared across slots. Do i, therefore, have to duplicate subroutines in each of the slots where they are to be used? If so, I need to give them different names?
Is it OK to define variables just the once and use them across slots?
If I run them as one large program, do I just put a run 1 command (or run 2, run 3) at the end of each slot program? When it gets to the end of slot 3 will it restart at slot 0 or do I need a run 0 command at the end?
How do I write the programs? Do I write them as individual slot programs and load them separately into each slot? How does PE6 handle this?
I know I have asked a lot of questions and I apologise for it but I really don't understand how it works and don't want to waste three quarters of my 40X2 memory.
Why have they designed it like this? Is there some advantage that I have not seen? It seems to me to be unnecessary complication and nothing that couldn't be achieved with GOTO commands.
Thanks for your patience. I'm impressed that you stuck with it until the end of the message. :)
 

thunderace7

New Member
Sorry, I've thought of another question. Can labels be used across slots? If I put a GOTO main at the end of slot 3 would it GOTO the main: label in slot 0?
Thanks.
 

lbenson

Senior Member
My 40X2 program has around 1200 lines and reports it's syntax check as 3910 bytes of 4048 used. Presumably this means that is all contained within 1 program slot (slot 0?) and there are 3 more I could use?
Right.
Do i, therefore, have to duplicate subroutines in each of the slots where they are to be used? If so, I need to give them different names?
Right again, but no need for different names--slot 1 knoweth not what slot 0 doth (except variables are shared--but not variable names--best to have an "include" file naming things in common and having the common subroutines).
Is it OK to define variables just the once and use them across slots?
Define them once in an include file and include that in each slot.
If I run them as one large program, do I just put a run 1 command (or run 2, run 3) at the end of each slot program? When it gets to the end of slot 3 will it restart at slot 0 or do I need a run 0 command at the end?
No. Using multiple slots can be tricky. Try to separate tasks and include all that's needed for a task within a given slot. I use a code (e.g., slot1Routine) to say what subroutine within a slot needs to be executed:
Code:
 select slot1Routine
  case slot1_displaySlotNo gosub displaySlotNo
  case slot1_printTemplate gosub printTemplate
  case slot1_printData gosub printData
 endselect
run 0
Can labels be used across slots? If I put a GOTO main at the end of slot 3 would it GOTO the main: label in slot 0?
No--GOTOs are only within slots, not between.
Why have they designed it like this?
Hardware constraints on the underlying PICs. Perhaps some heritage issues as well (limited size of jumps in original PICAXEs).
 

inglewoodpete

Senior Member
I wrote a 3-slot program for a 40X2 project a few years ago.

While it is too complex to attach here, I used the following principles:
  • Keep the main loop and most critical subroutines in slot 0. This allows the program to run as efficiently as possible.
  • Develop less-used or bulky subroutines and put them in the alternate slots.
  • Dedicate a couple of variables to pass task IDs back and forth between slots. This allows the entry routines in each slot to quickly pass control to the required subroutine.
  • Utilise upper RAM and/or Scratchpad to store data that is used in multiple slots. You may find that you run out of variables for storing data and/or passing data between slots.
  • You can choose to develop your code in one or multiple files. When I wrote mine the #Include directive was not available so it used conditional compilation using #define and #ifdef, as follows. Code that is duplicated across slots (eg interrupt routine) can be outside the condition flags and consequently be compiled and included in each slot.
  • Downloads are required for each slot. Version logging on entry to each slot is handy to ensure that the code all slots is compatible.
  • You have to be very organised in structuring your program. Design and map out what goes where before rushing into developing multi-slot code. I'm a dinosaur that uses the old technology (pencil and paper) to do this!
Rich (BB code):
'#Define LoadSlot0  'Allow loading of 2 different slots from 1 source file
'
#IfDef LoadSlot0
   #Slot 0         'Slot 0 handles most stuff: administration and end result routines
#Else
   #Slot 1         'Slot 1 handles menu and keypad/infrared command analysis
#EndIf
 
Last edited:

thunderace7

New Member
Thank you both for the replies. I'll have to study them at length before I understand them, especially the bit about include files.
Not today, though. I have a leaky toilet cistern that requires my urgent attention first!
 

Aries

New Member
I have (at least) three multi-slot programs on 28X2s. One is for monitoring electricity consumption and photovoltaic generation, one is for the underfloor heating controller, and the other is (in progress) for the gas-fired heating system.

They are designed in a similar way (much like Inglewoodpete's):
Slot 1 is normally the main program
Slot 2 handles the "user interface" - LCD display and buttons etc
Slot 3 handles comms - mostly I2C to another Picaxe which handles a transceiver
Slot 0 is not always used, except to recognise a cold start. However, the two heating controllers do use it to hold regression calculations on one or two variables. The slots each end up holding about 3700-4000 bytes of the available program space.

b0 and b1 are used for communication between slots, to indicate where the call has come from - b0 holds $F0 for a valid call, so that a cold start can be identified, and b1 holds the code used for the initial branch.

Communication between slots is in this general form - on entry to the slot:
Code:
    if b0 <> $F0 then RunSlot0 ' invalid call, treat as restart

    select case b1
    case 0
        gosub Initialise
        b1 = 0
    case 1
        goto MainLoop
    case 2
        goto PreLoadData
    ...
    else
        goto RunSlot0
    endselect
    
RunSlot2:
    b2 = 2
    goto RunSlotX

RunSlot3:
    b2 = 3
    goto RunSlotX

RunSlot4:                                                                        ' Slot0 to run routines
    b2 = 0

RunSlotX:
    b0 = $F0
    run b2

RunSlot0:
    run 0
When "calling" another slot, set b1 to the branching code and then do run x where x is the slot number. For convenience, the slot number is in b2, and is used as shown above.

The slots are effectively independent programs, which share the same memory (RAM, ROM and scratchpad) and variable areas. Values are not lost when switching between slots. For consistency, it is better to have universal definitions of the variables, which is where an include file is useful.

My programs each have a single file containing all the symbol and #define statements, plus a few other bits, which are then used at the start of each of the four slots ...
Code:
#picaxe 40x2
#no_data
#slot 1
#include "ZController.basinc"

' start of program

main:
 

johnlong

Senior Member
Hi
I run a program across all 4 slots I use 1 varible as an indicator as to which slot has being called and where to return too after diffrent functions have been inacted.
regards john
 

thunderace7

New Member
OK, I'm ready to give it a go.
Do I create the include file with PE6?
Does PE6 refer to the include file when checking syntax of the slot files to avoid undefined variable errors?
Does the include file have to be open in another tab of PE6 in order for it to be seen?
Thanks.
 

cpedw

Senior Member
Do I create the include file with PE6?
You could use any text editor but with PE6 it's simple to get the .basinc extension.
Does PE6 refer to the include file when checking syntax of the slot files to avoid undefined variable errors?
Yes.
Does the include file have to be open in another tab of PE6 in order for it to be seen?
No. For simplicity it should be in the same folder as the program file. It's possible to save it elsewhere but I'd need to check the manual for details.
 

johnlong

Senior Member
Hi
No the M series use Parallel Task an explination is in manual 1 on page 62 under Parallel Task Processing
regards john
 

AllyCat

Senior Member
Hi,
Does M series uses slots too?
Yes, the 14M2, 18M2+ and 20M2 do have two program slots (if using PE6), which includes separate Table Memories. See post #15 HERE (originally posted by hippy). But I've never found the need to use them myself, and in most cases suggest that a better solution is to write your programs more efficiently. :)

EDIT: Actually, hippy updated his Mem-Slot Diagram slightly (for the 20X2) to the following diagram (with nearly all the details explained in the Command Reference RUN slot instruction) :

hippys=MEM-SLOT.jpg

Cheers, Alan.
 
Last edited:

Buzby

Senior Member
Wait a minute. I don't think more efficiency is going to achieve this in one slot:
Well, I like challenge, so I looked at your code. I just downloaded and compiled each slot, #0 and #1.

Slot #0 compiles to 682 bytes, and slot #1 is 767 bytes.

682 + 767 = 1449.

A single slot holds 2048 bytes, so both progs should fit in one slot.

Or have I missed something ?.

Cheers,

Buzby
 

AllyCat

Senior Member
Hi,

I did say "in most cases..." and an obvious exception would be where a program has been "intentionally" designed to fill all the available space. Was there a specific requirement that between 512 (where one slot would be sufficient) and 1024 "bytes" (where 2 slots would be insufficient) needed to be stored? I believe the text also said that it was tested with "random" data (which might be created on-the-fly without any Table memory), but also the vast majority of "bytes" in the tables appear to fit into nibbles, so could be compressed into 512 bytes anyway. And I don't believe the 256 bytes of Data memory (EEPROM) was being used? ;)

Like Buzby, I downloaded the two program files (in my case into PE5) and noted that not only do the two programs look quite similar, but they total less than 2048 bytes. Interestingly, each "program" in PE5 was reported as being much larger, but each 512 "bytes" of Table Data had added about 900 bytes to the "program" size ! A lot of things with PICaxe are not "what you might expect".

So, even for that example, I would argue that the second slot wasn't "essential". In many cases a single slot could provide perfectly adequate performance, or at the other extreme the addition of a single little 8-pin I2C 24LC256 external serial EEPROM, for example, could provide greatly extended capability and convenience at a modest financial cost.

Cheers, Alan.
 

lbenson

Senior Member
A single slot holds 2048 bytes, so both progs should fit in one slot.

Or have I missed something ?.
Code is virtually identical, but both slots use nearly all of the 512 bytes of table available in each slot.

So, even for that example, I would argue that the second slot wasn't "essential". In many cases a single slot could provide perfectly adequate performance, or at the other extreme the addition of a single little 8-pin I2C 24LC256 external serial EEPROM,
True about the external EEPROM, but there's a question of whether that is more efficient.

The projects where I have used multiple slots for code have tended to end up on X2 devices.
 
Top