Oli Glaser wrote: > The one that springs to mind first for PIC18 is Microchip C18. My > experience of it is very good - it's now pretty solid and bug free, > and seems to do very well optimising and keeping the program size > down, I have used C18 and I agree with the quality of code it produces. It has a optimization mode that looks for redundant snippets of code and puts them i= n subroutines to minimize code size. It works but is a pain to debug. However, C18 also has some drawbacks. For one thing, its language is C. I would definitely use higher level languages more on PICs if there was something better than C commonly available. But that aside, it uses data stack and subroutine linkage conventions that are idiotic. Memory stacks are implemented with the aid of instructions that can increment or decrement a pointer before or after the access. When you design a stack, there are two choices to make: which direction the stack grows in, and whether the stack pointer points to the last pushed byte or the first empty one. Each of the four choices require one complementary pair of pre/post inc/dec instructions. For example, a stack that grows towards high addresses and where the stack pointer holds the address of the last pushed byte would require preinc for push and postdec for pop. If you look at the PIC 18 instruction set carefully, you can see that it only has 3 of the 4 possible pre/post inc/dec instructions. The missing on= e is predec. That means the only complementary pair of instructions is prein= c and postdec. That further means that only 2 of the four possible stack choices allow push and pop to be single instructions. These two layouts ar= e a stack that grows towards high addresses with the pointer pointing to the last pushed byte (as above), and one that grows towards low addresses pointing to the first free byte (push=3Dpostdec, pop=3Dpreinc). Incredibly, the C18 designers chose one of the other two layouts: Stack grows to high addresses with the pointer pointing to the first free byte. This means push is a postinc and pop a predec, but the PIC 18 has no predec instruction. Duh! Not only does it therefore take multiple instructions t= o pop a byte off the stack, but worse, the sequence is now interruptable. But wait, there's more! The C18 designers weren't done sabotaging the architecture yet (did these guys secretly work for TI, Motorola, or Atmel?)= .. The PIC 18 has three hardware pointer registers, FSR0-FSR2. The aforementioned pre/post inc/dec addressing modes only work on these registers, so one of them needs to be dedicated to the software data stack. However that would leave two for the application, which would clearly be to= o useful. Their solution was to grab another of the precious FSRs for a fram= e pointer. A frame pointer can be useful in debugging to unwind the stack fo= r a dump, and make bookkeeping a little easier in the compiler, but it does nothing for you at run time in production code other than take up resources= .. There are plenty of compilers as existance proofs that you don't need a frame pointer, include C30 where using frames is a compile time option. However, C18 permanently reserves FSR1 as the stack pointer and FSR2 as the frame pointer, leaving only FSR0 for application use. But wait, there's still more! There was subroutine linkage yet to sabotage= .. C18 passes arguments to subroutines on the data stack. That by itself is reasonable enough given the hardware architecture, and certainly not unusual. However, there is the choice of when exactly these call arguments get removed from the stack. On large systems there are points on both side= s for the caller or the callee cleaning the stack. On small systems however, the choice is quite clear in that the callee (the subroutine) must clean th= e stack. Again, the C18 designers chose the opposite. This means app code pushes parameters onto the stack and calls a subroutine. The subroutine ca= n read the parameters off the stack, but is not allowed to remove them even when it knows it is done with them. That means all parameters for each cal= l level down from the main line code are always on the stack, requiring way more stack space than otherwise necessary. When I first used the old Microchip network stack, I found that even 128 bytes of stack space wasn't good enough for calling TCP routines. The software architecture used a lot of nested routines, and a lot of parameters, which ate up stack space quickly. Allocating a whole bank (256 bytes) for the stack may not seem that bad whe= n you've got 14 banks, but think about multi-tasking. Any project large and complex enough to have lots of nested subroutines and lots of arguments to them is probably using multi-tasking. Now each task has to have a large stack area reserved. This eats into the available memory quickly. Maybe someday Microchip will fix this mess, but so far I haven't heard anyone even acknoledge these are problems. ******************************************************************** Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products (978) 742-9014. Gold level PIC consultants since 2000. --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .