mbed for p14p on the v10 branch

80 views
Skip to first unread message

Dean Hall

unread,
Feb 22, 2012, 12:58:49 AM2/22/12
to python-o...@googlegroups.com
When I started the v10 branch, I put all the platforms into the "_unmaintained" folder except the desktop platforms. Well, I need to do a P14p demo soon, so I resurrected the mbed platform on v10 and got it working using the cloud compiler. I just committed this and everyone should be able pull the update, "hg up -C v10" and "scons PLATFORM=mbed" to get a zip to use on the mbed.org compiler.

I attempted to use an arm-none-eabi-gcc toolchain for a local build as an additional option, but had some build errors that I couldn't easily figure out. I have commented out the attempts to build locally near the bottom of src/platform/mbed/SConscript. I hope someone can fix this and share the improvement. (Please note that it requires exporting an empty mbed project and copying all the files from the empty project's zip file's mbed directory into src/platform/mbed/mbed I can't put these files into the repository due to ARM copyright.)

!!Dean

James Thomas

unread,
Feb 22, 2012, 11:53:29 AM2/22/12
to python-o...@googlegroups.com
Dean-

I have a code-sourcery build working for mbed on V10 but in order to get it to work I ported over the make-based build system (to be honest I'm not a fan of the scons based build system).  If you are only using the mbed library I think you should be able to get the build to work without any code modifications.  I had a few problems with the FAT file system library that required tweaks to the code and .ld file.  However one of the things that I did to get things to work was change the platform files to .cpp to fix some c/c++ namespace issues.

Unfortunately the resultant code size is much larger than the online compiler.  So I'm using the offline compiler to reduce development cycle times but once something works the online compiler is a much better choice.

I'm attaching my make file so you can see what settings I used etc. but since I have a very different approach to the platform library code you won't be able to use it as-is.   As I mentioned here months ago I'm using a C-macro based wrapper system to semi-automatically generate most of the platform library code (my file for the entire mbed library is only 420 lines of  C code).  The secondary advantage is that I can write C code in a .cxx file using normal C syntax and editor and the macros will wrap that into the .py file in the __NATIVE__ string block.

If you post the specific errors you are having I can try to see if I can come up with what fixed it.

JT


!!Dean

--
You are subscribed to the "python-on-a-chip"  (or p14p for short) Google Group.
Site: http://groups.google.com/group/python-on-a-chip

Makefile

Dean Hall

unread,
Feb 26, 2012, 5:04:16 PM2/26/12
to python-o...@googlegroups.com
The local build issues I'm having are c/c++ namespace issues. I just need to fiddle around some more until I find the right combo of build options. Thank you for sharing your makefile.

I am getting huge binaries also. I believe the linker is pulling in the entire mbed library AND libc (p14p uses snprintf()).

!!Dean

> <Makefile>

James Thomas

unread,
Feb 26, 2012, 5:57:26 PM2/26/12
to python-o...@googlegroups.com
As you can see from my make file I just changed the problematic .c files to .cpp and used the C++ compiler on them.  I think anything that includes mbed.h needs to be a C++ file or else you have to find some sort of trick that I didn't.

JT

Dean Hall

unread,
Mar 6, 2012, 10:52:40 PM3/6/12
to Lucio Di Jasio, python-o...@googlegroups.com
Lucio,

You've provided great questions and feedback that I'm sure many people on the mail list would find interesting. So I hope you don't mind that I cc'd the list.

Good job on exploring new things!

Answering your items number-by-number:

1 - You encountered issue #225 ( http://code.google.com/p/python-on-a-chip/issues/detail?id=225 ) which was resolved on 2012/02/20. So you can hg pull to get the recent change, hg update and recompile to get the fix.

2 - P14p does not yet have "support" for exceptions. The VM detects exceptions and throws them (in C code), but there is nothing the programmer can do to catch these exceptions. Unhandled exceptions leave the VM's stack in an unstable state, so I let the VM exit. This is very ungraceful. It does require you to restart the VM (reset the MCU) and reload everything. Supporting exceptions has been on my issues list for a long time: http://code.google.com/p/python-on-a-chip/issues/detail?id=6

3 - The generated code was a design tradeoff. This change was done to eliminate code images in favor of code objects written directly in C by the code generator. This has substantial RAM savings. I also unified what used to be "user" native and "library" native in order to take advantage of constant pool reuse. This means that if a P14p library has the string "sys" in it and your user code has the string "sys" in it, they both refer to the same object in program memory resulting in saving program memory.

I hope debugging is not more complex. I specifically inserted directives such as:
#line 44 "src/lib/dict.py"
into the native functions so that the C compiler (and even the VM exception reports!) will report the error as coming from the Python code that contained the native function. I also believe having cryptic generated code will reduce the chance that someone will intentionally modify it by hand (and potentially cause trouble). My hope is that nobody should ever have to look into the generated code (except to learn).

4 - I relocated the call to plat_init() outside of pm_init() to help people who use p14p inside other programs on a desktop and for people who use p14p with an RTOS. I believe this allows the programmer more flexibility.

You are very right about the effect that removing mem_GetByte() has. This decision was intentional. I realize that MCU technology is allowing larger memories and 32-bit architectures are becoming as inexpensive as 8-bit ones. I removed mem_getByte() because doing so is a significant performance boost: all objects that were created by the code generator at compile time are accessed directly. The old way was that the object was an image and had to be ready byte-by-byte into an object in RAM. I do lament the loss of support for architectures which can't directly address program memory (AVRs and [serial]EEPROMs), but anyone who needs those platforms can stick with the r09 (and upcoming r0A) code base. AVRs are showing their age, XMEGAs can directly access program memory. And the alternative to code images in [serial]EEPROMs is to put marshaled code objects in that memory and load it at some point after platform init (requires hacking).

5 - You're right about the scheduler. I haven't put much effort into it at all. Threading is such a difficult topic. So many people want it done differently, that I haven't devised a one-way-fits-all approach yet. I appreciate your suggestions.

!!Dean


On Mar 6, 2012, at 10:46 AM, Lucio Di Jasio wrote:

> Hi Dean,
> I have moved to the V10 branch and got it working on the PIC32!
> This has been quite a ride for me!
> I am new to Python in general, so studying your code has been a great help to understand the true nature of this language. Add to that that I had not worked much with "make" in the last decade (relying mostly on the company IDE to take care of things for me, and now you got me on Scons!
> Then there is Mercurial, I had been using Subversion in the past, and I have to thank you again for getting me to try a new (good) thing.
>
> There are a few things though that I noticed in V10 and I would like to understand better:
> 1- while the ipm interface is improved (each character received is immediately echoed now) , when I use the load command I get the following error:
>
> ipm> load test/TFTTest.py
> Traceback (most recent call last):
> File "../../tools/ipm.py", line 412, in <module>
> main()
> File "../../tools/ipm.py", line 377, in main
> i.run()
> File "../../tools/ipm.py", line 337, in run
> self.cmdloop()
> File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/cmd.py", line 142, in cmdloop
> stop = self.onecmd(line)
> File "../../tools/ipm.py", line 266, in onecmd
> cmd.Cmd.onecmd(self, line)
> File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/cmd.py", line 219, in onecmd
> return func(arg)
> File "../../tools/ipm.py", line 240, in do_load
> self.conn.write(l & 0xff)
> File "../../tools/ipm.py", line 192, in write
> self.s.write(msg)
> File "/Library/Python/2.6/site-packages/serial/serialposix.py", line 467, in write
> t = len(data)
> TypeError: object of type 'int' has no len()
>
> Not sure if this is due to my version of Python (I am on 2.6.1) as I am running this on a MACBook Pro (Snow Leopard).
>
> 2- More in general I am perplexed with the pymite handling of errors when executing ipm.
> It appears that any error (even just an attribute or name error) common with trivial typos can practically send the machine off exiting the main program. This causes the debugging/development session to practically restart from scratch. All interactive commands (imports, inits) must be re-entered ...
> Is this necessary? THis is quite opposite to what happens in IDLE for example...
>
> 3- I noticed among the many changes in v10, that the native functions and libs are now handled differently.
> In particular the "generated" files (nicely gathered in a single .c and .h) appear to be more criptical and much less readable.
> Eventually debugging a platform has become much more complex now.
>
> 4- The platform init() is now left to main() (which eventually is more transparent) just as the HEAP allocation (nice) but the mem_GetByte() function is gone too and with it the option to fetch code from "other" media now replaced by the macro "PM_PROGMEM" which is simply a "const" and therefore works for me, but only as long as the microcontroller has enough FLASH memory to keep it all on board. I fear this will kill the AVR and other small platforms or further severely limit their capabilities.
>
> 5- The scheduler is nice and simple, but I noticed the lack of a "yeld" function of sorts to be used when a thread wants to pass until the next event. There are a couple of enhancements that would make it really useful in embdedded control:
> a- Adding the ability to schedule a (waiting) thread only when a specific event/resource is available.
> b- Adding an IDLE process (possibly to put the controller in a standby/low power mode) when all other threads are waiting
> Both can be added today, using a mechanism similar to the one you used for the "periodic" call to reschedule (using flags set by the interrupt service routine: interp_setRescheduleFlag()) but it would be nice to be able to put something generic in the VM allowing each platform to take advantage of it as needed. I have not fully though it out, but I could make a proposal...
> BTW in thread.h there is a macro defined to specify the frequency
> /** Frequency in Hz to switch threads */
> #define THREAD_RESCHEDULE_FREQUENCY 10
> But it is not used! On the contrary in pm.c the pm_vmPeriodic() function uses PM_THREAD_TIMESLICE_MS instead which is defined locally inside the pm.c same file.
> I think the latter works, but it should be given a little more visibility (plat.h?) and the former could/should go...
>
> Thanks for all your work/help, I hope soon to be able to send you a couple pictures or perhaps a video of actual applications running on the new platform...
> Lucio
>
>

Reply all
Reply to author
Forward
0 new messages