Command Line Pinguino

I have been working with PIC-s for a while and a few months back I was informed of the existence of ‘Pinguino’. You can find it at this page. I also heartily recommend you read the blog site as well to get more background information on it.

Jean-Pierre has written a really compact and useful IDE in Python which does a wonderful job of hiding all the dirty details on firing of SDCC for a compile and link and using the upload tool. That is a big help for people that may not be familiar with such things. The IDE is really good but I couldn’t figure out how to make it use Courier which I pretty much always like for coding for the font and also it seems to have the odd issue with cut and paste getting out of synch with what is really showing on the screen. I am sure these will all be ironed out over time. As it stands, I can’t think of a better way for people to enter into the world of PIC development!

However, I have used Emacs for over twenty three years and I kind of get used to being able to do everything with it and it started to become apparent that the best thing I could do would be to modify the IDE so that it accepted just a single command line argument which would allow me to run the ‘compile’ command from within Emacs and keep on hacking!

Some Python hacking…

It’s been a long time! I chose not to follow Python because I just didn’t like the indeting-is-the-association thing. Anyway, I modified the main code to look like this, just a simple call to the command line basher…

if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_1 = Pinguino(None, -1, "")
    # OBJITSU modifications start here!
    frame_1.cliRequest()
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()

All it does is call the cliRequest() function which is as follows: it checks for the -c or -C and if either is present it compiles a single file and exists. Sure, you could go mad and allow this and that but I am a strong follower of doing the simplest thing.. C2.COM is an awesome site; regular reading def. boosts brain-cells IMHO.

Here is the implementation of the cliRequest() function, it just uses the standard getopt module and drives the desired functionality…

    #
    # This checks to see if a filename was given on the command line with
    # the -c option. If it was then we just do the usual thing and exit
    # without bothering to fire up the UI.
    #
    def cliRequest(self):
        args, opts = getopt.getopt(sys.argv[1:],'C:c:',[])
        for opt, arg in args:
            if opt in ('-C'):
                self.cliBuild(arg,True)
            if opt in ('-c'):
                self.cliBuild(arg,False)
 
    def cliBuild(self,filename,upload):
        self.commandLine=True
        if self.buildHexImage(filename):
            if upload == True:
                raw_input("Reset the Pinguino, press RETURN to upload HEX...")
                rawfilename,extension=os.path.splitext(filename)
                self.cleanUpload( rawfilename)
        sys.exit(0)

I also had to re-factor some of the internal code to de-couple the editor component from the pre-process, compile, link and upload code. For completeness I may as well throw in the actual function that the re-factored code calls and the new code calls so you can read it. It’s been a while since I cut Python code so it may appear a liitle ‘idiosyncratic’ in places! LOL :)

    #
    # This wil pre-process, comile and link the 'filename' as though
    # it had come from the UI
    #
    def buildHexImage(self,filename):
        filename,extension=os.path.splitext(filename)
        if os.path.exists(filename+".hex"):
            os.remove(filename+".hex")
        if os.path.exists(sys.path[0]+"/source/user.c"):
            os.remove(sys.path[0]+"/source/user.c")
        retour=self.preprocess(filename)
        if retour=="error":
            return False
        retour=self.cleanCompile(filename)
        if retour!=0:
            self.displaymsg("error while compiling file "+filename,0)
            return False
        else:
            retour=self.link()
            if os.path.exists(sys.path[0]+"/source/main.hex")!=True:
                self.displaymsg("error while linking "+filename+".o",0)
                return False
            else:
                self.cp(sys.path[0]+"/source/main.hex",filename+".hex")
                self.displaymsg("compilation done",0)
                os.remove(sys.path[0]+"/source/main.hex")
                os.remove(filename+".c")         
                return True

The file is available at the Pinguino forums shown somewhere near the bottom left of the post.

Using it…

It has some limitations; it must be run from the Pinguino installation folder as I am no Python export and couldn’t make it run from /usr/local/bin. I don’t care so long as I can use it from Emacs! LOL If somebody cares to polish it so it could be installed from /usr/local/bin and still load the button icons etc then that would be nice.

Straight compile to a HEX file

$ ./pgb7cc.py -c filename.pde
compilation done

Straight compile to a HEX file

$ ./pgb7cc.py -c filename.pde
/home/sean/pinguino/pinguino beta7 linux /source/user.c:24: syntax error: token -> 'void' ; column 12
 
error while compiling file ir-jammer-1

and finally a good build and upload…

Compile to a HEX file and Upload

$ ./pgb7cc.py -C ir-jammer-1.pde 
compilation done
Reset the Pinguino, press RETURN to upload HEX...
Processing device 004
erasing section [2000, 7fff]
writing section [2000, 7fff]

The upload will only happen if the build succeeds, otherwise it just halts there and then with the errors fed to stdout.

All in all I have really enjoyed re-jigging the IDE to allow command line operation and Jean-Pierre has inspired me to now go and write another tool-set but I think I may use one of Gambit Scheme or PicoLisp or Erlang or… or… or… I love/hate software! LOL

I hope you found this useful.
:)

Published: April 30th, 2010 at 10:35
Categories: Pinguino, Python, hacking!