Parallax supported command line tool to load the P1 - SOLVED
The OpenSPIN spin compiler for the P8X32A does not include command line capability to load the compiled image to the prop.
the ploadlib module in the gcc complier for the prop has this code (to load a compiled raw image to the prop), and can be obtained as shown in heater's post (from May 23) below
Here is an example linux command line that will load an OpenSPIN compiled image file "SPINimage.eeprom" to eeprom, and begin execution:
Now the original request is changed, to have a note in the OpenSPIN readme, containing either the information from heater's post, or some directions how to find and use the ploadlib.c support for OpenSPIN.
Cheers!
Original post:
Hi Parallax
Users of OpenSPIN seem to be lacking a tool to load the propeller 1.
Our "build and test automation" code for generating new kernels and application images requires launch from a program script command line, and so anything that must be operated via GUI will not work.
While there are tools that load the P1, there are none that are both supported and stand-alone from the command line.
* Brad's Spin Tool still works of course, but it has no source code, and if a problem ever arises, there would be no way to fix it.
* There are proploader, p1load, propeller-loader, out on github, but these all appear to require propgcc. While propgcc is a fine tool, it is not used in a "spin only form the command line" environment, and just causes extra headaches.
Several users have made their own prop loaders, but along with not being supported by parallax, these appear to be derived from the propgcc code and also have all the propgcc support which is gets in the way.
This is request is for a parallax supported command line tool (in support of OpenSPIN users), for loading the OpenSPIN output compiled image to the prop, without the propgcc extra baggage, for linux, windows, and OSX.
Is this the best way to make this request to parallax?
Also, if such a tool exists, and I missed it, please point me to it.
Thanks!
the ploadlib module in the gcc complier for the prop has this code (to load a compiled raw image to the prop), and can be obtained as shown in heater's post (from May 23) below
Here is an example linux command line that will load an OpenSPIN compiled image file "SPINimage.eeprom" to eeprom, and begin execution:
./pload /dev/ttyUSB0 SPINimage.eeprom -p3
Now the original request is changed, to have a note in the OpenSPIN readme, containing either the information from heater's post, or some directions how to find and use the ploadlib.c support for OpenSPIN.
Cheers!
Original post:
Hi Parallax
Users of OpenSPIN seem to be lacking a tool to load the propeller 1.
Our "build and test automation" code for generating new kernels and application images requires launch from a program script command line, and so anything that must be operated via GUI will not work.
While there are tools that load the P1, there are none that are both supported and stand-alone from the command line.
* Brad's Spin Tool still works of course, but it has no source code, and if a problem ever arises, there would be no way to fix it.
* There are proploader, p1load, propeller-loader, out on github, but these all appear to require propgcc. While propgcc is a fine tool, it is not used in a "spin only form the command line" environment, and just causes extra headaches.
Several users have made their own prop loaders, but along with not being supported by parallax, these appear to be derived from the propgcc code and also have all the propgcc support which is gets in the way.
This is request is for a parallax supported command line tool (in support of OpenSPIN users), for loading the OpenSPIN output compiled image to the prop, without the propgcc extra baggage, for linux, windows, and OSX.
Is this the best way to make this request to parallax?
Also, if such a tool exists, and I missed it, please point me to it.
Thanks!
Comments
However there is a stand alone Propeller loader in the propgcc repository. One can download the propgcc source code and then just build that loader, no need to build all of propgcc.
I have done this, hence the pi-propeller-load I linked you to earlier.
The details of actually extracting the "official" loader from propgcc I can't describe at the moment. I have no way to test what I say here.
This is a hole Parallax should fill.
Not on the Parallax github repo. As far as I know not cross-platform and not open sourced.
Basically it does not exist as far as I can perceive.
https://www.parallax.com/downloads/propellent-library-and-executable-source-code
Here is the load prop method found in the command line version:
//command 1=load ram, then run, 2=load ram+eeprom+verify, then shutdown, 3=load ram+eeprom+verify, then run // Flush the buffers myCP2110.FlushBuffers(true, true) // Prepare the handshake squence preceded by &hF9 dim buffer as new MemoryBlock(251) buffer.Byte(0) = &hF9 // time sync dim i as integer = 80 // seed with "P" for the LFSR, pepare buffer with "secret" handshake for j as integer = 1 to 250 if Bitwise.BitAnd(i, 1) = 1 then buffer.byte(j) = &hff else buffer.byte(j) = &hfe end if // i = i << 1 | (i >> 7 ^ i >> 5 ^ i >> 4 ^ i >> 1) & 1; // predictable random numbers dim iL1 as integer = Bitwise.ShiftLeft(i, 1) dim iR7 as integer = Bitwise.ShiftRight(i, 7) dim iR5 as integer = Bitwise.ShiftRight(i, 5) dim iR4 as integer = Bitwise.ShiftRight(i, 4) dim iR1 as integer = Bitwise.ShiftRight(i, 1) i = iL1 or (iR7 xor iR5 xor iR4 xor iR1) and 1 next // Toggle DTR dim DTR as UInt16 = Bitwise.ShiftLeft(1, 13) // use GPIO9 (opendrain) as DTR myCP2110.SetGPIOValues(0, DTR) if myCP2110.LastError = HID2UART.SUCCESS then log "pulled DTR low" Wait(20) myCP2110.SetGPIOValues(DTR, DTR) if myCP2110.LastError = HID2UART.SUCCESS then log "pulled DTR high" // Send Handshake sequence Wait(100) myCP2110.Write(buffer.StringValue(0, buffer.size)) if myCP2110.LastError = HID2UART.SUCCESS then log "sent " + str(myCP2110.NumBytesWritten) + " bytes" // Send 258 sync bits buffer = new MemoryBlock(258) for j as integer = 0 to 257 buffer.byte(j) = &hf9 // set up 258 sync bits in one shoot as we have 480 byte fifo buffer we read later. next myCP2110.Write(buffer.StringValue(0, buffer.size)) if myCP2110.LastError = HID2UART.SUCCESS then log "sent " + str(myCP2110.NumBytesWritten) + " bytes of $F9 as sync bits" // read response from Propeller (258 bits) buffer = new MemoryBlock(258) buffer.StringValue(0, buffer.size) = myCP2110.Read(buffer.size) log "received " + str(myCP2110.NumBytesRead) + " bytes" // Get version number from response (8 bits) i = 0 for j as integer = 250 to 257 i = Bitwise.ShiftRight(i, 1) if buffer.byte(j) = &hff then i = i + Bitwise.ShiftLeft(1, 7) end if next log "Version: " + str(i) // Send the command as int32 (long) buffer = MakeLong(command) myCP2110.Write(buffer.StringValue(0, buffer.Size)) if myCP2110.LastError = HID2UART.SUCCESS then log "sent " + str(myCP2110.NumBytesWritten) + " bytes for command: " + str(command) // Send the length of the data as int32 (long) dim length as integer = Ceil(SpinCode.Size / 4) buffer = MakeLong(length) myCP2110.Write(buffer.StringValue(0, buffer.Size)) if myCP2110.LastError = HID2UART.SUCCESS then log "sent " + str(myCP2110.NumBytesWritten) + " bytes for length (" + str(length) + " longs)" // Send the data length = ceil((SpinCode.Size * 8) / 3) buffer = new MemoryBlock(length) dim bit as Byte = 1 dim buffcnt as UInt32 = 0 for j as Integer = 0 to length - 1 buffer.byte(j) = &h92 // fill buffer with $92 next // iterate through all the bytes for j as integer = 0 to SpinCode.Size - 1 // iterate through all 8 bits, starting with the LSB for i = 0 to 7 // check if bit is set // if ((SpinCode[j] & 1<<i) == 1<<i) if Bitwise.BitAnd(SpinCode.Byte(j), 2^i) = 2^i then buffer.byte(buffcnt) = buffer.byte(buffcnt) + bit // turn a %100 in to a %110 end if bit = Bitwise.ShiftLeft(bit, 3) // rolling bit if shifted out to zero, move on to next byte if bit = 0 then bit = 1 buffcnt = buffcnt + 1 end if next next // Writing the data. This needs to be done in chunks of 4096 bytes for large files log "sending " + str(buffer.Size) + " bytes of T1/T2 encoded SpinCode..." for j as integer = 0 to buffer.Size-1 step 4096 dim firstByte as integer = j dim lastByte as integer = min(j + 4096 - 1, buffer.size - 1) log "sending " + str(firstByte) + "..." + str(lastByte) myCP2110.Write(Buffer.StringValue(firstByte, lastByte - firstByte + 1)) if myCP2110.LastError = HID2UART.SUCCESS then log "sent " + str(myCP2110.NumBytesWritten) + " bytes" next for i = 0 to 2 Wait(100) buffer.byte(0) = &hf9 myCP2110.Write(buffer.StringValue(0, 1)) if myCP2110.LastError = HID2UART.SUCCESS then Continue next log "sent &hf9 " + str(i) + " times" log "Goodbye."
That way the entire process can be managed from any GUI that supports the command line, a hacker's paradise. With the advent of Windows 10 machines that cost some fraction of $100, I no longer care about cross-platform support. I am now convinced that any bot I build will either have a Win 10 machine or none at all. It only makes sense to develop on the compute platform that I plan to put in my bots. The GUI is a huge issue, that I could solve myself... except that PropellerTool is closed off from the command line.
I don't want my projects to be beholden to a single company, even if the hardware and software were free. So cross-platform support is still essential.
propgcc standalone downloader was not actually standalone, it relied on the rest of propgcc to work, and so did not work for me. I ended up using David Betts' version, but this is not official parallax, and is an extra step that should be included in the tool anyway, which is the purpose of this request. Yes, I do believe this is a hole parallax should fill.
Propellant is windows, and so is not usable, the tool must be windows, OSX, and windows.
Xojo is not free open source, and is not acceptable. Particularly $100 each license, and needing tweaks and further work. Typically this means lots of work, and maintenance headaches.
Again, this is for our automated build and test suite for PropFORTH. The process is run entirely from the command line and must be identical as possible on each OS. We start with a simple kernel written in spin (and compiled by OpenSPIN), and load that into the prop. Previously we used Brads Spin tool, but that is not supposed; when something inevitably goes wrong with it, we face problems. The PC side should be supported by the provider (parallax) for maintainability and compatibility. We know we are at risk, and wish to replace the unsupported bst loader with an official parallax supported loader.
The dozens of loader that are out there are all fine, but since they are not supported by parallax, are also at risk; ultimately these require us to support and maintain the loader ourselves, which is undesirable. If we need to write and maintain our own loader, that is always a possibility. That would be one more detour that we don't need.
In summary:
CAN PARALLAX PROVIDE THE SIMPLEST, MOST BASIC COMMAND LINE TOOL TO LOAD A RAW COMPILED IMAGE TO THE P8X32A, AND INCLUDE SOURCE CODE FOR WINDOWS, LINUX, AND OSX? This is an omission from the OpenSPIN tool, and should be addressed.
Thanks again!
Is there still a "suggestions to Parallax" mailbox I can sent this to? I can't seem to find one, and no parallax person has responded to this thread.
But really, checkout the prop-gcc source code. This is "official" Parallax supported. Compile PropellerLoadLIB.c, or PropLoadLIB.c or whatever it is called, by itself. It is a very small and simple, stand alone, loader program with no dependencies. You don't need to build the rest of prop-gcc to do this. Or even keep the source around.
Despite it's name PLoadLib.c is a complete stand alone loader. It has a main() function that is taken into use if you #define MAIN. It only needs a couple of other files to provide serial communication on whatever platform you are using, osint_XXX.c and osin_XXX.h.
Here is one can fetch those files from the prop-gcc repository and build a stand alone loader that runs on Linux:
$ mkdir ploadlib $ cd ploadlib/ $ wget https://raw.githubusercontent.com/parallaxinc/propgcc/master/loader/src/PLoadLib.c $ wget https://raw.githubusercontent.com/parallaxinc/propgcc/master/loader/src/PLoadLib.h $ wget https://raw.githubusercontent.com/parallaxinc/propgcc/master/loader/src/osint.h $ wget https://raw.githubusercontent.com/parallaxinc/propgcc/master/loader/src/osint_linux.c $ gcc -Wall -O3 -DMAIN -o pload PLoadLib.c osint_linux.c $ ./pload usage: pload <port> <filename> [-pN]
There we have it. One official, fully supported, standalone Popeller 1 loader.Yes, it loads, but I neglected to specify that the need is to load AND save to epprom.
Is there a simple way to load to eeprom using this function?
Have a look through the code, find the main() function, I think the command line argument set a variable called "mode" or "type" or something.
#define DOWNLOAD_EEPROM 2
#define DOWNLOAD_RUN_EEPROM 3
#define DOWNLOAD_SHUTDOWN 4
Examples:
$ pload <port> <filename.eeprom or filename.binary> -p1 <== load the program into the prop's HUB memory and run the program $ pload <port> <filename.eeprom or filename.binary> -p2 <== load the prop's eeprom, but don't run the program $ pload <port> <filename.eeprom or filename.binary> -p3 <== load the prop's eeprom & run the program etc...
propeller-load has the following optional parameters:
$ propeller-load usage: propeller-load [ -b <type> ] select target board (default is 'default:default') [ -p <port> ] serial port (default is to auto-detect the port) [ -P ] list serial ports with Propeller chips [ -Q ] list available serial ports [ -I <path> ] add a directory to the include path [ -D var=value ] define a board configuration variable [ -e ] write the program into EEPROM [ -r ] run the program after loading [ -g ] set up the program for debugging after loading [ -s ] write a spin .binary file for use with the Propeller Tool [ -x ] write a .pex binary file for use with the SD loader or SD cache [ -l ] write a program to the sd card and use the SD loader [ -z ] write a program to the sd card and use the SD cache [ -f ] write a file to the SD card [ -t ] enter terminal mode after running the program [ -t<baud> ] enter terminal mode with a different baud rate [ -T ] enter pst terminal mode after running the program [ -T<baud> ] enter pst terminal mode with a different baud rate [ -q ] quit on the exit sequence (0xff, 0x00, status) [ -v ] verbose output [ -S ] slow down the loader by adding 5 microseconds delay [ -S<n> ] slow down the loader by adding <n> microseconds delay [ -? ] display a usage message and exit <name> elf or spin binary file to load
The actual loader part of the code is the same, there are just 2 different entry points that can be compiled to create the executable loader as pload or propeller-load.
dgately
./pload /dev/ttyUSB0 PF5.5DevKernel.eeprom -p3
Thanks everybody!