You are currently browsing the archives for the Tips and Tricks category.
- AV16 (4)
- builtin (1)
- Chapter 1 (2)
- Chapter 12 (3)
- Chapter 14 (1)
- chapter 2 (1)
- Chapter 3 (1)
- Chapter 4 (1)
- Chapter 5 (4)
- Configuration (1)
- Events (2)
- Flying (4)
- I2C (5)
- Linux (1)
- MPLAB 8.00 (5)
- mplab c30 v3.02 (11)
- PIC24 (2)
- PIC32 (9)
- Tips and Tricks (14)
- Tools (10)
- Warnings (2)
- 19. November 2008: Bending the laws of physics
- 13. November 2008: Electronica 2008
- 6. November 2008: Deep Blue PIC32
- 4. November 2008: MIPS DSP Libraries
- 1. November 2008: Inexplicably Working Errata
- 26. October 2008: PIC32, Harvard or Von Neumann
- 22. October 2008: Back online, Excuses and the Blues Brothers
- 28. July 2008: Not a dsPIC!
- 23. July 2008: Scilab, FLEX and the Evidence
- 22. July 2008: New compiler and new libraries for the PIC32
Blogroll
PIC24
PIC32
Archive for the Tips and Tricks Category
Bending the laws of physics
19. November 2008 by pilot.
As a reader pointed out today, when preparing one of the pictures in Chapter 3, I did use a little trick, I had almost forgotten…
I did reduce the DELAY constants by a factor of 100 to … speed things up … so to speak. Otherwise the Logic Analyzer window would not be able to contain all the samples required to produce the complete “Hello” message.
I do these things quite a bit when I use the Simulator … Read the rest of this entry »
Posted in Tips and Tricks | No Comments »
3D Graphics
15. May 2008 by pilot.
Using the new double buffered graphic library (see previous post) we can now create simple animations. In chapter 12 we have already seen how to visualize a 2D function using a grid and a bit of perspective (isometric). The next obvious step is to look into 3D objects and how to animate them by moving and rotating them in space. Read the rest of this entry »
Posted in Chapter 12, Tips and Tricks, AV16 | No Comments »
Graphic Animation
10. May 2008 by pilot.
In the good old times, when studying at the University of Trieste, I particularly enjoyed Rational Mechanics, a required class for any EE Master back then, presented by professor Enzo Tonti. One of the things that were always making his lectures a pleasure (and a challenge) was his constant reference to, and practical use of, personal computers to illustrate visually the concept at hand.
Mind those were the early days of the Apple II, the Commodore C64, the Sinclair Spectrum and for the few lucky (and rich) ones among us the first IBM XT personal computers. The graphic capabilities of those personal computers were primitive to say the least. In fact, a single PIC24F128GA010 has today more program memory than any of those personal computers and the resolution of the video output, using the AV16 board we developed in the book (without any hardware assistance), is actually pretty close. Yet prof. Tonti used to teach us how to develop effective demos using little more than a few lines of BASIC or, I should say, of the “soup” of BASIC dialects that were popular at the time… (Actually prof. Tonti developed a brilliant scheme to identify a sort of minimum common denominator among all those disparate systems and Basic dialects that he called Inter-Basic if I recall correctly… there must be a web site somewhere where all this is documented)…
We simulated graphically the motion of planets around a sun, the complex motion of pendulums of various kinds, we animated objects in 2D and 3D! Key to all those graphic exercises was the ability to alternate fast images on the display to obtain the illusion of motion….
Posted in Chapter 12, Tips and Tricks, AV16 | 1 Comment »
Optimizing the graphic library
28. April 2008 by pilot.
While working on the porting to the PIC32 of the code developed for the original PIC24 book it occurred to me that there were some obvious optimizations I had yet to explore.
For a starter, the graphic.c library was using several resources including Timer3, the Output Compare 3 module, the Output Compare 4 module and the SPI1 port in addition to one general purpose I/O (RG0 in this case). The OC3 module was used to generate the Horizontal Synchronization pulse portion of the composite video signal, but the module output pin RD2 (active as soon as the module is enabled) was not used. Rather RG0 was “manually” set during the OC3 interrupt service routine and reset during the Timer3 interrupt service routine. This added unnecessary overhead to the application as the OC3 module could easily be configured to do it all by itself…
Posted in Chapter 12, Tips and Tricks | 1 Comment »
Visualizing Data - A taste of Visual C#
15. April 2008 by pilot.
Our brain is wired for image processing and all things visual just reach deep in our mind faster! If there is one moment when I just cannot seem to ever get enough of a “view”, that’s when I am debugging code. The Watch windows, the local variables windows, the stack window are not what I am talking about. The Logic Analyzer window (in MPLAB SIM) and the DCMI (with simulator and emulators) are barely starting to scratch the surface, when I need to debug some complex code, I am willing to use literally everything at my disposal, beyond MPLAB, using hardware (scopes and logic analyzers) but also additional software.
Posted in Tools, Tips and Tricks, MPLAB 8.00 | No Comments »
Look Mom No … Linker Script
9. April 2008 by pilot.
There are so many new features being added to MPLAB at each major (and minor) new release that I struggle to keep up. Just a couple of days ago for example, I was discussing with a colleague how it would be nice to have the MPLAB New Project Wizard to use a default linker script in every new project … so that in most standard cases the repetitive task of adding one (navigating through the many subdirectories inside Program Files) can be spared and … I got stopped mid-sentence and promptly reminded that this feature was already there! In fact since last November, with the introduction of version 8.00, MPLAB has been quietly offering a default linker script when the MPLAB C30 toolsuite is selected.
Thanks !
Posted in Tips and Tricks, MPLAB 8.00 | No Comments »
Of Explorer 16 boards and 5V LCD displays…
12. March 2008 by pilot.
I read with interest today an errata for the Explorer16 demonstration board…
I know, it seems strange to think of an errata for a demonstration board, but it can happen and as in this case, there is a good lesson to learn for all of us, living the dangerous lives of the Embedded Control designers on the edge between 5V legacy technology and the new 3V generations of products.
In order to keep their options as open as possible, the Explorer16 designers arranged for a number of different LCD displays to be used alternatively on the board. Three different layouts were pre-wired and, depending on market conditions (price) and availability, one of several different models of LCD displays (from different manufacturers) will be mounted at any given point in time. Since they are all compatible (or I should say there is a common minimum denominator among all of them) there are virtually no changes required to the demos and code offered with the board.
Interestingly some of these LCD displays are 5V and some are 3V devices. Since most of the PIC24 digital I/O pins are 5V tolerant, theoretically the two technology can be alternated without consequences except for one case that was recently uncovered.
When the Lumex LCM-S01602DTR/M module was used (the errata document will teach you how to recognize it) things got more complicated. This 5V LCD module has internal pull-up resistors connected to the 5V rail. When the PIC24 I/Os connected to it (for example PMPA0 which is multiplexed with the AN15 analog input function) is left three stated (very high impedence) it will let 5V get inside the PIC24!
Notice that this will not necessarily damage the part (the pull ups are pretty weak after all), but it will produce a more subtle problem, it will skew the internal analog voltage references and produce a large offset on the A/D module readings for example.
Reading the errata carefully, you will realize how an essential part of the problem is the high impedence of the input pins once three stated, which produces, with the LCD internal pull ups, a partition with a very high output voltage (close to 5V).
Decreasing the impedence, by turning pins to outputs (as you do when you enable the PMP), or by adding pull down resistors (even if of relatively high values) solves the problem as the partition is modified to produce a lower voltage …
The lesson learned: Once more, make sure that when you interface to a 5V device you either:
- use exclusively pins that are pure digital inputs (5V tolerant)
- use open drain outputs if you want to swing a 5V signal
Watch out from all pins that are multiplexed with analog functions, even if you have the analog function disabled in your particular configuration.
The pin-out cross reference table published in the previous posting “The Missing Pinout Table” might help you double check…
Posted in Tools, Tips and Tricks | No Comments »
The Stack … so misunderstood (continued)
29. February 2008 by pilot.
So we understand now what we don’t know (see The Stack … so misunderstood, part 1). We know how to set a minimum limit for the Stack size. We know how to verify how much space the linker has allocated for a project. We DON’T know how much Stack space our project is actually using!
If we have the luxury of being able to simulate the entire application in a complete and realistic scenario, nothing beats the power of MPLAB SIM. We can open the Watch window and keep an eye on WRGE15 and SPLIM. Opening the Stack window we can watch the stack grow and see each function parameters as they are passed along.
But as the complexity of a project grows, full simulations became less likely… and we want to find a way to identify Stack issues at run time when debugging in circuit.
Quite empirically, if a program is not crashing (as in experiencing inexplicable resets) chances are we have not reached the stack limit (yet). But what if we do experience those resets… in a complex application things can go wrong in many ways … it would be nice to be able to pin-point the issue and make a clear determination when we fail because of the stack.
Here is an example project with a (perverse) recursive function (call()) that will exercise the stack available for as many nested calls as the parameter passed: stack.c
Make the parameter large enough or allocate a large enough Heap (8,000?) and sooner rather than later it will produce a Stack Error trap.
By replacing the default trap handler for the _StackError vector, we could perhaps place a function (with an infinite loop) in there to capture and retain control of the application when things go wrong. Placing a breakpoint inside our custom handler we would be immediately alerted as soon as our program reaches the top of the stack space. Here is an example: stack2.c
Unfortunately the new handler, as any C function, is going to need to use the stack itself. Even if we declare it with the no_auto_psv attribute (to avoid saving and restoring the PSV registers values) and even if we don’t use any local variable.
It seems like a catch 22 condition. We cannot write a handler for a Stack Error condition in C because by definition each C function uses at least a small amount of Stack space.
We might be tempted to artificially lower the stack limit (SPLIM) to allow for some extra room for the handler function so to “break the loop”. But this is just an illusion… We cannot know before hand by how much the stack will be exceeded when the trap occurs. In other words, think of a case where the stack is almost all used up, the stack pointer is just one word below the limit and then a function call is made to a routine that allocates 100 bytes for local variables… To get away with it, we should really lower the stack limit for the worst possible case (the function that allocates the largest amount of stack space) but this is exactly the type of complex and manual analysis of a project we were determined NOT to have to go through in the first place (besides a possible big waste of space).
Fortunately to our rescue comes one powerful option of the MPLAB C30 compiler, that allows us to insert custom code before the prologue of an interrupt handler, that is before the stack is touched! It is called the interrupt preprologue. Here is an example of how we would use it, combined with one instruction of inline assembly to achieve a blocking interrupt handler that does not rely on the stack: stack3.c
void __attribute__((no_auto_psv, interrupt( preprologue(”1: bra 1b”))))
where the “1: bra 1b” is a single instruction infinite loop that we insert before the handler prologue.
But by the time we do this and we try to set a breakpoint on the line, we realize that we have gone full circle. This is not C code anymore… and to set the breakpoint we need to switch to the disassembly window…
If we surrender to the evidence, we get a cleaner, less cryptic and overall more elegant solution by using the original code stack.c and including in our project a simple (three lines long) assembly source code:
.global __StackError
__StackError:
bra __StackError
(Note the double underscore before the label StackError)
Save it as stackhandler.s and add it to the project.
Now we can set a breakpoint inside the new handler and we can have our real time debugger to halt and notify us whenever a Stack Error trap is triggered at run time!
Perhaps we learned a good lesson today. Certain things are just meant to be done in assembly! …although there are not that many left anymore!
Posted in Tips and Tricks | No Comments »
The Stack… so misunderstood
28. February 2008 by pilot.
The stack is such a key element of every C program that too often we take it for granted and we don’t spend enough time to make sure we have it set properly. Most often we resolve to look into it only by the time we notice the code is mis-behaving and by trial and error, among many other things, we finally decide to make some more room for it and see if things improve… There has to be a better way to check and debug our stack allocation strategy.
To start with you need to understand how the linker allocates space for it (where and how much) and how we can control the process.
Considering only the PIC24F architecture (the dsPIC and PIC24H will add a few twists to what follows) the stack is defined by the linker as the largest (and last) block of RAM allocated after everything else has been taken care of…
In the simplest possible situation, starting from the lowest RAM addresses (right after the interrupt vectors tables) you will see the linker placing all your programs (global) variables and those required by the libraries you used. Then you will see the Heap (if any size>0 is defined) and last the stack, using up ALL the memory that remained available. A picture is worth a million words, here is what an example for a simple project using the PIC24FJ128GA010 would look like:
Since the stack of the PIC24 grows toward higher addresses as you use it, the stack pointer (WREG15) is initially set at the bottom of the stack area (__SP) by the C startup code. The stack limit register (SPLIM) is also set at this time to be an address just 8 bytes below the physical end of the memory space. The function of SPLIM is that of triggering a trap when our application reaches the upper limit and runs out of stack space.
The trap mechanism is very similar to an interrupt (of the highest possible priority) that calls a specific vector (_StackError) where we can place a handler routine. The MPLAB C30 compiler places a default handler (just a reset instruction) in each trap and each empty interrupt vector unless otherwise instructed. We can of course define a custom trap handler, but first let’s look at how we can control the amount of space reserved for the stack.
The project Build Options dialog box (select Project>Build Options>Project or click on the Build Options button
) is the obvious place where to look and in particular the MPLAB LINK30 pane:
Here the Heap size and Min. Stack size parameters can be passed to the linker.
Notice that I marked in bold the word Min here, because it is way too easy to simply ignore this detail. In fact while we get full control on the size of the Heap, for the Stack we are given only the option to specify a “threshold” below which the linker will be required to “notify us”. The parameter we select here is NOT the value that will be used by the linker to set the initial stack pointer (__SP or WREG15) and/or to decide where the stack limit (SPLIM) is to be set! As we said above, the linker will first allocate all the other memory “objects” and then assign the largest remaining block of memory to the stack. So in other words, the true stack space size is defined sort of by default, as a result of the combination of all the other project parameters.
When all is said and done, the linker finally looks back and verifies that the size it came up with is larger than the Min Stack Size parameter we set. If it is not we get a compile time error right away. But if there is no error, the stack size could be actually much larger than the minimum amount we asked for.
Note that, probably because of my assembly programming background, this behavior is almost the opposite of the way I used to picture it to be. In my mind the stack size was the one deliberately assigned (just like I used to assign manually my stack pointer in the good old assembly days) and the Heap was supposed to be taking the left overs!
As a side effect of this allocation strategy, and mixing it with my (wrong) initial assumptions, I would like to illustrate a scenario that lead me in the past to considerable trouble and had me quite puzzled for a while.
In my application using both large global arrays and dynamic memory allocation (malloc()) I had the Min. Stack parameter set to 512 bytes and the Heap parameter set to 4,192. The application would run normally under these conditions, but the need for more dynamic memory and a few back of the envelope calculations induced me to think that I could really afford to allocate more space for the Heap (according to my estimates I was using only 1,512 bytes of RAM for my global variables) while keeping the stack safely to the present size. So I did increase the Heap size to 6k bytes, the linker did not complain about any issue with the stack, but the application started immediately behaving erratically producing inexplicable occasional resets.
What was going on?
To my surprise, after a lot of head scratching, I realized that my application was really using almost 1Kbytes of stack space. When the Heap was originally set to 4K bytes the Stack had been allocated as much as 2.5K bytes (8K-4K-1.5K=2.5K). A number larger than the minimum I was requesting.
When I increased the Heap size to 6K, the Stack got squeezed to 512 bytes (8K-6K-1.5K=.5K) still ok according to my request to the linker (notify me if less than 512…) but definitely not enough for the appetite of my application.
It is easy to fall in this trap (pun intended) and assume that since your Build Options are specifying X amount of bytes for the Stack, and your application is not crashing, your stack usage is X bytes or less. The actual amount of stack your application has been allocated and might be currently using could be much larger than the minimum specified. Finding out exactly how much could be quite tricky!
One quick reality check can be easily performed though, courtesy of the MPLAB C30 compiler (default options), you can inspect the build report in the output window Build pane:
Circled in red is the actual stack size that, as you can see in the example, is lager (192) than the amount specified in the project build options (64, see previous picture).
But once more, don’t fall in a “new” trap, the reported “allocated” stack space is not telling us how much of it is actually used by the application!
(to be continued…)
Posted in Tips and Tricks | No Comments »
Watching Expressions
6. February 2008 by pilot.
MPLAB has become such a large application, or I should better say “group” of applications, and it keeps evolving so fast that one can hardly keep up with the pace of monthly (when it is not weekly) updates. Typically before rushing to install a new version I scan quickly through the readme files to see if there is anything new that I could use immediately, otherwise I tend to postpone the update to let it … settle a bit, if you know what I mean.
With MPLAB 8.00 things were different. The PIC32 had just been announced and this was the first new version of MPLAB to openly support it. I was too curious to pass the opportunity and I did the install without paying much attention to what other features had been added. Turns out, I made a mistake because I failed to notice a powerful update to the Watch window capabilities!
Now you can inspect/watch:
- Aspecific element of an array: ar[12]
- An object pointed to by a pointer: *ptr
- An element of a structure/union: str.mbr
- An element of a structure/union via a pointer: p->mbr
- Perform simple math: vrbl-1
- Use constants defined in the program in all of the above: ar[M_SIZE-1]
Just type these simple expressions directly in the watch window in the Symbol Name column
it will work seamlessly allowing you to get a better picture of your… bugs!
Posted in Tips and Tricks, MPLAB 8.00 | No Comments »