qft0 wrote on Saturday, December 20, 2008:
OK, this story is a bit long, but maybe it will generate some enlightening discussion. Sooooooo…
Good call on the ADC register. I’m surprised the demo didn’t handle this correctly. Sounds like you’re making good progress though. I don’t understand why Microchip set up the PIC18 series to enable the ADC on reset. I’ve been burned by this enough times that I put it in all my application templates as a warning-to-self.
I stopped at rtosdemo1 because I think the heap_1 option is the best for the PIC. I started to construct a simple app by gutting demo1 and adding my own stuff. I enabled the idle_task_hook in freertosconfig.h, and added a simple LED flasher for the idle task hook function. It rasters back and forth on the RB1/2/3 LEDs. This worked perfectly, but I had to reduce the heap size to accommodate two static variables in the function. It calls the LED toggle function above, so there’s only three or four lines to it. This seems like a snug fit.
I also tend to pay the price up front and construct an old-fashioned makefile so I can build the application from a command shell. I find this is faster, easier to control and manage, and extendable to other processors. I also like being able to build multiple applications from one makefile. I did this with the rtosdemo1 program, and ended up figuring out quite a bit about where all the pieces of FreeRTOS live, and their dependencies.
Since I’m really evaluating just how far I can go with the RTOS, I wanted the fastest possible clock, so I pulled the 4MHz oscillator, added a 10MHz crystal, and enabled the PLL (10MIPs…me likee).
A small warning if you do this: Open up the serial.c file, and modify the baud-rate configuration to use a 16-bit divisor (it’s currently only 8-bit). When Fclk=40MHz, the divisor comes out to 259, and you lose the upper byte so the serial port ends up running at the wrong speed.
Today I received some samples of the 18F4620. This is a nice upgrade, twice the ROM and more than twice the RAM. Now there will be room for an application
I have an LCD library I wrote several years ago for the FEMA display on the PICDEM2+ (most character displays have indentical interfaces). This was before Microchip made their xlcd library available. I actually found mine worked much better than theirs (boy did I try to make theirs work for me). It works perfectly with my test app and several other previous applications . I compiled the library with the same options as the stock rtosdemo1. I even wrote 0x0f to ADCON1 to ensure the ADC doesn’t get in the way. It’s killing me
If I initialize the display and send “hello world” before starting the OS, then just do a while(1); I get nothing on the display. Since I know the RTOS isn’t running, and I’m just sitting in a tight loop, it can’t be something in the RTOS, and there’s no hardware reason I can think of why it shouldn’t work.
I tried stepping through the assembly code, and it looks like pointers to the text strings (in ROM space) are getting lost, suggesting a compiler issue. I hate suggesting this, because it’s almost always wrong. I’m still working on this one.
Moving on to what I think is a more serious issue, I’ve never been able to get a satisfactory answer to the question of how we get away with combining the RAM sections in the linker command file. This is a big issue to me. The linker manual is pretty clear on this:
"You must not combine data memory regions when using MPLINK linker with MPLAB C18 C compiler. MPLAB C18 requires that any section be located within a single bank. See MPLAB C18 documentation for directions on creating variables larger then a single bank."
Since we violate this rule in order to have a great big fat heap, it bears checking. The C18 manual has directions for creating pointers that can span sections, but if you allocate space for a structure or a small array from the heap, and it happens to fall across a bank boundary, your application will fail to operate reliably (if at all). The linker command file does not protect the big section for exclusive use by the heap, so out of the box, the stack, heap and global variables are all in this big block of RAM. Can anyone explain how we get away with this? Is it just a roll of the dice? We take it on trust that no variable will ever span a 256 byte bank boundary?
There is a note in the FreeRTOS documentation about this, by a user named John Franklin. He had an application fail to run because of this problem. His solution was to create a protected multi-bank space for the heap, and put the stack in a separate bank too. This still doesn’t guarantee a large variable, structure or array won’t span a 256 byte boundary. I think it just moved his
I’ve asked about this on the Microchip forums too, no takers so far.
Well, that was a mouthful.