problem with freertos-pic24 and hd44780 lcd

blackflowers wrote on Friday, July 15, 2011:

hi there!, I’m trying to run an lcd with a pic24hj and freertos. I’m using the sourcecode
provided with the freertos project for pic24h.I have the harware connected (let’s suppose everything is right, since i have checked out several times)
But it doesn’t work, besides it’s very difficult to debug a project with an lcd.
The “main” code it’s here, i don’t know wether i’m doing it wright or not.

**int main( void )
/* Configure any hardware required for this demo. */

/* Start the task that will control the LCD.  This returns the handle
to the queue used to write text out to the task. */
xLCDQueue = xStartLCDTask();
//xQueueSend( xLCDQueue, “hola”, portMAX_DELAY );

/* Finally start the scheduler. */

/* Will only reach here if there is insufficient heap available to start
the scheduler. */
return 0;

I commented the xQueueSend line since the very first task it need to do is to init the lcd and it seems that it’s not doing it at all, so i don’t even
try to send data to the lcd.
Apart from this, i have three questions:
1- xLCDQueue = xStartLCDTask(); Is this function supposed to init the lcd?
2- Which of those functions do i use for writting to the lcd; **xQueueSend( xLCDQueue, “hola”, portMAX_DELAY ); **or prvLCDPutString( “” );
3- Which is the clock source for the freertos? is it the internal rc oscilator?

thanks i wish i could at least check if there are any mistake, thanks!!

rtel wrote on Friday, July 15, 2011:


But it doesn’t work, besides it’s very difficult to debug a project with an lcd.



i don’t know wether i’m doing it wright or not.

It is difficult to say, as I don’t know what it is you are trying to do.  I would say, however, that un-commenting the call to xQueueSend() would be a *very* bad idea, as at that point you cannot cause the running task to block, as there are no tasks, and a context switch cannot be performed, again because there are no tasks and the scheduler has not yet been initialised/started.  If you want to send a message to a queue, then it is safest to do it after the scheduler has started, from a task.  The xQueueSend() function is designed to execute in a task.


xLCDQueue = xStartLCDTask(); Is this function supposed to init the lcd?

Umm.  I don’t know.  Look at its implementation and step through its code.  Then you will know, and I still won’t.


2- Which of those functions do i use for writting to the lcd; xQueueSend( xLCDQueue, “hola”, portMAX_DELAY ); or prvLCDPutString( “”; );

Again - I don’t know, but probably either - but only when the kernel is running.  Have you looked at the code you are trying to run?  Without doing that, or knowing what it is supposed to do, then you won’t know if it is doing it or not.  If this code is based on the officially supported FreeRTOS demo then I would recommend starting with the demo unmodified - it should build and run without any problems and allow you to inspect its behaiour using a debugger (and reading the documentation for it will tell you what it is supposed to be doing).


3- Which is the clock source for the freertos? is it the internal rc oscilator?

Look at the function prvSetupTimerInterrupt() in port.c.


blackflowers wrote on Friday, July 15, 2011:

thanks for answering all my doubts. I know i have to check out more deeply in the freertos sourcecode. On the other hand it’s difficult to find specific documentation and examples for an specific device. It would be a good idea, as you have said,  try the original example of the code, but it’s intended to run in a explorer16 and i haven’t got it.


blackflowers wrote on Friday, July 15, 2011:

i’m about to give up freertos, since it only makes things more difficult, and i can’t see the advantages.

blackflowers wrote on Friday, July 15, 2011:

it’s really difficult since i can’t find out the clock configuration.

edwards3 wrote on Friday, July 15, 2011:

If I am following this thread, then you are right. Trying to use code to initialize your own hardware without looking at the code first is difficult. Impossible even. It is not easy when you look at the code. Using a driver written for one hardware configuration with another hardware configuration without even knowing where the initialization is done is as about as hard as it gets.

3- Which is the clock source for the freertos? is it the internal rc oscilator?

Look at the function prvSetupTimerInterrupt() in port.c.

it’s really difficult since i can’t find out the clock configuration

Following the clues provided, I have just looked at prvSetupTimerInterrupt() in port.c and see

static void prvSetupTimerInterrupt( void )
const unsigned long ulCompareMatch = ( ( configCPU_CLOCK_HZ / portTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1;
	/* Prescale of 8. */
	T1CON = 0;
	TMR1 = 0;
	PR1 = ( unsigned short ) ulCompareMatch;
	/* Setup timer 1 interrupt priority. */
	/* Clear the interrupt as a starting condition. */
	IFS0bits.T1IF = 0;
	/* Enable the interrupt. */
	IEC0bits.T1IE = 1;
	/* Setup the prescale value. */
	T1CONbits.TCKPS0 = 1;
	T1CONbits.TCKPS1 = 0;
	/* Start the timer. */
	T1CONbits.TON = 1;

I guess it is using timer 1, but there is always a possibility the comments in the code are misleading.

blackflowers wrote on Friday, July 15, 2011:

i finally get it working, but i can’t understand your explanation about the clock configuration. I know that freertos it’s using timer1 for some kind of clocking but, it needs a clock source even for getting timer1 working, and this clock configuration is the one i need, because this example is using parallel master port to comunicate with lcd. And so, it can’t be driven by the timer1 because i suppose that parallel master port it’s driven by the microcontroller clock directly.
It was not neccesary to change anything on the original code, i have only modified the fuses configuration. In mplab i unchecked the “Configuration Bits set in code” option, and changed two fuses:

FNOSC-> Fast RC oscillator
OSCIOFNC-> OSC/OSC2 General purpose I/O pin

And with this only code in the main function the lcd shows the message “

int main( void )
xLCDQueue = xStartLCDTask();
return 0;

richard_damon wrote on Saturday, July 16, 2011:

First, copying and putting together pieces without looking at the documentation or understanding what they do is a good way to get yourself lost.

Second, you need to understand the difference between what is FreeRTOS itself, and what you find as sample code in demonstration code. The FreeRTOS Kernel has no code to run an LCD, all the code that manipulates the LCD is just demonstration code. Note that the demonstration code will also be documented with what the hardware setup should be, and you are responsible for understanding how to make changes if your system is different. It is also important that you understand how the microprocessors work.

On that latter point, you show a decided confusion on your 3rd question. FreeRTOS itself doesn’t do ANYTHING about the clock configuration of the processor. It is the users program responsibility for configuring this to meet their needs. FreeRTOS doesn’t care how this is set up, all it needs is a define in FreeRTOSConfig.h to tell it what frequency the system is running at, and only uses that the set up the timer for the desired tic rate. The Demo programs of course need to set this up, as they are full programs, but different demos may actually set it up in different configurations. FreeRTOS does have code to set up the timer for the tick (using timer1 on 16 bit PICs in the standard port code) as part of its portable layer.

As a matter of principle, I strongly suggest you don’t just uncheck the “Configuration Bits set in code option” and override the code with the menu options. If you wish to use the menu options, please remove the statements in the code that set these option different than you want. It would be even better to change the code to reflect the options you desire, and that way the code is better documented. (Note that you should find some macro calls to _FOSC and _FOSCSEL that setup the clock configuration).

If this is your first programming experience on this processor, and your first use of FreeRTOS, than maybe it would be worth slowing the learning curve, and first bringing up a “toy” version a program that just sets up the hardware and does some simple demo without using FreeRTOS, then upgrade that program to use FreeRTOS, and then add your real functionality. The PIC24 is actually a somewhat complicated processor depending on how many of the peripherals you will be using, and just blindly copying demo code that uses those devices is unlikely to really meet your needs. In fact, the documentation for the various demo code points out that the way it does some things is likely sub optimal for many applications, as it was coded more to be an example of techniques, and not highly efficient code.

blackflowers wrote on Saturday, July 16, 2011:

thanks richard for your explanation, i’m obviously newbie with freertos and i’m just learning. I think it’s a very interesting tool to develop bigger projects.
About what you have said about changing the fuses configuration in the code… i tryed to do so but i couldn’t find the way for configuring _FOSC and _FOSCSEL in the code. I made a search with this two words and this is what mplab found in files:
with the key _FOSC:
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:38: __FOSCSEL = 0xF80006;
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:39: __FOSC = 0xF80008;
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:160:   __FOSCSEL :
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:161:   { *(__FOSCSEL.sec)    } >FOSCSEL
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:162:   __FOSC :
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:163:   { *(__FOSC.sec)    } >FOSC
Search complete. 6 matches found.

with the key __FOSCSEL:
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:38: __FOSCSEL = 0xF80006;
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:160:   __FOSCSEL :
E:\FreeRTOS\Demo\PIC24_MPLAB\p24HJ128GP502.gld:161:   { *(__FOSCSEL.sec)    } >FOSCSEL
Search complete. 3 matches found.

¿So, where is it possible to change the __FOSC configuration?** I’m not sure but i’m affraid i can’t change the fuses configuration in .gld file. Besides, i can’t see anywhere the __FOSC configuration for this project.

richard_damon wrote on Saturday, July 16, 2011:

The gld files just define where the hardware is looking for the signals, so that isn’t where you want to make the changes.

I haven’t used those demos, but I suppose it is possible that they used the config options to set the fuses, which demonstrates why I suggest you not do it, If you didn’t start your program from the demo project file (and not just the source code), you will quietly miss these settings. 

If you want to change to using the configuration macros, there is documentation for them in the microprocessor include file (p24HJ128GP502.h) in the microchip compiler directories. To understand this, you should also read and understand the device datasheet, which will define the real meaning of all the bits.

blackflowers wrote on Saturday, July 16, 2011:

ok, I already know how to set the fuses by software. I suppose i can add this fuses configuration to the FreertosConfig.h. I think is the better place for doing it.

kind regards.

rtel wrote on Saturday, July 16, 2011:

Those demos are very old, and from memory set the fuses through the MPLAB menu.  The PIC32 demos, being newer, use #pragmas in main.c to perform configuration.  I’m not sure what would happen if you set them in the source code and through the IDE, so I suggest disabling the IDE from attempting to do the configuration if you add it to the source manually.  I don’t know, but would guess, that FreeRTOSConfig.h would not be the best place to put the definitions as they would be included from all the kernel files, and any file that made use of the FreeRTOS API.  When I have done this before I have just added them to the top of main.c.


richard_damon wrote on Saturday, July 16, 2011:

As the macros generate code, they should not be put in a header, I would suggest the file with main, or if you put the initialization code in different file, that one.

What the macros generate are global variables with attributes to get them loaded into the right place in memory to set the configuration fuses.

blackflowers wrote on Sunday, July 17, 2011:

ok, thanks.