Improved LOAD instruction (SX/B 2.0)
![JonnyMac](https://forums.parallax.com/uploads/userpics/922/n74EUX0AORWZS.jpg)
[noparse][[/noparse]Edited per suggestion from PV]
One of the improvements in SX/B 2.0 is that the LOAD instruction may now appear at any point in a listing; this makes the use of libraries a little easier. I create two files for each library: library_def.sxb (sub/func declarations) and library_inc.sxb (working code). I keep my library files in a folder on the root of my development drive so that it's easy to get to.
Here's an easy one that is in almost all of my programs: DELAYS -- this has routines called DELAY_MS (replaces PAUSE) and DELAY_US (replaces PAUSEUS). You may pass a byte or word value and neither of these routines require any user variables. Note that these routines are intended for programs that don't use interrupts (I have another library, IDELAYS, for that). Save the library files to a folder called C:\SXB LIBRARY\ and then run the demo.
Oh, the routines are enclosed in $IFUSED-$ENDIF blocks so that only the code you call gets compiled into the program. You can see $IFUSED in action by looking at the List file (Ctrl+L) -- note that the code for DELAY_US produces nothing but an empty shell (the shell is required by the declaration).
Post Edited (JonnyMac) : 1/29/2009 3:13:45 PM GMT
One of the improvements in SX/B 2.0 is that the LOAD instruction may now appear at any point in a listing; this makes the use of libraries a little easier. I create two files for each library: library_def.sxb (sub/func declarations) and library_inc.sxb (working code). I keep my library files in a folder on the root of my development drive so that it's easy to get to.
Here's an easy one that is in almost all of my programs: DELAYS -- this has routines called DELAY_MS (replaces PAUSE) and DELAY_US (replaces PAUSEUS). You may pass a byte or word value and neither of these routines require any user variables. Note that these routines are intended for programs that don't use interrupts (I have another library, IDELAYS, for that). Save the library files to a folder called C:\SXB LIBRARY\ and then run the demo.
Oh, the routines are enclosed in $IFUSED-$ENDIF blocks so that only the code you call gets compiled into the program. You can see $IFUSED in action by looking at the List file (Ctrl+L) -- note that the code for DELAY_US produces nothing but an empty shell (the shell is required by the declaration).
Post Edited (JonnyMac) : 1/29/2009 3:13:45 PM GMT
Comments
http://forums.parallax.com/showthread.php?p=780347
regards peter
You might want to consider keeping the sxb extension,
eg. use filename_def.sxb and filename_lib.sxb
That way when you open the files in the IDE,
the sxb keywords are highlighted.
regards peter
I guess I'd better go update that chapter in my book!
It seems like everyone specifying absolute paths to functions is going to make code samples/demos less portable.
Or barring that, perhaps having a default path for load in the SXB language itself like:
load_path="c:\program files\parrallax\sx\sxb\tsaavik\my_functions\"
the you could just do:
load "my_stupid_function"
load "\jonnymac\DELAYS_DEF.SXB"
Just a thought, most likely a bad one [noparse]:D[/noparse]
I like Your idea on file paths. It seems like I have to dig and dig to find the file (Program)I'm using with the SXB editor to be able to post it on a forum.
I'm still some what new to SXB software, And I'm not complaining about anything.
I have a nice new SX-KEY that works great. Thanks to Mr.Ken Gracey.
But I have found that the SXB software is a little more involved then the Basic Stamp editor. I would like all the SXB programs close or in the SXB files.
This may already be in place. as I have encountered some weird computer problems, And the problem MayBe totally on My end.
___Love-in the SX28____and the SXB editor________________$WMc%___________
Parallax Oscope is on sale for $90.99·· Thats 35% off the regualer price__on sale until 2/02/09_It is part # 28014.·seach for it on the Parallax·Home page.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Truth is out there············································ BoogerWoods, FL. USA
Post Edited ($WMc%) : 1/31/2009 4:44:47 AM GMT
The directive INCLUDE is for including assembly code files.
The directive LOAD is for including sxb code files.
T'Saavik,
How about using SUBST for now.
Suppose you create a library directory named sxblib at some location
%path%\sxblib
Then use
SUBST W: %path%\sxblib
Specify LOAD files as
LOAD "W:\math\Float32.SXB"
The W: accesses folder %path%\sxblib
The %path% could be default
C:\Program Files\Parallax Inc\
You can enter the SUBST command from a dos window or a .bat file
regards peter
Could the compiler read the library path from a file LIBRARY.DIR
in the SXB directory?
So if the file would read
C:\SXB LIB
and a LOAD would specify
LOAD "somedir\myfile.sxb"
the compiler would read file "C:\SXB LIB\somedir\myfile.sxb"
That would let us have a relative path in the LOAD command
without·change to the IDE or the SXB command line interface.
regards peter
Just a hope, Thanks for everything else you do.
Bill
Post Edited (Capt. Quirk) : 2/2/2009 5:58:31 AM GMT
Also, it would seem a good style for distribution of libraries is to edit the app/demo that uses LOAD or INCLUDE to be the filename only (i.e. a relative path to an included lib in the same dir as the SXB program that uses it). This way your "public" distribution can be zipped up along with the demo that uses and downloaded to any location on the user's computer and it will compile.
I also agree with Peter Verkaik that distributed libraries should require the manual insertion of $USES, rather than relying on "blank" subs/funcs and larger jump tables. When a user has an ISR w/o a GOTO Interrupt_Handler or the like, large jump tables plus the ISR in page $00 will lead to lots of out of space errors when libraries with many functions/subs are loaded into the same app.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
That only works while your project file is in the original location.
Move your project to another drive or subdirectory level and it won't find the libraries.
So a known but settable library root folder is desirable.
@Capt. Quirk,
That should be the goal. In my opinion you must be able to load·a library
and use it, without the need to edit the library. Attached is a first attempt
to implement dynamic Virtual Peripherals. Dynamic in the sense that VP's
occupy a ram bank and that VP's can be started and stopped. Once stopped,
its rambank is freed and can be used by another VP.
Note that this was written months ago so there are no '{$ifused subname} blocks yet.
VP's are declared using DATA tables. So you can declare more VP's than you can
run simultaneously. In that they are much like TASKS.
Unzip the attachement in a folder and open vpTemplate.sxb
It should compile without error.
@anybody,
I'd like to discuss library development so we can come up with a template framework
for libraries.
Some things are already clear:
Code must be enclosed in '{ifused subname} blocks.
Interrupt code, if possible, should be pure assembly, encoded in a macro (see attachement).
That way it can be easily·inserted in the INTERRUPT routine.
· INTERRUPT
· \myMacro
· RETURNINT
A library consist of a definition file libname_DEF.SXB and a code file libname_INC.SXB
(I used Jonnymacs filenaming as it just as good as the _h and _lib I used in the attachement).
The DEF file should contain all CON's, VAR's and IOPIN's used by the library with the exception
of those that needs to be·set by the application program. The DEF should state clearly what
needs to be declared/defined externally before loading the library.
The INC should contain all subs, funcs, tasks enclosed in·$ifused blocks.
The DEF should contain all declarations for subs, funcs and tasks, also enclosed in·$ifused blocks.
The DEF should contain a list of public subs,·vars and tasks (eg. those the application
may call directly) before the sub/func/task declarations, but commented out.
This list is to copied to the application program that uses the library.
That way one just needs to uncomment an entry in the application program if that entry is used.
For example, a list in the DEF could be
''{uses mySub1}
''{uses mySub2}
''{uses mySub3}
''{uses mySub4}
(Note the two single quotes at the start.
Once copied·to the application program it is easy to enable·subs by just uncommenting
the used subs.
To enhance readability I request that $uses accepts a comma seperated list. In DEF
'{$uses libname: -mySub1,-mySub2,-mySub3,-mySub4}
Note that $uses is not commented out, rather the - prefixed to the subname specifies
the sub as not used.
Once copied to the application program, just remove the - to enable a sub.
The libname: is just comment but shows to what library the subs belong.
The DEF should contain a $define libname which is to be used to load the accompanied INC file.
'{$ifdef libname}
load "libname_INC.SXB"
'{$endif}
For documentation purposes,·javadoc info blocks can be inserted in the DEF file.
The free utility DOXYGEN can extract those blocks and convert it to html or pdf.
At start of DEF file:
'{$ifdef doxygen}
'{$undefine doxygen}
to make sure doxygen is undefined.
Per sub/func a block like
'{$ifdef doxygen}
/**
·* \brief Sub/func description
·*
·* @param x Description of x
·* @param y Description of y
·* @return Return value
·*/
·word myFunc(byte x, word y) {}
'{$endif}
which is complete skipped by sxb but extracted by the doxygen program.
That summarizes what I think is required to make libaries re-usable.
Please comment.
regards peter
They are all derived from the template program file that we currently use.
Notice in DEF how I turn subs into private subs: I leave out private subs
in the list that must be copied to the application. I then use '{$uses privateSub}
at the SUB declaration that uses that private sub.
I think these templates have everything·in place
but suggestions for·improvements·are welcome.
regards peter
First, that the nested DEFs and such may be too much for some users -- tracing the threads is not quite as simple. I would prefer simple IFUSED/USES, and perhaps break out ISR code separately (though formally your trick is really good for convenience if the library is set up properly). I think a balance between the utter simplicity Jon prefers and the formally coherent you produce would be ideal. I really like the list of ready to cut/paste USES statements, and the overall organization. Not sure how I feel about variable declarations in the lib, however. Need to mull over that.
Second, I'm not sure adherence to doxygen documentation formatting will happen with any regularity. I also would encourage easier to read comments/instructions as comment lines in the doc itself. I know that the doxygen ready formatting is something you encourage because you also are posting classes and such for the Javalin Stamp, and I'm guessing that for your purposes it is essential to extract this info since you must answer 1000s of questions, but it might be a bit much for other users; and in the case of submitted libraries, I wouldn't want folks to be discouraged from inserting copious commentary because the formatting could be troublesome for some. E.G., when someone posts a Kalman IMU lib, any documentation would be awesome.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Not sure what you mean by nested DEF. If you refer to
'file vpCore_h.sxb
'{$IFNDEF __vpCore__}
'{$DEFINE __vpCore__}
and simular as found in the vpLibrary.zip, I already have abanded the $ifndef
because there is no need for it as sxb does not allow seperate compilation.
It also dates from months ago. The templates I posted are the most recent
and these do not have the $ifndef line.
If you referred to something else·please specify.
The vpLibrary was a first attempt to see if it was possible to create dynamic VP loading
without too much hassle in·the application file. The DATA used to specify the VP's
is quite a nice way to handle it. I am not quite happy about the total result as it
already uses half the sx48 memory, mainly because most·subroutines are written
in sxb. Much room for improvement there, perhaps a static design saves alot of
codesize. But whatever design, the library should hide all details and the
application file should just be able to call some subs that deal with the VP's.
If you are concerned about the complexity of the vpLibrary design, especially the
interrupt part, that should·be of no concern if·the library is well written.
After all, I don't think anybody cares about the complexity·of generated TASKS code,
(there are 3 parts involved there, scattered around) as long as it works.
It is always possible to do all variable allocation in the application program file.
I see the benefits of that approach. In that case the DEF file must clearly specify
in its documentation the variable names and variable sizes it needs defined.
We can put in those declarations as comments in the DEF that just needs to be copied
to the application file and uncommented. This also allows to organize memory
exactly as you want it.
The whole doxygen item is optional. After all, to sxb·it·is just comment.
But you are right that I have dozens of javelin classes, some of which
I·will convert to sxb. These classes are heavily documented with javadocs
so why not integrate these as comments, but·it is not mandatory.
I just mentioned it to show it is easily done.
regards peter
'{$define __libTemplate__}
Which is then used further in the APP file to decide whether or not to include the lib_inc further down the app. This is the part I think is confusing for the casual user... I would rather the same list of $USES be used in both def and inc, and just load them. Otherwise the user has to p/u both the commented out list of USES and any custom DEFINEs that could be required to load subsequent parts of the library. Since the IFUSED are present in both def and inc, I don't see the value (outside of speeding up compilation by not loading a file that is unecessary) in having the def define items for including further down in the APP. It's one thing if the lib def or inc itself defines items for includes within itself (say a high-level lib that requires a math lib).
Below is my tiny edit.....
Now, thinking out loud, here's a case. I have a math lib that does signed word mult, div, mid-mult, with accurate 16-bit rounding. I use it everywhere. So what if I accidentally include it (via USES/USED) in both an app AND it's linked to from within some other higher-level library? My thought would be to have the lib and def internally track this, like so:
This would prevent the possible insertion of the same code even if the library is loaded more than once. I'm just not at my micro machine right now to test if you can enclose ifused as above.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
You forget about any DATA that may reside in the INC file.
To leave those out the entire INC file must not load.
Secondly, I think we agree that we can not have circular use of libraries.
So if a library x uses subs from library y than library y cannot use subs from library x.
This means if library x uses library y then library y must be loaded prior to library x
(for the DEF files that is, the order of loading INC files is irrelevant), because library x
(the DEF) may use some constants defined in library y.
The library name $define therefore also allows some checking.
If library x uses library y then library x (the DEF) should have a line
'{$ifndef __liby__}
'{$error Library y must be loaded prior to library x}
'{$endif}
There is no problem with multiple identical $uses as long as there is only 1 instance
of the sub. More instances would generate a compiler error.
regards peter
···· Doesn't work unfortunately as it's clean. But you can nest IFDEF within IFUSED (just not the other way around).
Sort of like what you did, but in this case each loaded flag is local to the routine itself, which I think makes for easy reading, and also easy nuking, moving around. The attached math libraries I can load TWICE and they only compile once. This means that multiple libraries that use the same libraries (which could be common if every body starts using a basic serial, math, lcd, etc. library linked in their own higher level library, e.g. motor control w/real time ramping). This covers for only compiling data once as well, or whatever the author deems necessary, and the flags are all right with the code itself. I dunno :-)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
What we can do is moving the
'{$ifdef __libTemplate__} and '{$ifend} that surround the load "libTemplate_INC.SXB"
into the file libTemplate_INC.SXB
In the application file we can then just use
load "libTemplate_INC.SXB"
So if one loads a DEF then one must also load the INC.
Loading·the INC when the DEF is not loaded is no problem
because then __libTemplate__ is not defined.
regards peter
You can use $ifused within $ifdef.
For the attached updated templates I have moved the
'{$ifdef·__libTemplate__}
into the INC file itself.
So that file has $ifused within $ifdef, and it compiles ok.
I have been on that route for multiple loading of libraries.
The vpLibrary.zip I wrote months ago did the same thing.
The reason I abondoned it is because sxb has no linker.
So it is easiest to just load the libraries in·the application
file.·If the order of loading is·incorrect, the·library
that misses a required library can show that by means
of an error·message as explained in my previous post.
However, if·a library requires another library it should
be specified, so the user can load the required library
prior to loading·the library itself.
regards peter
Only singly, not multiples -- I wanted to prevent entire swaths of the lib that contained multiple ifused/endif blocks from compiling. Wait I take that back -- IFNDEF did NOT work when I used it just like you used IFDEF in your posted example. I need to check that again to be sure, however.
Second, the one thing I don't see here is prevention of duplicate compiling if a lib is loaded twice. And I see no reason why libs themselves can't load other libs (e.g. a motor control lib loading a math lib -- the end user only needs to load motor_lib). Obviously, the author would need to provide the libs, but I think a good style should a) allow for the fewest load statements in the main application, b) using multiple libs without the hassle of checking to see if other used libs will load the same utilities and throw an error. See my attached SXB files from earlier. They can all be loaded multiple times w/o double compilation.
Whew. Nuff' said for now -- gotta get back to a project on the bench
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I have enclosed the DEF and INC files in $ifndef blocks.
So a library DEF or INC will only compile once.
In the example, mySub2 now calls a mySub5 that is located in library libTemplate2.
The $ifused mySub2 block in libTemplate_DEF
'{$ifused mySub2}
'{$uses mySub3}
'{$uses mySub5}
load "libTemplate2_DEF.SXB"
mySub2 sub 1
'{$endif}
now loads the libTemplate2_DEF.
The libTemplate_INC has
'{$ifused mySub2}
load "libTemplate2_INC.SXB"
sub mySub2
· mySub3 2
· mySub5 1
endsub
'{$endif}
which loads the libTemplate2_INC when required.
The application file merely loads the libTemplate, no reference to libTemplate2
is visible in the application file.
The only problem is that you must know all used subs from libTemplate2 at the
moment libTemplate2 is compiled. If another library also uses libTemplate2
but only uses one·sub from it, the remaining subs cannot be compiled.
The solution is either declare all used subs in· the application file
(at· least it is all grouped then, just as you want all VAR declarations grouped),
or use a $define·per sub (as you did in your example), which is not very appealing to me
but workable.
I'd like more comments, arguments, what the best strategy is here.
From a maintaining viewpoint, having grouped all LOAD commands
might be best.
Edit:
Just realized, having LOAD commands where required, also means these appear
in the list view. So·if a library is loaded more than once it appears as many times
as comments in the list view. Having grouped all LOAD commands keeps the list view clear
and also·gives an overview of what subs are used by an application.
I don't know about others, but I frequently·use the list view to check generated
code. A·clean list view is important I think.
Having said that, a construct like
'{$ifdef __libTemplate__}
load "libTemplate_INC.SXB"
'{$endif}
in the application file prevents libTemplate_INC to show at all at the list view if
its DEF is not loaded. Moving the $ifdef into the INC file results in the INC showing
up as comments when not loaded.
regards peter
Post Edited (Peter Verkaik) : 2/3/2009 9:57:38 AM GMT
I was actually just looking at output where everything not compiled is commented. Bean, is it possible to change that so that material that is not compiled is just stripped?
Second, while my example works under some circumstances, in further tests last night, it would seem that when IFUSED encloses IFDEF, the results of the IFDEF will trump any result of the parsing the IFUSED, even if the result of the IFUSED is negative.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I don't know if that is wise, but if Bean adds this it should be optional (compile full, compile stripped)
but it probably means changing the IDE also.
Do you have an example of that as it would indicate a bug in conditional compiling.
Although it is clear it is possible to write libraries such that they can load in any order,
I am not sure it is the best way. Just to save on a few load commands in the application
file, the libraries become more complex with conditional statements and we get a list view
where library subroutines may be scattered around depending on which library gets to compile
the subroutine first, plus the list view will hold multiple loaded libraries as comments.
For me it is clear that grouping the load commands in the application·file is preferable.
You already must state·in the library which variables to declare, so·you can just as well
state what other libraries must be·loaded for your library to work.
regards peter
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php