PIC stack overflow

Saturday, April 25th, 2009 by Nigel Jones

For regular readers of this blog I apologize for turning once again to the topic of my Nom de Guerre. If you really don’t want to read about stack overflow again, then just skip to the second section of this posting where I address the far more interesting topic of why anyone uses an 8-bit PIC in the first place.

Anyway, the motivation for this post is that the most common search term that drives folks to this blog is ‘PIC stack overflow’. While I’ve expounded on the topic of stacks in general here and here, I’ve never explicitly addressed the problem with 8 bit PICs. So to make my PIC visitors happy, I thought I’ll give them all they need to know to solve the problem of stack overflow on their 8 bit PIC processors.

The key thing to understand about the 8 bit PIC architecture is that the stack size is fixed. It varies from a depth of 2 for the really low end devices to 31 for the high end 8 bit devices. The most popular parts (such as the 16F877) have a stack size of 8. Every (r)call consumes a level, as does the interrupt handler. To add insult to injury, if you use the In Circuit Debugger (ICD) rather than a full blown ICE, then support for the ICD also consumes a level. So if you are using a 16 series part (for example) with an ICD and interrupts, then you have at most 6 levels available to you. What does this mean? Well if you are programming in assembly language (which when you get down to it was always the intention of the PIC designers) it means that you can nest function calls no more than six deep. If you are programming in C then depending on your compiler you may not even be able to nest functions this deep, particularly if you are using size optimization.

So on the assumption that you are overflowing the call stack, what can you do? Here’s a checklist:

  • Switch from the ICD to an ICE. It’s only a few thousand dollars difference…
  • If you don’t really need interrupt support, then eliminate it.
  • If you need interrupt support then don’t make any function calls from within the ISR (as this subtracts from your available levels).
  • Inline low level functions
  • Use speed optimization (which effectively inlines functions)
  • Examine your call tree and determine where the greatest call depth occurs. At this point either restructure the code to reduce the call depth, or disable interrupts during the deepest point.
  • Structure your code such that calls can be replaced with jumps. You do this by only making calls at the very end of the function, so that the compiler can simply jump to the new function. (Yes this is a really ugly technique).
  • Buy a much better compiler.

If you are still stuck after trying all these, then you really are in a pickle. You could seek paid expert help (e.g. from me or some of the other folks that blog here at embeddedgurus) or you could change CPU architectures. Which leads me to:

So why are you using a PIC anyway?

The popularity of 8 bit PICs baffles me. It’s architecture is awful – the limited call stack is just the first dreadful thing. Throw in the need for paging and banking together with the single interrupt vector and you have a nightmare of a programming model. It would be one thing if this was the norm for 8 bit devices – but it isn’t. The AVR architecture blows the PIC away, while the HC05 / HC08 are also streets ahead of the PIC. Given the choice I think I’d even take an 8051 over the PIC. I don’t see any cost advantages, packaging advantages (Atmel has just released a SOT23-6 AVR which is essentially instruction set compatible with their largest devices) or peripheral set advantages. In short, I don’t get it! Incidentally, this isn’t an indictment of Microchip – they are a great company and I really like a lot of their other products, their web site, tech support and so on (perhaps this is why the PIC is so widely used?). So to the (ir)regular readers of this blog – if you are you using 8 bit PICs perhaps you could use the comment section to explain why. Let the debate begin! Home

15 Responses to “PIC stack overflow”

  1. Gauthier says:

    Could it be that Microchip is better at marketing?Don’t they give free samples to universities? How about Atmel?

  2. Anonymous says:

    They are good at marketing for sure. Inferior product at higher price, and on of the least compiler friendly micros out there.Free samples for hobbyists and educational puposes worldwide (I got all the PICs this way, back when I developed my EE degree projects).

  3. Nigel Jones says:

    If it is a marketing issue, then what does it say about engineers? Aren’t we supposed to be objective and logical in our design decisions? If we aren’t, then the only explanation is that we go with what we are comfortable with, rather than what is right. Perhaps this explains a lot!

  4. Gauthier says:

    Objective and logical in our decisions, yes… given the time.If management pushes for fast development, there may be no other way than going with what you already know works (although not best). For example what you used in college, which seems a good place for marketing to focus on.That’s why I love to read blogs such as yours, and embedded.com for example. It gives me insights in other alternatives.

  5. Nigel Jones says:

    I think you are correct about management induced time pressures. It’s another symptom of ‘if you aren’t coding or debugging then you aren’t working’. Time spent on the front end of a project always pays dividends on the back end – the trick is how to convince management.

  6. GregK says:

    Have You notice that almost every problem we can treat like management problem, and in fact I think it is.Often for management software development is ‘transparent’, you get something to do with hardware and you do this. If You are lucky someone ask you what ROM memory you suppose to need, I have never get situation: what RAM size you need… so call stack deep is completely abstraction

  7. Miro Samek says:

    To add insult to injury, the 8-bit PIC microcontrollers have also the worst code density in the industry (see my blog post “Insects of the computer world” at http://www.embeddedgurus.net/state-space/2009/03/insects-of-computer-world.html).The 8-bit PIC is possibly the worst imaginable embedded processor in the history of mankind. PIC is not just braindead. It is outright dangerous.It also is the most popular chip in the world…This doesn’t add up in my mind. What’s wrong with our industry? Is the intellectual inertia the most dominant force for us?

  8. Kyle says:

    I think Microchip enjoys the benefit of being familiar to most engineers and the “incumbent part” on many redesigns. And while they may lag technologically today, they achieved a number of firsts in the 90’s which put them in this position. They were the first to break the $3 barrier, and then the $1 barrier. They were the first in 8 pin packages. They were the first to give away an IDE – not just command line tools. (The IDE price isn’t really an issue once you get into a serious development project but it will help you take a look at something you are unsure of using.) Atmel may have beat them at their own game technologically, but their marketing is still weak. I recently wanted to play around with an SPI interface part and thought it would be interesting to drive it with a USB interface and a PC application. I requested samples from Microchip and Atmel – I had found sample USB interface code for each processor but I wanted the option to use either after studying the examples. The Microchip part arrived in two days. The Atmel part took six weeks to get to me. If that had been a “real” project the decision would have been made long before the sample arrived.

  9. Nigel Jones says:

    Good point Kyle. If anyone from Atmel is reading this blog then I think it should give you cause to pause. So far no one has defended the PIC on technical grounds – instead it’s down to marketing. I’m struck by the parallels with the PC / Mac debate.

  10. Stephen says:

    From my perspective, PICs are readily available and cheap, but also have a very good range of peripherals available. Indeed, these are what keep me using PICs as you can do some pretty powerful stuff. Most programmers are isolated from the problems of the architecture as they use higher level languages. The PIC also has a few free C compilers available which makes it ideal for hobbyists and EEs on a budget. Also, for prototyping they are great as all the more basic ones are available in DIL packages so are very easy to breadboard. I believe also that Microchip are addressing some of the architecture issues with an enhanced baseline range.I guess also the use of PICs depends on what you are trying to do. For complex programs granted they aren’t that good, but for implementing simple functions they are pretty easy to use.

  11. J. Peterson says:

    I wanted a cheap, low pin count part with (here's the catch) a built in UART. The last requirement pretty quickly left me with the PIC16F688.I've found the BKND CC5X compiler does a reasonable job of letting you program the 16F688 in some semblance of C while generating efficient code. Well worth the $220.By the way, don't ignore the 16 bit PIC devices (PIC24F, dsPIC30 etc). Unlike the smaller chips, the 16 bit PIC line has a very clean architecture that works very well with C. They also have some great features (e.g., ability to map internal peripherals to arbitrary pins on the fly) that other chips don't have.

  12. Anonymous says:

    I entered with PIC18, and was mainly attracted because the barrier to entry is low and the abundance of peripheral devices like uarts, timers/counters, interrupt-pins and even integrated ethernet. I later migrated to dspic33 because the cost are not important (we ship 10 units a year, and some of the optocouplers on the print are more expensive than the most expensive microchip CPU), and our electronics man was able to solder even the 100pin devices by hand. 100pins, 2 uarts, CAN, I2C, 2x SPI, quadrature decoder, 6 timers, 6 interrupt pins, block-pin interrupts the list goes on and on, for Eur 5. Programmed in (gc)C.The only thing I hate is the missing ethernet support in the 16-bit line

  13. Anonymous says:

    I can tell you why PICs are most common, Microchip has the BEST documentation by far. The "getting started" series from Microchip is just Fantastic. I myself learned how to program PIC/PC interface in Assembly with the help of all the PDFs that microchip have online, without ANY knowlage of HI or LO level programming.Atmels documentation is much harder to understand for an amature /Sebastian

  14. Anonymous says:

    1) Don't agree with the economic tradeoffs selected by Atmel. PICs are ruthlessly cheap, fast, and high-feature compared to AVRs because Microchip didn't set out with the (quixotic and misdirected) goal of running GCC on a $1.90 part. 2) I find the Atmel marketing materials and documentation to be heavy-handed and evangelistic. 3) The Atmel demo boards are not as extensive or interesting as the PIC equivalents.4) PICs have been around longer; it's like Bing vs. Google. Part of me won't use Bing simply because Google got their first and I don't see why the gents behind Bing can't find something more creative to do with their time. So a couple of geniuses in Scandinavia made a little RISC chip for their senior project… who cares? I find the Atmel proponents to be a bit too heavy-handed and evangelistic in tone. The message seems to be "quit using that bloody primitive PIC and come into the 21st century, you knuckle-dragger" and I just don't respond to that. I'm paraphrasing and reading between the lines a bit, to be sure, but this is my impression. This translates into the documentation as well. The Atmel materials tend to drone on theoretically where the PIC docs are ruthlessly hands-on. Beyond that, I think it's a question of economics. Who really wants to write high-level code for a $1.00 part?

  15. Anonymous says:

    I read above that "no one has defended the PIC on technical grounds – it's all marketing." This supposedly calls to mind the PC-vs.-Mac dichotomy. I don't agree with that.I think a better analogy is UNIX versus Multics. The PIC philosophy is very similar to UNIX… to get a given piece of functionality into as many hands as possible as quickly and cheaply as possible. Edge cases (e.g. applications that might nest function calls beyond the capabilities of an 8-entry stack) are not allowed to impact the large majority of people with more rational needs. Like UNIX, the PIC architecture doesn't make heroic or costly attempts to deal with user error. If you exceed the boundaries of the fixed stack, the resultant behavior is potentially destructive, but is also easy to understand and presumably easy to implement… two very important points in its favor. In the case of UNIX, this "less-is-more" approach was justified because the team had tried to do something better (Multics), and it turned into an unusable behemoth. In the case of the PIC, the justification is that this narrow, undistracted focus has given us a cheap, fast, and comprehensible device. And I can't overemphasize this last point… I find it refreshing how Microchip's marketing materials enthuse that there are "only 35 instructions to learn." When I read things like that, I think "Someone else gets it. Sometimes less really is more." Practically, one big dividend of the PIC's simplistic assembly language is that it's quite easy to determine execution time. Much of the time, it's possible to determine execution time by measuring the code with a ruler! Sure, higher level features are nice, but by no means do they help with this task (which is crucial in real-time systems).In my opinion, the architects of the Atmel were too distracted by notions gleaned outside the embedded millieu. Sure, PIC assembly is crap if you're trying to port GCC to it. But there's nothing particularly wrong with PIC assembly for an assembly language programmer. Having worked with several assembly languages, I can assure you that there are scarier monsters than the PIC. For one thing, it's assembly language is small. This reduces the opportunity to write code that's slower than it needs to be. Atmel makes a big stink over the word "othogonal." But I do think PIC assembly is very regular and logical. All of the byte-oriented instructions have a version that places the result in a register and a version that places it in the accumulator. There are no exceptions, nor are extra modes grafted onto select instructions. This is a great deal more "orthogonality" than one finds in, for example, x86 assembly. I should add that simplicity doesn't just translates to cheap and comprehensible. It also translates into low power consumption and high speed.So, in summary, I think what many people overlook is the issue of "tradeoffs." And I do not think the issues of business can be seperated from the abstract concept of "design" quite so cleanly as many of the other posts propose.

Leave a Reply