My first Propeller C program (if I can do it. . . )
Ken Gracey
Posts: 7,401
Hey all,
I shouldn't have been so late to this party but I have to say I'm really excited about Propeller GCC. This afternoon I had a 15 minute break and I installed the 40 MB Propeller GCC compiler and sample programs.
Next I found the lmm_toggle directory and proceeded to modify toggle.c to look like this:
Compiled the code and downloaded to RAM in a Propeller BOE. I was really excited to see the results! At least now I can run the demos that all of your are producing and do something beyond being the sideline cheerleader. Didn't want to wear a dress anyway.
I need to learn enough about C to port some of my simple projects from Spin. I need to find a C tutorial for business types (hah ha) - does such a book exist? Can somebody point me in the right direction so I can get a better feeling for the syntax? I have a whole week off over Thanksgiving and I think I should be able to come back here with some real questions and a demo of my own.
Nice work to the Propeller GCC developers!
Ken Gracey
I shouldn't have been so late to this party but I have to say I'm really excited about Propeller GCC. This afternoon I had a 15 minute break and I installed the 40 MB Propeller GCC compiler and sample programs.
Next I found the lmm_toggle directory and proceeded to modify toggle.c to look like this:
*/ #include "propeller.h" int main(int argc, char* argv[]) { int mask = 0x3fffffff; int freq = CLKFREQ>>1; DIRA = mask; for(;;) { OUTA ^= 1<<0; OUTA ^= 1<<1; OUTA ^= 1<<2; OUTA ^= 1<<3; OUTA ^= 1<<4; OUTA ^= 1<<5; OUTA ^= 1<<6; waitcnt(freq+CNT); } }
Compiled the code and downloaded to RAM in a Propeller BOE. I was really excited to see the results! At least now I can run the demos that all of your are producing and do something beyond being the sideline cheerleader. Didn't want to wear a dress anyway.
I need to learn enough about C to port some of my simple projects from Spin. I need to find a C tutorial for business types (hah ha) - does such a book exist? Can somebody point me in the right direction so I can get a better feeling for the syntax? I have a whole week off over Thanksgiving and I think I should be able to come back here with some real questions and a demo of my own.
Nice work to the Propeller GCC developers!
Ken Gracey
Comments
I thought you were following the "business types" guide to C - set direction, hire consultants, concentrate on YOUR job until they are done! (kidding!)
Hats off to all the developers!
We still need to find a front-end Eclipse guru. Got a few tips from Captain Quirk but more options would be beneficial.
And hats off to the volunteers, too. If any of them want anything we can provide (hardware, robots, sensors, etc.) please contact me. Your contributions are truly valuable.
Ken Gracey
In another thread a lot of people recomended "The C Programming Language(ANSI)" by Brian W. Kernighan and Dennis M. Ritchie. I picked up a copy at BN I just started to get into it. It assumes you have a little programming knowledge, but I understand it so far (I Think). As I go through it I am going to compile and run it on my computer and then the Propeller with PropGcc. Propgcc has compiled and ran the first two examples with no problems.
Yeah, Great Job Propeller GCC Team.
Ron
What I'm not sure about is how the Propeller's capabilities will shine through in C. For example, how can any standard C code run on a Propeller when syntax must be supplemented for cog launching, driving a VGA, etc. I guess everybody accepts that C must vary from what we've seen on a PC to be useful in embedded systems. Probably a very elementary concern. David Betz is porting the VGA from Spin to C/PASM blob so maybe that'll answer my questions.
Forgot to mention the book is in its 2nd Edition. I also found this C Reference Card (ANSI) usefull makes a good book mark to.:cool:
Ron
Good points.
I've experimented with two solutions. One involves writing an IDE that can detect pasm code and separate it out and compile it and then read it back in as a C array and copy it into a C program as a hex array.
The second is to treat such compiled programs as something that can be loaded off an sd card.
In both cases the C and the pasm have to be separated out and the only interaction between the two must be via the array passed by par. This means that not every piece of code in the Obex can be translated easily.
Some work well though. The mouse for instance (this is Catalina code):
At the beginning of the program, declare an array to store this. This works best for XMM so this array ends up in external memory rather than hub memory. This saves hub memory. You could also load directly from an sd card into the cog, but I have written this so there is a copy in external memory as reloads are then quicker. In terms of speed, you could put the cog data anywhere - fastest = in hub, medium =external ram, slowest = sd card. It depends if you will be loading and reloading cogs through the program or just loading them once at the beginning.
In the main, declare the common array between hub and spin. In Catalina, declaring an array in "main" means it is local and so ends up in hub rather than in external memory
Read the cog data from an sd card into the xmm array we declared earlier. The file "mouse.cog" is actually "mouse.bin" which is the pasm part of the standard Obex mouse driver that has been compiled without any Spin.
which calls this code to read from the sd card
Then fill up the array we pass to the cog with some parameters
which calls this routine
and which calls this routine to move data from an array in external memory into a cog:
That starts up the cog, and the mouse location and the buttons appear in the mouse_parameters array.
This is a fragment of code to read the mouse pointer and check it is not off the screen and to see if a button has been pressed
You can do the same thing with a VGA driver, eg this is a C translation of Kye's VGA driver. Separate out the pasm and the Spin. Convert the Spin to C. Compile the pasm part to a binary file, rename it as .cog and put it on an sd card
and for reference, this was Kye's original Spin/Pasm VGA driver. Compare the function 'pixenginestart' in C and Spin
I beg to differ - Catalina allows you to run exactly the same C code you run on your PC on your Propeller!
Catalina supports launching C (or Spin or PASM for that matter) in multiple cogs using syntax that will be very familiar to anyone who has ever used Posix threads, plus it has full VGA, TV, serial device, file system support using standard C syntax, plus it gives you access to all the unique facilities of the Propeller.
Yes, I expect GCC may catch up eventually ... but why wait?
Ross.
P.S. Sorry, Ken - but you asked for this one
Just a little clarification here. Technically as far as syntax goes C is C is C...That is to say that Catalina or ICC or propgcc or whatever C are designed to support the same standardized C syntax. (Give or take a few standard revisions). The syntax is not modified to support Propeller features.
Next up we have to consider the environment your C code runs in. One of the reasons C became so popular is that it did specify a minimal input output system based on library functions. Old languages like Algol did not do that and every "Hello world" program ended up using some weird IO system local to that compiler or that machine. Things were very unportable. (N.B. Spin is still in that era). So C has things like printf for dealing with the console and fopen, fclose, fprintf, fscanf etc etc for dealing with files and so on.
So yes any standard code can run on any machine supporting the standard without modification. As Catalina does and propgcc surely will.
Next up we come to all those features of embedded devices that are not mentioned in any standard. The classic simple case being how to set a pin to input or out put and how to read and write it's state. For sure every compiler and every system does this a different way. Remember the C syntax is not changed to do this but different library functions or macros may be supplied to do it. Or perhaps you are just left to know the address of the register that drives that pin and have to figure out how to read/write it your self. (Much like Spin). In the extreme on something like a Linux system or Windows you may end up having to write an entire device driver to connect your user application to the hardware!
In the embedded world all this customization of I/O and special device features is pretty much taken for granted.
I have to take issue with RossH though, the vast majority of C programs that will run on a PC will not run on your embedded system just because your compiler supports the C standard libraries. There is always a pile of operating system and or hardware dependencies that make it unlikely your code will work with out modification or perhaps porting the OS interface from one OS to another. Why do we need things like cygwin and mingw otherwise?
Having said all that. GCC does have a pile of non-standard extensions to the actual C syntax. A wise programmer wanting to create cross-platform code would not use such extensions. I am guilty of using one such extension in order to get my full duplex serial driver compiled into native COG code to run at 115200 baud.
But if you restrict yourself to ANSI C programs (i.e. C programs written in the last 20 years or so) then yes they will - provided (of course) that there is enough RAM space for them to do so. Ummm. This is also a bit of a red herring. Yes, if I write a program that uses some OS-specific libraries, then it will probably not work on another OS. But this has nothing to do with C itself - it is true in any language. A good question - but I'm not sure I see the relevance to this particular argument. Cygwin and/or MinGW are required by GCC because GCC is specifically intended to run in a Linux-like OS environment, not a Windows one. This is not true of other C compilers (including Catalina), and it also has nothing to do with the language supported by the compiler.
Ross.
True, no argument there. But of course programs with those restrictions are
basically useless on most MCU systems. Take that simple I/O pin access for
example. I have an application that uses a lot of general purpose I/O bits
running on an industrial PC under Linux. We created a Linux device driver for
those I/O's. So yes, the app can use standard functions to access those I/Os
now. But would you really want to carry all that baggage to a small system
where INA/OUTA would do?
Yes it is. OS specific or hardware specific the problem is always there.
I'm just hinting that on a Propeller or other MCU we don't really need all those
standard libs. Spin users have not missed such luxuries so far.
A very good point. Given a standardized C language which also standardizes the
I/O and such, the run time environment. How the hell did the GNU guys come
up with a compiler that doesn't just compile anywhere that has a similarly
standardized compiler to start with? After all when all is said and done it's
just read text in, write binary out.
It's been long time since I've been here, and now I see this. However it comes out, my opinion is that C on the Prop is .... hmmmmmmmmm..... unnecessary. You are killing what Prop can do with this. I never could understand all these *MM things. And over 5 KB "Hello world" .... Nothing good.
Bad direction. I have nothing more to say.
Congratulations on writing your first C program! I think you'll find that most fairly generic C code will run on the PropBOE as long as it fits into hub memory. Also, I've just finished an SD cache driver that will allow larger programs to run on the PropBOE or any Propeller board with an SD card interface. This gives an almost limitless amount of code space but data will still be restricted to hub memory since the SD card is currently treated as read-only. Of course, programs will run much slower from the SD card but performance may be good enough for a non-time-critical main program. Anyway, have fun with C on the Propeller and feel free to ask questions if you find yourself getting into difficulties.
David
You can use C as a kind of "structured assembler" and write programs that will never be portable, were never intended to be portable, and would generally be better off actually written in assembler if you could be bothered to do so - Dr_A just posted a perfect example in the Catalina 3.4 thread (a driver for an LCD display).
Or you can use C and write extremely portable programs, but at the cost of efficiency. Rayman's chess program was a good exampe of the latter, also posted in the same thread.
But you also find programs designed to be embedded that are written in ANSI C. Take the Lua scripting language - 100% ANSI C, runs fine on the Propeller (well, a little slow on the Prop 1 perhaps - but it will be perfect for the Prop 2!).
However, most C programs (ANSI or not) fall somewhere in between. A well structured C program would typically have >95% completely portable C that will compile correctly on any C compiler, and <5% platform (or OS) specific C that won't. Good examples are the xvi text editor, or David Betz' xbasic. In both these examples the platform specific code limited to a single file of no more than a couple of dozen lines of code - and both run fine on the Propeller. Are these programs "useless" on an MCU? Well, for you perhaps they are - but for others they most definitely are not!
What baggage? If you don't use any of the standard library functions, they cost you nothing.
Ross.
(And congratulations on joining the ranks of C programmers, Ken!)
Eric
If we're going to be pedantic "syntax that will be very familiar" is not "exactly the same"! Propgcc actually has a pthreads library. It's still a work in progress, but you can launch threads on other cogs in propgcc using standard pthreads functions, not "pthreads-like" functions.
Of course Catalina could adopt the same library -- it's a fine compiler. But none of us are in a position to throw stones about who is "most standards compliant". Neither Catalina nor the current propgcc distribution is fully compliant with the latest C standard (C99). I daresay propgcc is closer to compliant with C99, and Catalina is probably closer to compliant with the previous C89 standard.
As did you .
Eric
If you use only gcc (and it's assembler gas) then code in cogs can communicate with the main code -- they can share variables in hub ram on so forth. And in fact you can often write the cog code in C, which is certainly easier than PASM (but a little bigger and slower).
For many drivers restricting the interaction to a memory block pointed to by PAR makes sense, and it does make it easier to port the code between compilers (and lets you do neat things like loading the driver from an sd card, as you showed). So that's probably the preferred way to do it wherever possible.
Eric
Your post is based on the premise that there is one direction and that implementing a C compiler for the prop in some way removes all the other methods of programming the device.
It doesn't.
What it does do is reduce the investment required for an embedded development shop to start using the propeller. They no longer have to learn a chip-specific language or asm, they can use the most commonly used language in the world. C.
So, keep on using SPIN, keep on using PASM. C just opens up our influence to a whole other world of developers and existing code.
Yeep, I guess 99% of embedded Software worldwide is written in C.
For my point of view : THANKS to all the people, they developed Catalina, ICCv7 and now propgcc.
best regards,
Reinhard
The point of C on the propeller chip is to prepare for C on the propeller 2. Alot of bugs and how to do things can be worked out now and then port to the new hardware when it comes out.
@ Ken
If people want ultra portable C code that works on any platform then they must have functions that must be called for any device specific functionality not in the C library or standard. This isn't really a huge issue. Any developer would just have to write the code more carfully and not use DIRA and OUTA but a function that could be replaced that sets DIRA or OUTA to hide the details of the underlying hardware.
http://mindview.net/CDs/ThinkingInC/beta3
There is also a free version of the book "Thinking in C++" in pdf form available here: http://www.lib.ru.ac.th/download/e-books/TIC2Vone.pdf
Volume two is available here: http://www.lib.ru.ac.th/download/e-books/Tic2Vtwo.pdf
However, volume two is less interesting for Microcontroller use.
propgcc does support C++, and we will use it to great effect in the long run.
This on-line tutorial is pretty good: http://www.cprogramming.com/tutorial/c/lesson1.html
Bob Lawrence recommended this book: http://publications.gbdirect.co.uk/c_book/ It is a good reference.
But I'll be quite impressed if propGCC can actually support pthreads (in its entirety) on the Prop 1! I'm not throwing stones - and certainly not about C99 - neither Catalina nor GCC claim to be C99 compliant, and I don't think C99 is all that relevant for embedded systems anyway - but I do think C89 compliance is important, and I have already said I expect GCC to become more C89 compliant over time. The main point (to bring this back to Ken's original posts) is that I believe such compliance to be necessary to the success of C on the Propeller, whereas some others obviously don't. But that's fine - everyone is entitled to their opinion, no matter how muddle-headed it may be
I guess we should let Ken have his thread back at this point - but I'd be happy to carry on this discussion in another thread.
Ross.
Say what? Surely the point of the propGCC project is to be able to offer C on both the Propeller 1 and the Propeller 2 ???? Or is propGCC on the Prop 1 just going to stay in alpha mode?
Ross.
I think we'll leave the rest to another thread and/or another time.
Eric
All my private hobby code is also following C89. There's very little in C99 that I find particularly useful, with the exception of the occasional need for declarations-following-code, but that's often a mis-used feature anyway and all in all it's better without it.
-Tor
Thanks!
BTW: I think GCC and Catalina will both be important for whatever Prop2 is called....