Shop OBEX P1 Docs P2 Docs Learn Events
Parallax supported command line tool to load the P1 - SOLVED — Parallax Forums

Parallax supported command line tool to load the P1 - SOLVED

prof_brainoprof_braino Posts: 4,313
edited 2016-05-29 14:34 in General Discussion
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:
./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

  • Heater.Heater. Posts: 21,230
    I could not find one in the Parallax github repositories. Which I found surprising.

    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.
  • Cluso99Cluso99 Posts: 18,069
    What about Propellant ???
  • Heater.Heater. Posts: 21,230
    Cluso99,
    What about Propellant ???
    No idea.

    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.
  • I built a proploader in Xojo for use with the CP2110, both GUI and command line. In Xojo you can compile to Mac/PC/Linux if you own each license. Just load the same file for either platform, compile(in some case minor platform specific tweaks but not always). 100 bucks each platform. Not sure I recall how much is required to adapt it to FTDI. But the Proploader is rather specific to the Prop loading stuff so parts of it would likely translate easily. I highly recommend Xojo for anyone working with the Prop, it is a perfect combination of making apps that work quick and easy with the Prop with little programming skills. I stopped using FTDI and and needed a way to load with the Silabs USB UART. Screenshot is from the Tester GUI that allows a full range of testing with the Cp2110. The tester will load a binary, upload to ram/eeprom. If anyone wants to see the xojo file I can post a dropbox link, it is too big to upload. Depending on the binary size, I can get 200% speed loads. On large files, it gets funky, I think we determined that on large files at higher speeds Cp2110 is adding extra stop bits, not really sure. You could have a multi platform loader working rather quickly if you invested some time into this. I will explore how much effort it would take to convert it to FTDI. Free demo available at xojo site.

    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."
    
    
    617 x 655 - 79K
  • rjo__rjo__ Posts: 2,114
    Actually... what is needed is for the PropellerTool to respond robustly to the command line.

    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.
  • Heater.Heater. Posts: 21,230
    I don't see the need for the Propeller Tool if all you need is a Propeller loader. There are a dozen command line loaders out there already.

    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.
  • My understanding was that Propellant pretty much was the Proptool's downloader with a command line driver...?
  • Heater.Heater. Posts: 21,230
    Yes, I believe you are right.
  • prof_brainoprof_braino Posts: 4,313
    edited 2016-05-22 14:17
    Thanks all for the responses.

    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.

  • Heater.Heater. Posts: 21,230
    Raise it as an issue on github. Either in the prop-gcc repository or some other.

    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.

  • Have you tried Propellant under Wine?
  • propeller-load does not require the rest of PropGCC to run it. It just requires it to build it. That's because some of the helper code is written in C.
  • Can propeller-load load a binary file? I thought it only worked with the ELF files that are generated by PropGCC. I know it can produce a binary file from and ELF file, but can it load a binary file also?
  • Heater.Heater. Posts: 21,230
    edited 2016-05-23 05:51
    The heart of the prop-gcc loader is this file here: https://github.com/parallaxinc/propgcc/blob/master/loader/src/PLoadLib.c

    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.


  • Dave Hein wrote: »
    Can propeller-load load a binary file? I thought it only worked with the ELF files that are generated by PropGCC. I know it can produce a binary file from and ELF file, but can it load a binary file also?
    Yes, propeller-load can load .binary files.

  • Hey, thanks heater. That looks like what i need, I give it a whirl.

    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?

  • Heater.Heater. Posts: 21,230
    edited 2016-05-28 20:18
    I forget. There is a command line parameter to load eeprom, presumably -p. I seem to recall you need to set it to 1. Perhaps something like "pload /dev/ttyUSB0" myprog.bin -p1" will do it.

    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.

  • Assuming it's the same options as the full "propeller-load" program, try "-e". That will load to EEPROM with the version of propeller-load shipped with PropGCC.
  • dgatelydgately Posts: 1,630
    edited 2016-05-29 06:24
    There's a differences between the executables "pload' and "propeller-load". "pload" gets built by the source code that Heater gave links for in a post above. The "propeller-load" executable uses a different main function that allows more optional parameters than the main function in PLoadLib.c. An "#ifdef MAIN" provides a conditional compile of a different main function in PLoadLib.c which takes the "-pN" parameter with "N" being one of:

    #define DOWNLOAD_RUN_BINARY 1
    #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
  • Ok I got it, its the -p3 parameter that loads to eeprom and starts execution
    ./pload /dev/ttyUSB0 PF5.5DevKernel.eeprom -p3
    

    Thanks everybody!
Sign In or Register to comment.