Trying and failing on a pic 18f8525

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

Trying and failing on a pic 18f8525

> 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.

Trying and failing on a pic 18f8525

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

Trying and failing on a pic 18f8525

>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.

Trying and failing on a pic 18f8525

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_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. 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

Trying and failing on a pic 18f8525

> 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.

Trying and failing on a pic 18f8525

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

Trying and failing on a pic 18f8525

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

Trying and failing on a pic 18f8525

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

Trying and failing on a pic 18f8525

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.

Trying and failing on a pic 18f8525

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