PIC MPLAB port for 18f4520

First time to FreeRTOS.  Targeting PICDEM2PLUS board with 18f4520.  Using rtosdemo1.mcp to toggle some LEDs.  I am getting a linker error as follows: MPLINK 4.21, LinkerCopyright (c) 2008 Microchip Technology Inc.Error – section ‘.udata_heap_1.o’ can not fit the section. Section ‘.udata_heap_1.o’ length=0x00000604 If I change the FreeRTOSconfig.h file from the default TOTAL_HEAP_SIZE of 1024 to 1536, I get the length as reported above.  1024 setting gives 0x404 as the length.  Everytime, 4 bytes larger than the total heap.  What is happening?

PIC MPLAB port for 18f4520

You need to change the linker script to include one large block of memory big enough for the heap to fit. Look at the linker script in the project files as example.

PIC MPLAB port for 18f4520

Thank you.  That was correct and I went back to find it in the docs as well.  I have the board up now but a strange result in LED toggling is getting me.  The following LED test routine does toggle the LEDs but instead of toggling one at a time, it toggles all so that only one is set at a time.  e.g. RB0 is set, then RB1 is set but RB0 gets cleared, etc.         switch( uxLED )         {             case 3    :    PORTBbits.RB3 = !( PORTBbits.RB3 );                    // Same changes as above                         break;             case 2    :    PORTBbits.RB2 = !( PORTBbits.RB2 );                         break;             case 1    :    PORTBbits.RB1 = !( PORTBbits.RB1 );                         break;             case 0    :    PORTBbits.RB0 = !( PORTBbits.RB0 );                         break;             default    :    /* There are only 4 LED’s. */                         break;         } I expect: set RB0, RB1, RB2, RB3, clear RB0, RB1, RB2, RB3

PIC MPLAB port for 18f4520

Update: it appears to be correctly compiling to toggle a bit.  Here is the assembly: 141:                           case 1    :    PORTBbits.RB1 = !( PORTBbits.RB1 );   423C    7281     BTG 0xf81, 0x1, ACCESS That toggle clears all other bits on the port.  Another observation is that the MPLAB only reads back 0x00 on PORTB.  LATB reads correctly as only one bit set at a time.

PIC MPLAB port for 18f4520

Funny, I’m doing the same thing, same processor, same board.  The 18f4520 only has 1536 bytes of ram to begin with.  If you allocate it all to the heap, it could be tough to successfully build. :) The extra four bytes are a mystery to me too.  I ended up putting the heap size down to 796, as anything I added to the example would run out of available ram space at link time. The code you’ve shown doesn’t explain how you’re lighting up the four LEDs.  If you called the LED toggle function four times passing it 0,1,2,3, they should all be on, assuming they were all off to begin with.   If you call it twice each time, 0,0,1,1,2,2,3,3, the behaviour should match your description of what’s happening. With the LATB register, the description sounds right, as you’re reading the contents of the output latch, not the port pin itself.  Writing to LATB or PORTB puts data in the output latch, doesn’t matter which one you write to.  Is it possible you have something else going on?  Perhaps the J6 jumper is not installed?  If you modified the ParTest.c file, did you change the TRISB settings to match the PICDEM2 board?

PIC MPLAB port for 18f4520

ICJ, The rtosdemo1 does run.  Not sure if I am out of memory already.  The ParTest.c was updated for the correct TRIS settings.  Again, the LEDs light but the BTG 0xf81 0x01 causes LED1 set but clears any other set bits.  Very strange. I can send 0x0f to PORTB and light all LEDs.  

PIC MPLAB port for 18f4520

OK, the problem was that ADCON1 was not set correctly for all pins to be digital I/O.  It now works as expected.  Issue closed.

PIC MPLAB port for 18f4520

ICJ, The rtosdemo1 does run.  Not sure if I am out of memory already.  The ParTest.c was updated for the correct TRIS settings.  Again, the LEDs light but the BTG 0xf81 0x01 causes LED1 set but clears any other set bits.  Very strange. I can send 0x0f to PORTB and light all LEDs.  

PIC MPLAB port for 18f4520

ICJ, I have demos 1 and 2 running.  Linker file needed BIG_BLOCK setting of 1024 for total heap.  Maximum memory is allocated but I can not tell what is used.  Program memory is 50% used in both cases. Demo 3 is not working.  When I run with no loopback, I get LEDs 2 and 3 blinking repeatedly and fast.  I assume it is the receive error and the transmit success.  When I loopback, I get a continual reset that I can’t explain.  Did you get this far?

PIC MPLAB port for 18f4520

ICJ, I have demos 1 and 2 running.  Linker file needed BIG_BLOCK setting of 1024 for total heap.  Maximum memory is allocated but I can not tell what is used.  Program memory is 50% used in both cases. Demo 3 is not working.  When I run with no loopback, I get LEDs 2 and 3 blinking repeatedly and fast.  I assume it is the receive error and the transmit success.  When I loopback, I get a continual reset that I can’t explain.  Did you get this far?

PIC MPLAB port for 18f4520

Duncan, 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. Cheers, Lawrence

PIC MPLAB port for 18f4520

Lawrence, Thank you for the detailed response.  I am new to the RTOS and hoped it would solve more problems than it creates.  I have an application that needs long time counting (e.g. act every 30 sec., 1hr,  24hr. etc.  I really need to be multi threaded so I can have these long waits in simple tasks.  I can’t figure out how to do it in a single thread. Let me try to respond to your points. ADCON:  I was so pissed that there was no documentation to provide a kick-off for programming.  It would have saved me a week or more to know that the default for IO was analog!!!  That was buried in the spec sheet.  I had words for the course instructor after that was discovered.  It still bites because it’s symptoms are so odd, not a clean failure. Memory:  I did not pay attention to the memory management after demo1 so I did not notice if it changed.  I’ll have to look again.  One big heap is fine for me as I will not create and destroy threads dynamically, or so I expect.  But being in conflict with the compiler is not good.  I am curious as to what Microchip will say.  Did you ask the 24/7 support group? Serial:  I could not get 57600 working in the demo at 4MHz.  I just drop down to 9600 to get by.  Goal is to get USB working some day. 4620:  Is it 2x the price too? LCD:  Lord above, it has been a stupid arrangement.  XLCD with 2000 line .h files???  Does not support the power control line on PICDEM2+!!!!!!!  I have tried XLCD, the C18 library routines (worst) and my own.  I now have a hybrid that works on a board of my design but when it started working, I was not sure of the solution.  I know I will have problems again.  Is it display or timing???  No idea.  I loop 32 characters to the 2×16 to prove it works.  LCD boot timing seems to be the most sensitive so once that works, the writes are fairly reliable.   If it does get lost, it can’t come back. Memory management:  If what you say is true, it is a show stopper. Have you tried the uC/OS-II?  I may give that a try if I feel this is too shaky.  I am not wed to Microchip but free IDE and C compiler keep me putting up with ADCON and the like.  My email is first dot last at gmail if you want to share more. Regards, Duncan

PIC MPLAB port for 18f4520

Duncan, Just in case anyone else is curious, I’ll respond here.  I’ll send you an e-mail later. Memory: I never asked the support group at Microchip, because the RTOS is not theirs to support.  I doubt they’d offer much help on this.  I had hoped we could entice somebody on this forum to clear the issue up.  I’ll file a support request and see if they have any comments on it. Serial: 57600 is a little tough when running at 1MIPs.  It’s not that the processor can’t do it, it’s that it can’t get the speed quite right.  You’d be better off running the processor at a frequency that divides nicely into 57600.  The way serial.c has it configured, you will actually get 62500 baud.  This might be off by too much to work reliably with other hardware. 4620: The price is about 25% more than a 4520. XLCD: :) Glad it’s not just me that thought it was poorly executed.  If it takes you longer to work with this library than to write your own, need we say more?  You are right though, it’s all in getting the reset function to work properly.  If you don’t reset properly, it will never work.  I had the toughest time figuring out the fastest timing for communication with the LCD.  The datasheet gives some reset timings assuming the LCD is running at maximum clock frequency, but doesn’t say what the frequency of operation actually is.  It also doesn’t give anything useful like setup and hold times for latching data into the chip.  I digress… Memory Management: Anyone? Please tell me I’m wrong and explain how this will work reliably? Cheers, Lawrence

PIC MPLAB port for 18f4520

>I had hoped we could entice somebody on this forum to clear the issue up. Sorry but I have not been following the thread so don’t know which issue you are referring to.  Could you re-state it in as few words as possible in a new post to prevent me having to read through all the list.  If its FreeRTOS related I will try and answer it, if its specific to any particular PIC18 peripheral then you might be on your own :o) Regards.

PIC MPLAB port for 18f4520

Duncan, Just in case anyone else is curious, I’ll respond here.  I’ll send you an e-mail later. Memory: I never asked the support group at Microchip, because the RTOS is not theirs to support.  I doubt they’d offer much help on this.  I had hoped we could entice somebody on this forum to clear the issue up.  I’ll file a support request and see if they have any comments on it. Serial: 57600 is a little tough when running at 1MIPs.  It’s not that the processor can’t do it, it’s that it can’t get the speed quite right.  You’d be better off running the processor at a frequency that divides nicely into 57600.  The way serial.c has it configured, you will actually get 62500 baud.  This might be off by too much to work reliably with other hardware. 4620: The price is about 25% more than a 4520. XLCD: :) Glad it’s not just me that thought it was poorly executed.  If it takes you longer to work with this library than to write your own, need we say more?  You are right though, it’s all in getting the reset function to work properly.  If you don’t reset properly, it will never work.  I had the toughest time figuring out the fastest timing for communication with the LCD.  The datasheet gives some reset timings assuming the LCD is running at maximum clock frequency, but doesn’t say what the frequency of operation actually is.  It also doesn’t give anything useful like setup and hold times for latching data into the chip.  I digress… Memory Management: Anyone? Please tell me I’m wrong and explain how this will work reliably? Cheers, Lawrence

PIC MPLAB port for 18f4520

Richard, As few words as possible?  What are you trying to say? :) I think I may be on my own, but here’s my issue.  John Franklin’s attempt to solve this problem is in the FreeRTOS doc’s along with a link to his solution.  I don’t see how his solution can work, and suspect that it worked for him by fluke.  This, I hope, means I don’t understand it, not that it won’t work. The issue is specific not to PIC18 peripherals but to the PIC18’s internal RAM.  Memory is organized in 256 byte banks.  The manual for the linker (MPLINK, not the C18 compiler) specifically says not to combine banks as the compiler won’t generate code that can navigate across a bank boundary.  For instance a 32-bit variable might live at 0x1fe:0x201. Here’s what I’m hoping for:  If you must combine banks into a large section, you can protect the space (use PROTECTED keyword in linker command file) and allocate it to the heap with the right #pragma directives and section assignments wrapped around said heap declaration.  This will allow pointers and arrays to grow past 256 bytes with proper addressing. Where I see it going pear-shaped is that the heap is not a single array, but a space into which variables are allocated.  If this is the case, I can’t see how this will ever work, other than by providence.  Is there something I don’t get about how space is allocated to variables on the heap?  I’m really struggling to understand this. OK, so I failed to keep it short, it’s not that easy of a problem to explain. Lawrence

PIC MPLAB port for 18f4520

Ok well I can’t really help on the vagaries of the PIC18 tools, but I can maybe help on explaining the memory allocation. The heap is only used when a task, queue or semaphore is created.  It is used to hold the task/queue/semaphore data structures and to hold the task stack.  The data structures are small enough to be able to fiddle to get within the required block.  The stack would be a bit more tricky.  The compiler will allocate things to the stack in just the same way as it would normally, so presumable there is some rule that says as long as the stack is configured in some particular way (maybe starts on a 256 boundary) then the compiler will always allocate variables on the stack safely. Most small embedded apps will allocate all the tasks and resources before the scheduler started, so dynamic memory allocation is not really required.  You could at a push provide your own implementations of pvPortMalloc() and vPortFree() that just returned statically declared blocks of memory in response to requests.  Sorry to not be of more help.  The architecture is tricky, as are the tools. Regards.

PIC MPLAB port for 18f4520

Thanks Richard, Too  bad the compiler can’t handle this more gracefully. As to the stack, it’s actually much less of a problem.  The linker command file can allocate more than one bank to the stack without a problem, and can handle putting the stack in a protected space all on its own.  Odd that there is a special provision for the stack but not for more general use. Lawrence