Catalina release 4.1 is a full release. You can install this over an existing version of Catalina, but it is recommended that you instead uninstall any previous Catalina release before installing, or install this release to a different location. If you are installing under Linux, you should execute the following command to set your permissions correctly after installing (this command is a script in the Catalina bin directory, and may itself need to have its permissions manually set to allow execution): Set_Linux_Permissions The following changes have been made since the previous release of Catalina. If you have not used a previous release of Catalina, you can ignore the following list: RELEASE 4.1 1. Added Multi-Memory Model (MMM) support. See the separate section below. 2. Fixed a bug in the Makefiles for compiling the XMM LARGE libraries. Some library functions were being compiled as XMM SMALL, not XMM LARGE. 3. Added a new option (-B) to the spinc utility, for producing blobs from a Catalina C binary file. This option accepts a parameter to specify the object, but for Catalina Propeller 1 programs this is generally the second object, so it is normally specified as -B2. The existing command-line options -c, -f, -s, -l and -n are also supported for blobs, and the -c option would normally be specified to generate a callable function that can be used to execute the blob as a C program. The -s option can be used to specify the runtime space (stack and heap) required. If not specified, then 80 bytes (20 longs) is used, which is sufficient for small programs. The output is usually redirected to a header file, which is suitable for inclusion in another program. For example: spinc hello_world.binary -B2 > hello_blob.inc spinc hello_world.binary -B2 -c -s 1024 > hello_blob.inc 4. Fixed a bug in catalina that meant the -M memory size option (previously used mainly when compiling EEPROM programs, but now also useful when generating blobs) was not being specified correctly. This could result in the compilation failing. 5. Modified the Catalina -M, -P and -R options to accept hex values as well as decimals. A hex value must be preceded by $ or 0x - e.g. $ABCD or 0xFFFF. Note that these options also accepted modifiers - i.e. m or k (or M or K) when using decimal values, but these are not supported for hexadecimal values. Examples of acceptable parameter values are: -M 16k (or -M16k) -M 16384 (or -M16384) -M 0x2000 (or -M0x2000) -M $2000 (or -M$2000) -P 1m (or -P1m) -P 1048576 (or -P1048576) -P 0x1000 (or -P0x1000) -P $1000 (or -P$1000) -R 8K (or -R8K) -R 8192 (or -R8192) -R 0X3000 (or -R0X3000) -R $3000 (or -R$3000) This can be useful when generating blobs that must execute at a specific nominated Hub RAM location. Generating a blob is done just by specifying the address of the read-only (code and initialized data segments) to a specific value (i.e. using the -R option). The read-write segments will follow immediately, and so the -P option does not usually need to be used. For example, to generate a version of hello_world that executes at Hub RAM location 6000 (hex): catalina -R 0x6000 -lci hello_world.c Note that it is the users responsibility to ensure that there is sufficient space for the program code and data, and that this does not overlap with the reserved areas in the upper Hub RAM. The amount of reserved space varies depending on the memory model, plugins and loader options used, so it is recommended that the program itself determine (and check!) this location at run-tine. Examples of how to do this are provided (see the directory demos\multimodel). 6. Added _cogstart_C (and _cogstart_C_cog) to the P1 libraries, which are compatible with the same functions on the P2 (previously the P1 had only _coginit_C, but the P2 had both _coginit_C and _cogstart_C). The main difference between _coginit_C and _cogstart_C is that the latter accepts a parameter, which is passed to the function being started. For backward compatibility, _coginint_C (and also _coginit_C_cog) can still be used if no parameter is required, and _cogstart_C (and also _cogstart_C_cog) can be used where a parameter is required. 7. Added new functions for starting secondary programs from within a primary program (see the section on Multi-Model support later in this document): On the Propeller 1 and Propeller 2: _cogstart_CMM() - start a blob as a CMM program on any available cog _cogstart_CMM_cog() - start a blob as a CMM program on a specific cog _cogstart_LMM() - start a blob as an LMM program on any available cog _cogstart_LMM_cog() - start a blob as an LMM program on a specific cog On the Propeller 2 only: _cogstart_NMM() - start a blob as an NMM program on any available cog _cogstart_NMM_cog() - start a blob as an NMM program on a specific cog However, note that these functions do not generally need to be called directly - when generating a blob that represents a dynamically loadable program, the spinc utility can also generate a function to start this program, which knows all the necessary program details. 8. Modified the LMM and CMM dynamic kernels to initialize R2, assuming this value is passed in. This allows _cogstart_C (and _cogstart_C_cog) to be implemented on the P1 the same way it is implemented on the P2, and also allows _cogstart_CMM and _cogstart_LMM to accept the address of the shared variable. 9. Allow the -M option to be passed to the assembler when compiling CMM or LMM programs (previously, it was only supported for EMM, SMM, XMM etc). The reason this was not previously allowed is that it is not possible for CMM or LMM programs to be larger than 32k. However, when compiling such programs for dynamic loading, it can occur that the program code is to be located in upper Hub RAM, in an area that pushes other things normally included after the program code (such as the kernel) over the 32k limit. So now this option is permitted. But it should only be used for LMM or CMM programs when they are being compiled for dynamic loading via the Multi-Memory Model support (see below). Also, there is no reason to ever use a value other than 64k for such purposes. 10. Added a new symbol for the Parallax FLiP Module. The FLiP Module has no special configuration options, but in case a user chooses to modify the Custom platform, when compiling programs for the FLiP Module the symbol FLIP can now be specified on the Catalina command line. For example: catalina hello_world.c -lci -C FLIP Note that the symbol used is FLIP, not FLiP! By convention, all Catalina symbols are all upper-case. 11. Fixed a minor bug in the dynamic CMM kernel, which was not registering itself properly on startup. 12. Fixed a problem with spinc on Linux that may have led to a segmentation fault when used on some binaries. 13. Removed a limitation in the Compact code generator that prevented program sizes larger than 256k or executing at memory locations above 0x3FFFF. 14. The -v33 flag to p2asm was not being specified in the file Makefile.inc in the source\lib directory. This may have prevented some multithreading functions from compiling correctly for the P2 RevB silicon. Note that this flag will have to be removed again from both this file, and also from the files p2_asm (Linux) and p2_asm.bat (Windows) in the bin directory to rebuild Catalina for the P2 RevA silicon. Out of the box, Catalina now only supports the Propeller 2 RevB (or later) silicon. 15. Some of the multithreading demo programs were not calling the function _thread_set_lock() before using other thread functions. This worked ok on the Propeller 2 RevA silicon, but will not work on the RevB silicon. Various demo programs have been updated. 16. Modified the various serial libraries to store their lock in the registry instead of in a local variable. This is necessary to support the new Multi-Memory Model, otherwise different kernels executing under different memory models would have used different locks, making the lock pointless. There should be no visible difference in the program behaviour. 17. Reduced the number of threads in some of the demo programs when compiled for the Propeller 1 - some combinations of HMI drivers on some platforms occupy more memory than others, which meant the demos (which intentionally push the limits) may have failed to work correctly on some platforms with some HMI options. 18. Fixed a bug in the compact Catalina Optimizer that may have led to some symbols being removed from the source even though they were used - this would have led to 'undefined' symbols being reported when the source was compiled. 19. Added a Code::Blocks workspace to demonstrate building a multi-model program (Windows only) using Code::Blocks. 20. Fixed a potential problem with the Catalina Optimizer, which may have led to relative jumps being used when the target of the jump ended up out of range due to other optimizations. Multi-Memory Model (MMM) support. ================================= MMM is new for Catalina 4.1. It allows the Propeller to simultaneously execute LMM, CMM and NMM or XMM Catalina programs. Each program is executed on a separate cog and essentially runs independently. However, all programs share the same registry and all programs can use any of the loaded plugins. There is only one program binary, which contains all the programs. When this binary is loaded and started, it starts the "primary" program, which must explicitly start each of the "secondary" programs, which are stored either in the memory space of the primary program (useful if you have XMM RAM) or on SD Card (useful if you do not have XMM RAM), and only loaded into Hub RAM when they are to be executed. For this reason, on the Propeller 1, MMM is generally most useful when the primary program is an XMM (SMALL or LARGE) program, otherwise it is wasteful of precious Hub RAM. On the Propeller 2, the best option is to store the secondary programs on the SD Card. In either case, the secondary programs will then use no precious Hub RAM until executed by the primary program. Each secondary program can share a variable with the primary program - this variable can either be a simple variable or a structure, if a single variable is not sufficient. Each secondary program can use a different variable, or they can all share the same variable. The compilation process for MMM requires that each secondary program be compiled first, as either a TINY (LMM), COMPACT (CMM) or (on the Propeller 2) a NATIVE (NMM) program, with all the usual command-line options, plus the following additional options: -R XXXXXX -C NO_ARGS -M64k A binary file must be generated for each secondary program. However, this binary is not executed directly - it must be processed for inclusion either as an array in the primary program or as an overlay file that can be loaded off SD Card by the primary program. This is done using an updated version of the 'spinc' utility. The XXXXXX value represents the address at which the secondary program is to be loaded for execution, and must be determined according to the size of each secondary program, its run-time space requirements, and also by the necessity to not interfere with the reserved memory at the top of Hub RAM - i.e. the registry, cache, plugin data etc. This value may have to be established partly by trial and error, but it can also be done by simply reserving a suitable amount of Hub RAM as a local variable in the main function of the primary program, determining where the Hub RAM address of that local variable is, and then using that value for the -R parameter. An example of doing this is provided in the Multi-Memory Model demo programs. The -C NO_ARGS is required to disable the usual C command-line argument processing in the secondary program (but not the primary program). Command-line arguments are not supported for secondary programs that are to be dynamically loaded, and it would also interfere with the passing of the parameter that specifies the shared variable address from the primary program to the secondary program. On the Propeller 1, the -M64k option may be required to allow CMM or LMM code to be compiled in areas of upper Hub RAM that would not normally be permitted for primary program code, but are permitted for secondary programs. Without this option, specifying a -R option in high Hub RAM can make the secondary program's binary size exceed the usual 32k limit - which is not normally supported for LMM or CMM programs on the Propeller 1, but is for secondary programs that are to be dynamically loaded. There is no problem in simply always including this option when compiling programs intended to be dynamically loaded on the Propeller 1. The -M option is not required on the Propeller 2. To run MULTIPLE subsidiaries simultaneously you must calculate a different value of XXXXXX for each secondary, and ensure they will not overlap when loaded. The runtime size of each secondary can be determined as described below. Each secondary program must be compiled and then turned into a "blob" (i.e. a "binary large object", or "binary loadable object") for inclusion in the primary program. The blob can be an array in the include file generated by spinc, or as a separate binary file. Producing an array blob: ======================== Building a blob as an array in an include file on the Propeller 1 is done using an updated version of the "spinc" utility, using a new command-line option (-B). For example: spinc -B2 -c secondary_1.binary >blob_1.inc spinc -B2 -c secondary_2.binary >blob_2.inc (etc) The new option (-B) specifies that a blob is to be created from one of the objects in the binary. It accepts a parameter to specify the object number, which (for Catalina Propeller 1 binaries) should generally be the SECOND object within the binary. For Catalina binaries the second object will be Catalina.spin - i.e. the object produced by the Catalina compiler from the C source code. So this option should (currently) always be specified as -B2. Building a blob on the Propeller 2 is also done using the "spinc" utility, but using an additional -p2 command-line option to specify that the binary file being processed is a Propeller 2 binary (i.e. -p2 -B2). For example: spinc -p2 -B2 -c secondary_1.bin >blob_1.inc spinc -p2 -B2 -c secondary_2.bin >blob_2.inc The parameter to the -B option is not currently used on the Propeller 2, but it is recommended it always be specified as 2. The -c option specifies that a suitable 'start' function will be generated in the include file, suitable for starting the C program from the primary program. The name used for the function will be the name of the binary (i.e. "start_<>"). This can be overridden using the -n option if required (for instance, if you are generating multiple loadable programs from the same secondary binary). So, for example, if your binary file name is hello_world.binary, the start program generated would be: int start_hello_world(void* var_addr, int cog) This function accepts the address of a shared variable and a cog number on which the secondary program will be run (which can be the special constant ANY_COG). The function will return the actual cog number used, which can be used later to stop the secondary program. If the object cannot be found or does not have the correct type (it must be an LMM or CMM object on the Propeller 1, or an LMM, CMM or NMM object on the Propeller 2) then an error message will be issued. Additional runtime space to be allocated for the blob can be specified using the -s option. If no size is specified, 80 bytes (20 longs) is the default. For example, to instead specify run-time space of 200 bytes (50 longs): spinc -B 2 -s 200 -n my_blob secondary.binary >blob.inc As shown above, the -n option can be used to specify a name for the secondary, otherwise the binary file name is used. This name will be used for the start function, the blob itself, and all the constants defined for the blob. The output is a C source file, suitable for inclusion in the primary program. The output of the spinc program is intended to be redirected to an include file that will be included in the primary program. Not only does it contain the start function and the blob in the form of an array, but also (as a series of #defines) the necessary addresses and sizes associated with the blob. This information can be used to allocate runtime space for the blob. The #defines are all named in a similar way to the start function, by preceding them either with the binary file name, or the value of the -n parameter. The most important ones are: #define <>_BLOB_SIZE 0xXXXX // size of the blob in bytes #define <>_RUNTIME_SIZE 0xXXXX // runtime size required in bytes #define <>_CODE_ADDRESS 0xXXXX // Hub RAM Address for execution These and other constants are used by the start function, and can also be used in the primary program. For instance, to reserve runtime space for a secondary called My_Prog, and also to print it at runtime so that it can be used in the spinc process, the primary program might include code similar to the following: #include "My_Prog.inc" void main(void) { char RESERVED_SPACE[My_Prog_RUNTIME_SIZE]; ... if ((int)&RESERVED_SPACE != My_Prog_CODE_ADDRESS) { printf("Recompile My_Prog using -R 0x%x\n", (int)&RESERVED_SPACE); } ... } The spinc process must be repeated for each secondary program (each one must have a unique name, even if the same binary is used to create them). For examples of producing and using blobs, see the demos\multimodel directory. Multi-Memory Models and Multi-threading ======================================= The new Multi-Memory Model support works with the existing multi-threading support, but things can get a little complicated. First of all, note that if a primary or secondary program is multi-threaded, then ALL the dynamic kernels started by that program using the existing _thread_cog() function or the new _threadstart_C() functions will also be multi-threaded, and use the same memory model. However, threads cannot be shared between primary and secondary programs. So while each primary or secondary program can share threads with any kernels they start using the _thread_cog() or _threadstart_C() functions, they cannot share threads with other primary or secondary kernels started with the new multi-model start functions, even if the programs are identical and use the same memory model. Each primary and secondary program (and any additional kernels they start) constitute a separate and isolated "world" as far as threads are concerned. However, it is perfectly feasible for a threaded primary program to start a non-threaded secondary program, or vice versa. To facilitate this, additional threaded start functions have been added to explicitly start a secondary program as a multi-threaded program, corresponding to the various _cogstart functions: On the Propeller 1 and Propeller 2: _threaded_cogstart_CMM_cog() - start a blob as a threaded CMM program on a specific cog _threaded_cogstart_LMM_cog() - start a blob as a threaded LMM program on a specific cog On the Propeller 2 only: _threaded_cogstart_NMM_cog() - start a blob as a threaded NMM program on a specific cog Since the most likely case is that the primary and secondary programs will both be threaded, or both be non-threaded, by default the spinc utility will use the threaded or non-threaded start functions based on whether the primary program is threaded or non-threaded. However, if your primary program is threaded and your secondary program is not (or vice-versa) then you can override the default using one of two methods: 1. You can manually specify which start function to use using the -f command-line option to the spinc utility. For example, to specify the non-threaded start function be used, even though the primary program is threaded: catalina -lc -C NO_ARGS secondary.c spinc -B2 -f _cogstart_LMM_cog -c secondary.bin >secondary.inc catalina -lc -lthreads primary.c Or, to specify the threaded start function be used, even though the primary program is non-threaded: catalina -lc -lthreads -C NO_ARGS secondary.c spinc -B2 -f _threaded_cogstart_LMM_cog -c secondary.bin >secondary.inc catalina -lc primary.c See the build_all script in the demos\multimodel directory, and the instructions for building run_dining_philosophers.c for an example of this method. 2. You can specify which start function to use in the program itself, by defining one of the following two symbols prior to including the output of the spinc utility: #define COGSTART_THREADED /* use threaded start functions */ Or #define COGSTART_NON_THREADED /* use non-threaded start functions */ See the file "run_dining_philosophers.c" in the demos\multimodel directory for an example of this method. Note that the use of the first method (described above) overrides the use of this second method. Multi-Memory Models and Overlays ================================ When using XMM modes on the Propeller 1, it makes perfect sense to create secondary programs in XMM RAM and use them as "overlays". The secondary programs occupy no valuable Hub RAM until they are needed. When they are needed they are loaded from XMM RAM into Hub RAM for execution, and they can be terminated and the same Hub RAM used for other purposes - such as loading another secondary program. However, Catalina (as yet) does not support XMM RAM on the Propeller 2, which means all secondary programs would exist in Hub RAM even when not being used. Worse, when they are executed, TWO copies of the programs will exist in Hub RAM, since the blob must be copied to the Hub RAM location it was compiled at for execution. This would seem to make multi-memory model support somewhat less useful on the Propeller 2 than on the Propeller 1. However, Catalina also allows programs to load overlays from files on an SD Card. This is supported on both the Propeller 1 and the Propeller 2. Producing a file blob: ====================== To make use of the MMM feature to load overlays from a file, the spinc program is used with a new option specified (-o 'name'), which will generate an output file (called 'name') containing the binary blob instead of an array. Using this option will also generate a start function that will load the blob from the named file at run time. For example: For a non-threaded overlay: catalina -lc -R 0x4000 -C NO_ARGS secondary.c spinc -B2 secondary.bin -o blob.ovl >secondary.inc catalina -lcx primary.c For a threaded overlay: catalina -lc -lthreads -R 0x4000 -C NO_ARGS secondary.c spinc -B2 -f _threaded_cogstart_LMM_cog secondary.bin -o blob.ovl >secondary.inc catalina -lcx -lthreads primary.c Note that an include file is still generated, and must still be included in the primary program even though the blob itself is written to the overlay file. The include file contains the start function that will load the blob from the named file on the SD Card at run-time. Of course, the primary program must be built with an SD Card file system to be able to load the overlays (in the cases above, this is accomplished by linking with the extended libraries via the -lcx command line option), and that the overlay files must exist on an SD Card which is inserted into the Propeller when the primary program is started (in the examples above, that file will be called 'blob.ovl'). An overlay file is not a normal Catalina binary - it is just the code and initialized data segments of the secondary program. The secondary program must be compiled to run at the correct address when loaded, and the start function will load the overlay file into this location in Hub RAM. A simple example of overlays is included in the demos\multimodel directory.