This Armpit Scheme snapshot, like the previous one, allows the user to store code and data in a library (or libraries) stored in FLASH. The current implementation is however more flexible (and less managed) than that of the previous snapshot. Also, as with the previous snapshot, FLASH libraries are available only on MCUs with executable FLASH space which is where they are stored. The idea is that code within a FLASH library can be executed in place without transfer to RAM and therefore without reducing heap size. This increases performance of the system by allowing more heap space for truly dynamic code and data, entered interactively, or loaded from FLASH files.
In this snapshot, objects are added to library flash using the unpack function with a negative integer as second input argument (cf. ChangeLog), for example:
(unpack (pack "hello") -1)
Objects are stored from the top of executable FLASH, down towards file FLASH space on MCU boards where files and library share a common FLASH space, or towards the ARMpit Scheme binary on boards with non-shared FLASH space (eg. LPC-H2214, LPC-H2294). The function flib (a contraction of flash library) returns the latest object stored in the FLASH library space (it returns its address, not a copy of the object), for example:
(unpack (pack "hello") -1)
(flib) ; -> "hello"
(unpack (pack "bye") -1)
(flib) ; -> "bye"
It is notable in this example that while both "hello" and "bye" are stored in library FLASH space, only "bye" is readily accessible (the read function may however still be used to access "hello", possibly by scanning library FLASH backwards starting with the last page). Thus, to manage the library FLASH space as a library, the user may need to explicitly establish linkages between the objects installed in the library space.
(unpack (pack (list "hello again!" (flib))) -1)
(flib) ; -> ("hello again!" "bye")
The library flash space is erased using the erase function with a negative input argument (cf. ChangeLog), for example:
(erase -1)
(flib) ; -> ()
A simple library system can be built using this functionality and the built-in-environment function, _BIE, available in this snapshot. The idea is essentially to write library functions to library flash, bind them to appropriate symbols in an environment-vector, write that environment-vector to library flash, and upload it in the built-in-environment at a pre-selected index. This approach turns library symbols into built-in symbols which reduces RAM use for the object array (obarray) but does mean that consistency management is in the library designer's (and user's) hands.
A series of functions that has been designed to help with this simple approach to library management is provided here. The soften function brings the built-in-environment's spine to the heap so that it can be modified dynamically, and ensures that this vector is long enough to add bindings for a new library at a specified index location (indices 0 to 4 are used by the system, 5 to 126 are available). The intern function is used to place a new binding in the library under development. The harden function writes the library's environment vector to library FLASH after linking it to another object (typically the prior contents of library flash). The import function is used to load a library's environment vector into the built-in environment (eg. after resetting the MCU).
Using this code, it is a simple matter to add flash libraries to a running system. For example, to define a flash library named "test 0" that stores a single binding, between the symbol x1 (specified as a string during library building) and the value 100, one may use the sequence of commands:
(define old-lib (flib)) ; save a reference to the current flash library
(define new-lib (list "test 0" 10)) ; specify new library name and index in built-in env
(soften new-lib) ; make built-in-environment modifiable
(intern new-lib "x1" 100) ; and symbol x1 bound to 100 in new library
(harden new-lib) ; write new library environment to lib flash and connect to old lib
(flib) ; check
; reset the MCU
; load or paste-in the import function
(import "test 0") ; load library into built-in environment
x1 ; -> 100
Additional examples include:
(map import (map car (flib)))
This simple set of examples has no truly automatic enforcement of consistency and dependencies. Well, except that it will not allow a symbol defined in an exisiting (built-in or imported) library to be redefined in a new library. For example, the function 'list cannot be redefined in a library. It can be used as a variable in an expression within a library and it can be redefined in user space, but the simple library management functions will not allow a new binding for it in a new library. Additional flexibility relating to this behavior, along with dependency specifications and other aspects of library management should be straightforward to implement, in enhanced versions of the library management functions, in view of the flexibility of the flash library system in this snapshot. The list of library name and index (eg. (list "test 0" 10)) could for this purpose be extended to include a list of dependencies and a list of initialization functions for the new library.
As a last example, we consider adding a compiled function to a flash library. We compile the factorial function on-chip or off-chip using:
(escompile
(define fact
(lambda (n)
(if (< n 1)
1
(* n (fact (- n 1)))))))
we extract the result and then write it to a flash library named "factorial" which will be attached to the built-in environment at index 15. The process requires the library management, utilities, bytevector and linker libraries defined above. Assuming an ARM target (fact compiled for ARM rather than Thumb 2):
(define old-lib (flib))
(define new-lib (list "factorial" 15))
(soften new-lib)
(intern
new-lib "fact"
(unpack
(link
'#(#vu8(223 0 0 0
127 0 0 235 0 16 138 229 212 65 159 229 12 192 160 225 8 80 143 226 15 16 160 225 123 0 0 234
103 0 0 234 119 0 0 235 0 16 138 229 117 0 0 235 0 144 138 229 184 65 159 229 12 192 160 225
15 16 160 225 116 0 0 234 111 0 0 235 0 64 138 229 15 80 160 227 5 64 160 227 113 0 0 235
48 0 162 232 8 80 66 226 2 0 130 227 140 65 159 229 12 192 160 225 15 16 160 225 104 0 0 234
105 0 0 235 48 0 162 232 8 80 66 226 2 0 130 227 16 4 154 232 15 16 160 225 101 0 0 234
0 6 154 232 2 4 154 232 47 0 52 227 1 0 0 10 5 64 160 227 1 240 160 225 86 0 0 235 0 16 138 229
68 65 159 229 12 192 160 225 15 16 160 225 85 0 0 234 80 0 0 235 0 64 138 229 15 80 160 227
77 0 0 235 0 144 138 229 75 0 0 235 0 80 138 229 28 65 159 229 12 192 160 225 15 16 160 225
74 0 0 234 69 0 0 235 0 64 138 229 67 0 0 235 0 144 138 229 0 65 159 229 12 192 160 225
15 16 160 225 66 0 0 234 61 0 0 235 0 64 138 229 15 80 160 227 5 64 160 227 63 0 0 235
48 0 162 232 8 80 66 226 2 0 130 227 196 64 159 229 12 192 160 225 15 16 160 225 54 0 0 234
55 0 0 235 48 0 162 232 8 80 66 226 2 0 130 227 16 4 154 232 15 16 160 225 51 0 0 234
0 6 154 232 47 0 0 235 15 192 160 227 16 16 162 232 8 80 66 226 2 0 130 227 16 4 154 232
15 16 160 225 42 0 0 234 32 4 154 232 38 0 0 235 48 0 162 232 8 80 66 226 2 0 130 227
0 144 154 229 92 64 159 229 12 192 160 225 15 16 160 225 28 0 0 234 29 0 0 235 48 0 162 232
8 80 66 226 2 0 130 227 0 6 154 232 16 4 154 232 2 4 154 232 24 0 0 234 4 112 160 225
48 64 159 229 12 192 160 225 15 16 160 225 21 0 0 234 4 112 133 229 63 64 160 227 2 4 154 232
1 240 160 225 236 1 0 0 175 1 128 0 15 0 0 0 175 2 128 0 175 1 128 0 175 3 128 0 175 4 128 0
175 5 128 0 4 240 31 229 0 0 0 0 4 240 31 229 0 0 0 0 4 240 31 229 0 0 0 0 4 240 31 229
0 0 0 0 4 240 31 229 0 0 0 0 4 240 31 229 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
((516 . 32773) (512 . 32772) (508 . 32771) (504 . 32769) (500 . 32770) (492 . 32769))
((32769 . "n") (32770 . "<") (32771 . "*") (32772 . "fact") (32773 . "-"))
((564 . "_dfv") (556 . "_apl") (548 . "_cns") (540 . "_lkp") (532 . "_mkc") (524 . "_sav")))
new-lib)
-1))
(harden new-lib old-lib)
Alternatively, for a Thumb2 target (fact compiled for Thumb 2):
(define old-lib (flib))
(define new-lib (list "factorial" 15))
(soften new-lib)
(intern
new-lib "fact"
(unpack
(link
'#(#vu8(223 0 0 0
0 240 20 249 202 248 0 16 223 248 0 66 79 234 12 12 79 234 12 12 15 242 12 5 15 241 4 1
0 240 10 185 0 240 224 184 0 240 2 249 202 248 0 16 0 240 254 248 202 248 0 144 223 248 224 65
79 234 12 12 79 234 12 12 15 241 4 1 0 240 250 184 0 240 240 248 202 248 0 64 79 240 15 5
79 240 5 4 0 240 244 248 162 232 48 0 162 241 8 5 66 240 2 0 223 248 176 65 79 234 12 12
79 234 12 12 15 241 4 1 0 240 224 184 0 240 226 248 162 232 48 0 162 241 8 5 66 240 2 0
154 232 16 4 15 241 4 1 0 240 218 184 154 232 0 6 154 232 2 4 148 240 47 15 0 191 8 191
0 240 4 184 79 240 5 4 143 70 0 191 0 240 186 248 202 248 0 16 223 248 96 65 79 234 12 12
79 234 12 12 15 241 4 1 0 240 182 184 0 240 172 248 202 248 0 64 79 240 15 5 0 240 166 248
202 248 0 144 0 240 162 248 202 248 0 80 223 248 52 65 79 234 12 12 79 234 12 12 15 241 4 1
0 240 158 184 0 240 148 248 202 248 0 64 0 240 144 248 202 248 0 144 223 248 20 65
79 234 12 12 79 234 12 12 15 241 4 1 0 240 140 184 0 240 130 248 202 248 0 64 79 240 15 5
79 240 5 4 0 240 134 248 162 232 48 0 162 241 8 5 66 240 2 0 223 248 212 64 79 234 12 12
79 234 12 12 15 241 4 1 0 240 114 184 0 240 116 248 162 232 48 0 162 241 8 5 66 240 2 0
154 232 16 4 15 241 4 1 0 240 108 184 154 232 0 6 0 240 100 248 79 240 15 12 162 232 16 16
162 241 8 5 66 240 2 0 154 232 16 4 15 241 4 1 0 240 90 184 154 232 32 4 0 240 82 248
162 232 48 0 162 241 8 5 66 240 2 0 218 248 0 144 223 248 104 64 79 234 12 12 79 234 12 12
15 241 4 1 0 240 60 184 0 240 62 248 162 232 48 0 162 241 8 5 66 240 2 0 154 232 0 6
154 232 16 4 154 232 2 4 0 240 52 184 79 234 4 7 223 248 56 64 79 234 12 12 79 234 12 12
15 241 4 1 0 240 44 184 197 248 4 112 79 240 63 4 154 232 2 4 143 70 0 191 20 2 0 0
175 1 128 0 15 0 0 0 175 2 128 0 175 1 128 0 175 3 128 0 175 4 128 0 175 5 128 0 0 74 151 70
0 0 0 0 0 74 151 70 0 0 0 0 0 74 151 70 0 0 0 0 0 74 151 70 0 0 0 0 0 74 151 70 0 0 0 0
0 74 151 70 0 0 0 0 0 0 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
((556 . 32773) (552 . 32772) (548 . 32771) (544 . 32769) (540 . 32770) (532 . 32769))
((32769 . "n") (32770 . "<") (32771 . "*") (32772 . "fact") (32773 . "-"))
((604 . "_dfv") (596 . "_apl") (588 . "_cns") (580 . "_lkp") (572 . "_mkc") (564 . "_sav")))
new-lib)
-1))
(harden new-lib old-lib)