# FreeRTOS PIC18 Port using CCS compiler

**URL:** <https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825>\
**Category:** Kernel\
**Created:** [November 22, 2004, 5:48pm UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825 "2004-11-22T17:48:47Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 22, 2004, 5:48pm UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/1 "2004-11-22T17:48:47Z")

</div>

**nobody** wrote on [Monday, November 22, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea):

I am trying to write a PIC18 port using the CCS C compiler.  
Could someone explain me how the functions prvLowInterrupt and prvTickISR in port.c work?

If I can understand how those two functions switch the context and start executing a specific task, I may be able to write a CCS version . Implementing interrups with CCS is totally different that C18 compiler.  
I read the page on the Implementation of FreeRTOS, it helps, but not enough.

A lot of people out there would like a CCS version of FreeRTOS, since CCS is a lot less xpensive than C18.

Please, help me with this port.  
Thanks in advance.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [November 22, 2004, 6:29pm UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/2 "2004-11-22T18:29:32Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Monday, November 22, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/65e7):

Hi,

Ugliest of all the ports&nbsp; primarily because the compiler is not re-enterant so a whole chunk of global memory has to be saved as part of the context switch.

prvLowInterrupt() is the interrupt service routine.&nbsp; The compatibility mode is used meaning that only one interrupt priority exists.&nbsp; prvLowInterrupt() simple polls all the peripherals that could have caused the interrupt and call the appropriate ISR routine.&nbsp; It first checks to see if the interrupt was caused by the timer&nbsp; and if so calls the Tick ISR, it then checks to see if it was caused by a character Rx and if so calls the serial port Rx interrupt&nbsp; etc.

prvTickISR() is the function that implements the tick ISR (strangely), it is called by prvLowInterrupt() when the interrupt was generated by the timer.

prvTickISR() follows the same sequence as all the tick ISRs in all the ports, namely:

-&nbsp;&nbsp;&nbsp; Save the current context  
-&nbsp;&nbsp;&nbsp; Call vTaskIncrementTick() which checks to see if any tasks are woken by the tick ISR.  
-&nbsp;&nbsp;&nbsp; If the preemptive scheduler is being used, vTaskSwitchContext() is called to switch to the highest priority task that is ready to run.&nbsp; If the preemptive scheduler is not called this step is skipped as a context switch can only be caused by a call to portYIELD().  
-&nbsp;&nbsp;&nbsp; Finally restores the current context&nbsp; which may be different to the context saved if vTaskSwitchContext() switched in another task.&nbsp; This way the ISR will return to the highest priority task.

The tricky bit is the saving and restoring of the context which is very C18 specific.&nbsp; The compiler uses two of the indirect memory registers as stack pointer and frame pointer.&nbsp; Therefore the POSTINC0 calls is effectively pushing variables onto the stack.

1) First some registers are pushed so they get stored in their original state&nbsp; these get modified in the next step so this must happen first.

2) Next the interrupt status flags are stored&nbsp; this is what causes the registers to get modified in step 2.

3) Next all the other necessary CPU registers are stored.

4) Followed by the global memory regions used by the compiler (.tempdata and MATH\_DATA sections&nbsp; yuk).

5) Next the hardware stack is saved onto the software stack.

6) The size of the hardware stack is variable, so following the hardware stack values, the number of values pushed onto the stack also gets stored.

7) Finally the new stack top is saved into the TCB.

Hopefully this will help you follow the comments in the code.&nbsp; As I said though this is very specific to the C18 compiler.&nbsp; This is also the trickiest of all the ports.&nbsp; It may be helpful to get the evaluation version of the C18 compiler and step through the code to help understanding.

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 25, 2004, 11:53pm UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/3 "2004-11-25T23:53:08Z")

</div>

**nobody** wrote on [Thursday, November 25, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/b0e5):

Thanks a lot for your help. You almost wrote a book. Your comments were a precious help. I was able to get the scheduler running on the CCS compiler. I am still working on it. The CCS malloc and free functions really suck. They work properly on certain conditions, not all the time. So I am working on how to handle memory management. Thank you again.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 26, 2004, 9:22am UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/4 "2004-11-26T09:22:34Z")

</div>

**nobody** wrote on [Friday, November 26, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/b0e5/6219):

There are some basic memory management routines included in the download.&nbsp; May be good enough for what you want.

[http://www.freertos.org/a00111.html](http://www.freertos.org/a00111.html)

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 15, 2004, 1:49am UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/5 "2004-12-15T01:49:00Z")

</div>

**nobody** wrote on [Wednesday, December 15, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/1505):

hello  
&nbsp;&nbsp; Thanks for Richard - richardbarry&nbsp; and&nbsp; Nobody/Anonymous - nobody&nbsp; for&nbsp;&nbsp; detailed description of porting&nbsp; 18f452 using ccs complier.Ii am a baby to this. I like to port this&nbsp; to pic 16f877 Is it possible?  
Pl give reply sir

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [December 15, 2004, 6:44am UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/6 "2004-12-15T06:44:29Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Wednesday, December 15, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/1505/2b4d):

Unfortunately I dont think this is really feasible with the tiny on board memory available.&nbsp; Also the current port uses some instructions/modes only available on the PIC18 series.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 16, 2004, 1:01am UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/7 "2004-12-16T01:01:11Z")

</div>

**nobody** wrote on [Thursday, December 16, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/6b68):

By: Richard - richardbarry  
RE: FreeRTOS PIC18 Port using CCS compiler&nbsp;&nbsp;  
2004-11-22 10:29&nbsp;  
Hi,

Ugliest of all the ports&nbsp; primarily because the compiler is not re-enterant so a whole chunk of global memory has to be saved as part of the context switch.

what is re-enterant can u explain

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [December 16, 2004, 8:58am UTC](https://forums.freertos.org/t/freertos-pic18-port-using-ccs-compiler/3825/8 "2004-12-16T08:58:38Z")

</div>

**nobody** wrote on [Thursday, December 16, 2004](https://sourceforge.net/p/freertos/discussion/382005/thread/a7582be8/#15ea/6b68/06a3):

Here is a small text:

[http://en.wikipedia.org/wiki/Reentrant](http://en.wikipedia.org/wiki/Reentrant)

It means basically that functions can be shared by different processes (inc interrupts).

If a function places all it’s code on the stack then different tasks can call the same function and each will use different memory.&nbsp; For example:

int Calculate( int in1, int in2 )  
{  
&nbsp;&nbsp;&nbsp; int temp;

&nbsp;&nbsp;&nbsp; temp = in1;  
&nbsp;&nbsp;&nbsp; temp += 2;

&nbsp;&nbsp;&nbsp; return temp;  
}

Here temp is on the stack.&nbsp; Now if one task Calculate it will use a local stack copy of temp.&nbsp; If the task gets swapped out and another task runs, then it too calls Calculate it will have its own copy of temp also.&nbsp; This means that it will not corrupt the temp used by the first task.&nbsp; This function is reentrant.

Instead -

int Calculate( int in1, int in2 )  
{  
&nbsp;&nbsp;&nbsp; static int temp;

&nbsp;&nbsp;&nbsp; temp = in1;  
&nbsp;&nbsp;&nbsp; temp += 2;

&nbsp;&nbsp;&nbsp; return temp;  
}

Here temp is static so is not on the stack.&nbsp; Each task that calls Calculate will use the same temp variable.&nbsp; If more than one task calls temp at the same time then temp will corrupt.&nbsp; This function is not reentrant.
