Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 18, 2005
Hello,

I'm running into some trouble, trying to get freertos running on a pic18F8525.

First: the program restarts over an over again. I found out that the (hardware) stack overflow bit was set after a reset, so there is definitely something wrong.

In one situation I noticed that when restoring the first task to run (in startScheduler) the restored INTCON had the global interrupt bit diabled!, so I guess something is wrong in saving or restoring process context.

Secondly, when I enabled debugging, I received an error message stating that the hex file format wouldn't allow addressing beyond 64kbytes. Since the ROM is only 48kbytes, this should not be a problem. enabling the suggested INHX32 format 'solves' this problem, but I'm concerned the program is now stored partly in non-existent memory.

The stack is also not clear to me.
Is there a hardware stack, a software stack and a freertos context stack?
Otherwise I do not see how you fit so many tasks which each require portMINIMAL_STACK_SIZE (105 according to portmacro.h , 0xa5=165 according to the FAQ:how big should the stack be, which is it?) into the software stack defined in the linkerscript (0x60 bytes)

I understand the RAM should be defined as 1 continuous block in the linker script?, in order to be able to keep the process context stack?

Greetings

Paul van der Hulst

RE: Trying and failing on a pic 18f8525

Posted by Richard on January 18, 2005

> I'm running into some trouble, trying to get freertos running on a pic18F8525.
>
> First: the program restarts over an over again. I found out that the (hardware)
> stack overflow bit was set after a reset, so there is definitely something
> wrong.

Sorry to state the obvious - but have you disabled the hardware watchdog if there is such a thing on the 18f8525?

The 8525 has more RAM than the 452 - on which the port was produced - so we should be able to get it running.

If you are not already doing so then... to start with just try getting a hello world type application running - create a single task that flashes an LED for example - using the cooperative scheduler (set portUSE_PREEMPTION to 0) is also a good idea at the start as it makes stepping through the code much easier.


> In one situation I noticed that when restoring the first task to run (in
> startScheduler) the restored INTCON had the global interrupt bit diabled!, so
> I guess something is wrong in saving or restoring process context.

If this is the first task to execute then this is very strange. When the task is created a chunk of memory is grabbed for the task stack, and the initial stack is setup. When the task starts it restores it's stack from that memory so if it is being restored with a value other than 0xc0 in INTCON then either the memory has been corrupted prior to the task starting - or memory was never allocated in the first place.

Have you checked the return value of sTaskCreate() when you create your task?


>
> Secondly, when I enabled debugging, I received an error message stating that
> the hex file format wouldn't allow addressing beyond 64kbytes. Since the ROM
> is only 48kbytes, this should not be a problem. enabling the suggested INHX32
> format 'solves' this problem, but I'm concerned the program is now stored partly
> in non-existent memory.

Check the .map file - this will tell you if this is the case. I doubt there is a problem otherwise you would expect linking to fail but you never know.

>
> The stack is also not clear to me.
> Is there a hardware stack, a software stack and a freertos context stack?

Each task maintains it's own software stack space - but while executing the compiler uses the hardware stack also. When a task is switched out the hardware stack is copied onto it's own software stack to prevent it getting clobbered by the next task. Likewise when the task starts again it copies the saved hardware stack values from the software stack back onto the hardware stack.


> Otherwise I do not see how you fit so many tasks which each require
> portMINIMAL_STACK_SIZE (105 according to portmacro.h , 0xa5=165 according to
> the FAQ:how big should the stack be, which is it?)

The value of portMINIMAL_STACK_SIZE is actually different for every port - hence it's location in the portmacro.h file. Maybe this needs to be made clearer in the FAQ.


If you are still having problems with a simple hello world type program then maybe I can give it a go in the MPLAB simulator.

Regards.

RE: Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 18, 2005
Hello,

Thanks for your fast reply.

Yes, the watchdog timer is disabled. I think this would result in a constant restarting rate, since I don't think the watchdog is cleared anywhere. Anyway, the restarting frequency changes very erratic with the slightest change in the program.

For debugging I now have this nice task running:
void Task2 (void *pvParameters)
{
for ( ;; )
{
_DRIVE2=1;
Nop();
_DRIVE2=0;
Nop();
}
}
(_DRIVE is defined as a port output)
And I have cooperative on now.
I'll be working on this since it runs for about a second and then stops.
Global interrupt is on now, the first time the program enters Task2

The first call to portRESTORE_CONTEXT(); puts me in prvIdleTask, not task 2. Is this correct?
(task 2 has tskIDLE_PRIORITY)

CreateTask returns 1, so that's ok

The .map file says:
Program Memory Usage
Start End
--------- ---------
0x000000 0x000005
0x000008 0x003ad7
0x300001 0x300003
0x300006 0x300006
15066 out of 50200 program addresses used, program memory utilization is 30%

so that seems ok too

I'll be stepping through this code first thing tomorrow

Greetings,
Paul van der Hulst




RE: Trying and failing on a pic 18f8525

Posted by Richard on January 18, 2005
>The first call to portRESTORE_CONTEXT(); puts
>me in prvIdleTask, not task 2. Is this correct?

This is just a quirk of having no tasks above priority 0. The idle task is the first to get created.

RE: Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 19, 2005
Good morning,

I made the changes you suggested. (no pre-emption and only 1 task)
the map file says:
MATH_DATA udata 0x000000 data 0x000010
.tmpdata udata 0x000010 data 0x000004

so the total is 0x14= 20 decimal. I therefore changed the compiler managed memory size to:
#define portCOMPILER_MANAGED_MEMORY_SIZE0x14

and added
MOVFFPOSTINC0, PREINC1
to Save_context and
MOVFFPOSTDEC1, POSTDEC0
to restore_context, to make the total number of lines 20, instead of 19 in the demo project.

As already said, after starting the scheduler, first the idle task is entered, followed by a switch to task2.
The program toggles the port for about a second and then stops. When I pause the debugger I am either in vListInsertEnd or vListRemove (or sometimes in vTaskIncrementTick)

As an experiment I disabled the context save and restore lines in the prvTickISR interrupt routine (after all, I am only running 1 task now, so there should be no need to change context). Now everything is fine.

So either something is going wrong in the save and restore context routines or maybe the incrementTick function forces a contextswitch (which is not succesful now I have the context restore disabled)
Or: something is going wrong with memory management in vTaskIncrementTick.

Now I re-enable the save and restore context macros and disable the call to vTaskIncrementTick. This should bring no change since I do not delay any higher priority tasks, which could get swapped back in.
Hurray! Now the port keeps toggling.
Partial conclusion: context save and restore seem to be OK (at least when you restore the same context you just saved)
The tick and delay seems to cause the trouble.

I don't understand the tick overflow detection. You seem to be keeping 2 delayed task lists. Why not just let the delay wrap?

An other question: wouldn't it be more efficient to check if a task switch will occur and only then save old and restore new context? (more efficient in all cases when a single task is running at highest priority)

Greetings

Paul van der Hulst

RE: Trying and failing on a pic 18f8525

Posted by Richard on January 19, 2005
> I made the changes you suggested. (no pre-emption and only 1 task)
> the map file says:
> MATH_DATA udata 0x000000 data 0x000010
> .tmpdata udata 0x000010 data 0x000004
>
> so the total is 0x14= 20 decimal. I therefore changed the compiler managed memory
> size to:
> #define portCOMPILER_MANAGED_MEMORY_SIZE 0x14
> and added
> MOVFF POSTINC0, PREINC1
> to Save_context and
> MOVFF POSTDEC1, POSTDEC0
> to restore_context, to make the total number of lines 20, instead of 19 in the
> demo project.

I'm not sure this was necessary. I have previously noticed the value appears to be one short of that required - but when I looked into it further found the code was actually correct. However, I cannot remember the details now so will need to look again. While this change >may< not be necessary it will not do any harm.


> As already said, after starting the scheduler, first the idle task is entered,
> followed by a switch to task2.
> The program toggles the port for about a second and then stops. When I pause
> the debugger I am either in vListInsertEnd or vListRemove (or sometimes
> in vTaskIncrementTick)
>
> As an experiment I disabled the context save and restore lines in the prvTickISR
> interrupt routine (after all, I am only running 1 task now, so there should
> be no need to change context). Now everything is fine.

What processor frequency and tick frequency are you using. Can you verify that the processor frequency is running as you expect.

Will this sample project run in the MPLAB simulator. If so could you send it to me? The email address can be obtained from the WEB site contact page. I don't like to print the email address here for obvious reasons. If you send the files can you include the project files and all the intermediate files for the program that executes for a while then stops. Hopefully I will be able to see the cause.

<snip>

> I don't understand the tick overflow detection. You seem to be keeping 2 delayed
> task lists. Why not just let the delay wrap?

The list is held in time order - the kernel looks at the list to find the delay with the shortest time. It is done this way to prevent the kernel having to traverse the list from the ISR. Once it finds a time greater than the current time it knows it has to look no further. If you let the time wrap then the task being delayed would end up at the start of the list and be unblocked first rather than last.


RE: Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 19, 2005
Processor frequency is 20MHz and tick rate 500Hz. I verified this with a toggling LED in the ISR.

The code is on it's way

Paul

RE: Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 19, 2005
It seems that after 1018 ticks, the scheduler detects a delayed task.
I replaced prvCheckDelayedTasks() in vTaskIncrementTick with the contents of this #define, so the code now reads:

/* See if this tick has made a timeout expire. */
//prvCheckDelayedTasks();// removed #define
{
register tskTCB *pxTCB;
while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ) ) != NULL )
{
if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) )
{
break;
}
vListRemove( &( pxTCB->xGenericListItem ) );
/* Is the task waiting on an event also? */
if( pxTCB->xEventListItem.pvContainer )
{
vListRemove( &( pxTCB->xEventListItem ) );
}
prvAddTaskToReadyQueue( pxTCB );
}
}

After 1018 ticks, the code breaks at if( xTickCount < listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ) )


Paul

RE: Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 19, 2005
I was SO wrong, the program DOES reset continuously if I just disable the call to vTaskIncrementTick(); in prvTickISR

So the problem must be in save/restore context

The simulator terminates with
CORE-E0002: Stack under flow error occurred from instruction at 0x00293a
which is the return from portRESTORE_CONTEXT without effecting interupts (return 0)

Paul

RE: Trying and failing on a pic 18f8525

Posted by Richard on January 19, 2005
The port.c file you sent has a modification whereby the prvTickISR() is declared as an ISR. This causes the compiler to introduce some prologue code that modifies the stack prior to the context being saved. The upshot of this is that the stack is growing by a couple of bytes on ever tick interrupt. The stack keeps growing until it clobbers the data structures used by the compiler whereby everything crashes.

If you remove the added line "#pragma interrupt prvTickISR", then the test program you supplied works fine.

One other point. Be careful with adding code to your InterruptHander() function. Any registers getting altered here will cause an incorrect context to be saved. Try moving the line "_REL2 = !_REL2;" to within the prvTickISR function - after portSAVE_CONTEXT.

The save and restore context are only required in this function when using the preemptive scheduler (I think?).

Regards.

RE: Trying and failing on a pic 18f8525

Posted by Nobody/Anonymous on January 19, 2005
Thanks very much for the support, I was becoming very desperate.
I don't know how I messed up with the demo project, but that's not important any more.

Thanks again,

Paul van der Hulst


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists