Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

On adding… ‘#’define configUSEPORTOPTIMISEDTASKSELECTION 1 to the FreeRTOSConfig.h of my PIC24FJ1024GB610 port. I get the following compiler errors from my XC16 compiler. build/default/production/ext/449926602/tasks.o(.text+0x48): In function .LBB2': : undefined reference toportRESETREADYPRIORITY’ I can see that this is because the this is not defined in the switched in parts of tasks.h. Why is this so? Is there another config I have to enable. My project was working, using the generic example with my own CLI inserted. Apart from it would automatically reset after 130 seconds. Maybe that is a clue? Mark

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

configUSEPORTOPTIMISEDTASKSELECTION is not a valid option for all targets, and is not implemented for the PIC24.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Fantastic quick reply 🙂 Ok thanks, I thought I read it could, but it looks like a assumed because the PIC24 support CLZ using y = builtin_fbcl(x); Ho hum. Any ideas why my demo is resetting every 130 seconds, when it does compile? Is there any reports of simarlar behavour? I’ll put a breakpoint on startup and look if there is any residual in the error registers, may it is stack.**

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Have a look through the “My application does not run, what could be wrong” FAQ page, although not all of it applies to the PIC24. Specific to the PIC24: Do you have all interrupts that make use of the FreeRTOS API running at the lowest possible interrupt priority? Do you have the tick running at the lowest possible interrupt priority. Are all calls to portENDSWITCHINGISR/portYIELDFROMISR used inside an ISR the very last instruction in the ISR? Is the watchdog disabled?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

All very good guidense and questions. I will check now. Thanks again.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

My watchdog was enabled, with no periodic clear on its counter. So it was doing what it is designed to do :). I disabled it and the resets stopped. Thanks. All looking good now appart from my interrupt latency is a longer than I would like. The raw latency for my edge triggered ISR is 1.6 uS, but when the semaphored call to my task is included it goes up to 40uS. It would be better if it was closer to 10uS. I am using this code in my ISR to pass on the interrupt control… BaseTypet taskwoken = 0; xSemaphoreGiveFromISR(binarysemINT1,&taskwoken); if(taskwoken) vPortYield(); // FromISR not defined my task is running at PRIORTY 3, which is one greater than my CLI task. The only other tasks I am running are the example FlashCORoutines PRIORTY 1 , which I have tried to remove but if I do, strangly, nothing works. My original question about the configUSEPORTOPTIMISEDTASKSELECTION was one attempt to speed things up. So any other suggestions on speeding it up would be very welcome. IF I have reached a ceiling as reguards to latency, I will have to code a “mixed” OS where the high priorty control stuff remains in the raw ISRs and the lower priorty UI and MTM interfaces are in RTOS tasks. Do you think this is feasible, what would be the minimum time for isr activity to keep the Rtos happy? Sorry there are a few questions in there. Mark

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Try using a task notify instead of the semaphore http://www.freertos.org/RTOS-task-notifications.html

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Yes, this looks really promising. Give me a while to impliment and I ‘ll tell how it worked out. Thanks again. Loving your response times 🙂

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Oh dear… The latency has gone up to 45us using Notify. I am using this in the interrupt ~~~~ ulStatusRegister = (uint32t)(IFS1); // PIC24 interupt register _INT1IF = 0; //Clear the INT1 interrupt flag or else xHigherPriorityTaskWoken = pdFALSE; xTaskNotifyFromISR( xINT1ProcessHandle, ulStatusRegister, eSetBits, &xHigherPriorityTaskWoken ); if(xHigherPriorityTaskWoken) vPortYield(); // FromISR not defined task init is like this xTaskCreate( INT1ProcessInterrupt, “ISR INT1 Process”, configMINIMALSTACKSIZE, NULL, uxPriority + 1, ( TaskHandlet * ) &xINT1_ProcessHandle ); and this in the task while(1) { uint32t ulInterruptStatus; xTaskNotifyWait( 0x00, /* Don’t clear any bits on entry. */ 0xffffffff, /* Clear all bits on exit. */ &ulInterruptStatus, /* Receives the notification value. */ portMAXDELAY ); /* Block indefinitely. */
     if( ( ulInterruptStatus & 0x0000000010 ) != 0x0000000000 ) // test for int1 bit
    {
        // show caught
         _LATA6 = 0; // signal interrupt completed for latency measurement
    }
}
~~~~ I have put this into the configuration too define configUSETASKNOTIFICATIONS 1 all ends up taken an extra 5 or more us only things I can think is I am not calling the Notify from the isr in the most efficient way or, is there is something wrong with the PortYield? Mark

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I can’t see any reason for the latency to go up – you just need to look at the amount of code executing to see it should be faster, plus it is a point to point path rather than going through an intermediate object (the semaphore). Using the notify “give” and notify “take” variants of the functions would be simpler, but that doesn’t explain what you are seeing.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I changed the call to xTaskNotifyFromISR with eSetBits to eNoAction and then passed a NULL instead of &ulInterruotStatus into xTaskNotifyWait, with the test on the bit commented out below it. It sped up by 2 us, but still slower than the semaphore.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I changed the call to xTaskNotifyFromISR with eSetBits to eNoAction and then passed a NULL instead of &ulInterruotStatus into xTaskNotifyWait, with the test on the bit commented out below it. It sped up by 2 us, but still slower than the semaphore.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Someting else going on here, because I have put back my semaphore method and that is now 45 us ???? I’ll get back to you when I have worked out what I have done wrong.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I must have misread/quoted my first latency value for the semaphore method. Anyhow, here is the final result Latency using binary semaphor 44.8 us Latency using notify 43.6 us Latency of raw irq 1.6 us

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Is there a way of increasing the speed of the scheduler so the latency goes down? Can I take stuff out of it to make it faster? I assume the schedular it self does not run off and interrupt, or does it?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

This link: http://www.freertos.org/FAQMem.html#ContextSwitchTime describes the configuration for taking an optimal measurement. The context switch code saves all the register then restores a new set of registers (the code can be seen in the portasm_pic24.s in the port layer). Lets say that is approximately 70 or so instructions if you include the C function call too. If you are running at 16MHz, and assuming most instructions use a single cycle, then that would be about (1/16000000)*70=4.4us (I think?). Then perhaps triple it as you are measuring the notify give and take functions too – gives you about 13us – which is a long way off your measured time. Perhaps instructions take two cycles, or you are running the clock slower?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I should be running at 32MHz!

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Morning I have been doing some more timings and they are quite interesting. I have configured my interrupt routine to either trigger the task via binary semaphore or or notification and have put ticks around each function so I can get accurate scope timings. Here are my results Set up for semiphore : here are the timing to call and return from xSemphoreGiveFromISR 8.1us PortYield 94.9us Time for the task to recieve the Semaphore after the start of the PortYield 34.5us Set up for notify : here are the timing to call and return from xTaskNotifyGiveFromISR 6.1us PortYield 73.9us Time for the task to recieve the Notification after the start of the PortYield 35 us So it looks like whatever is going on in PortYield is the cause of the long timings. Should there be a PortYieldFromISR which is a little more friendly to interupts? Could it be that I have badly configured priorities for my and the schedular interupts? What interrupt(s), other the the 1 ms timer, is the schedular using and which should I set to the highest priority? Regards Mark

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Be careful with how you are taking measurements as you are probably not measuring what you think (this is why we normally stipulate no published measurements!). If I recall correctly on the PIC24 when you call yield you will get a switch out of the ISR into the task immediately. You will then not effectively (conceptually) return from the yield until the task that was yielded away from next executes. So if you are measuring before and after the yield you are measuring the entire time the task took to execute and a switch back to the original task to be performed – not the time of the yield.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Thats what I was just thinking it must be doing, this seams to indicate that I may as well do my data processing in the raw isr and not use tasks for that purpose, as the PortYield is causing the the interupt to persist as long as its invoked process + all of the rtos context switching time. All my task is doing atm is clearing a pin, 70 to 90 us to do that is much too much. So the question still remains, what is causing the 35us delays before the task triggers? Could this be down to my set priorities being wrong? I have looked for hidden interupts firing but not seen. Above you say is should be taking 2 or 3 us with my clock speeds.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

“this is why we normally stipulate no published measurements!” Would you like me to edit and redact the timings I got?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

No – its fine in this case – provided people read the whole thread :o) Regards, Richard.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Have you any other ideas / guidense. Referencing our link to http://www.freertos.org/FAQMem.html#ContextSwitchTime I have tried everything in here. Change in optimisation had a very small effect. Can’t use configUSEPORTOPTIMISEDTASKSELECTION, see above. Stack probe disable and the others are not applicable. Priorities perhaps? Here is my entire config ~~~~

include <p24FJ1024GB610.h>

/———————————————————– * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE ‘CONFIGURATION’ SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html. *———————————————————-/ /* Define configASSERT() to call vAssertCalled() if the assertion fails. The assertion has failed if the value of the parameter passed into configASSERT() equals zero. */

define qAssertCalled(A,B) printf(“Assert line : %s file : %d”,FILE,LINE )

define configASSERT( x ) if( ( x ) == 0 ) qAssertCalled( FILE, LINE )

define configUSE_PREEMPTION 1

define configUSEIDLEHOOK 1

define configUSETICKHOOK 0

define configTICKRATEHZ ( ( TickType_t ) 1000 )

define configCPUCLOCKHZ ( ( unsigned long ) 16000000 ) // fosc /2 ?????

define configMAX_PRIORITIES ( 5 )

define configMINIMALSTACKSIZE ( 128 )

define configTOTALHEAPSIZE ( ( size_t ) 5120 )

define configMAXTASKNAME_LEN ( 16 )

define configUSETRACEFACILITY 0

define configUSE16BIT_TICKS 1

define configIDLESHOULDYIELD 1

define configCHECKFORSTACK_OVERFLOW 2

define configTICKINTERRUPTHANDLER _T1Interrupt

//#define configUSETASKNOTIFICATIONS 1 /* Co-routine definitions. */

define configUSECOROUTINES 1

define configMAXCOROUTINE_PRIORITIES ( 1 )

//#define configUSEPORTOPTIMISEDTASKSELECTION 1 /* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */

define INCLUDE_vTaskPrioritySet 1

define INCLUDE_uxTaskPriorityGet 0

define INCLUDE_vTaskDelete 0

define INCLUDE_vTaskCleanUpResources 0

define INCLUDE_vTaskSuspend 1

define INCLUDE_vTaskDelayUntil 1

define INCLUDE_vTaskDelay 1

define configKERNELINTERRUPTPRIORITY 0x01

define portPOINTERSIZETYPE uint16_t // mqn

~~~~ Mark

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I think I had somet issue similar to you on the dspic which shares the same codebase as athe pic24. Change the following in “FreeRTOSConfig.h” from: ~~~~

define configKERNELINTERRUPTPRIORITY 0x01

~~~~ to: ~~~~

define configKERNELINTERRUPTPRIORITY 0x04

~~~~ This will cause an error in originating in “port.c”. Comment out as shown: ~~~~ //#if configKERNELINTERRUPTPRIORITY != 1 // #error If configKERNELINTERRUPTPRIORITY is not 1 then the #32 in the following macros needs changing to equal the portINTERRUPTBITS value, which is ( configKERNELINTERRUPT_PRIORITY << 5 ) //#endif ~~~~ The reason I did all this was because the default hardware priority level of the interrupts is “4” on power up. You have to specifically force the hardware interrupts to be at or below the interrupt level set for Timer1 or whatever timer you use for your tick timer. I hope this helps.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Thanks for that. Unfortunatly this did not help in my particular situation. One thing I did discover is if I set configCHECKFORSTACKOVERFLOW from 2 to 0 the my latency almost halves, down to 20.8 us. The question is now how safe is it to remove the stack check. I put timing signals inside the vPortYield function in portasmPIC24. Then I could see that with stack check this took 30 us and without it took 6.6 us. This is very close to what was quoted, 6 comments above. We are a little more happier now but think we will be doing most off our control processing in the raw processor isr and not in tasks. The lower priorty tasks will just be deployed for UI and MTM processing.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

…also, just managed to shave off another 1.5 us by using NotifyTake instead of NotifyWait in the task. 🙂

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

….I think these two items (turning off stack checking, undefining configASSERT(), etc. and using the lighter task notification function) were suggested higher up in this thread ;o)

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Yes, sorry. Not sure why I dismissed the Stack check disable first time around. I’m not too old to learn new tricks after all 🙂 Here is the big news which I do not understand but it is great if I can utilise it in my overall system. I have managed to reduce my latency down to 8us!!! Here is how. I have three task running. The first one is the demo co flash task, which of course is several coroutine tasks running at priority 1. The other two tasks are my CLI running at priority 2 and the test task running at prioity 3. One of my CLI functions can set an output line high on one port which is feed back into the board and causes an edge triggered isr. This calls the notify to my test task which signals on yet another output port bit. The difference between the interupt trigger signal and the recieved signal is my latency. Now in this setup I can see that the are two PortYeilds called and in between them the test task is called (20us with stack check off). Now I set the priority of the test task down to the same as the CLI and the notify ( give and take ) are much improved because the two yields are not there anymore. Latency now 8us. Is this because they exist in the same context and no switching is required? If so I am a little “at sea” at the moment trying to work out how I should order my priorities to keep this loverly low latency in my system. I must be on the right track but I need it to make sense of it. Is it that I am totally misunderstand the prioity ordering? I just set the CLI to 3 and my test to 2 and got the same good low latency. Please can someone explain what I am seeing.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Now in this setup I can see that the are two PortYeilds called and in between them the test task is called
As I understand it, you have the CLI task executing, this generates an interrupt [on an external line], the interrupt unlbocks a higher priority test task so yields, then the test task executes. Where is the second yield?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I assume it is being called from within the NotifyTake in my test task when it loops back from the signal complete send. That is, the first yield in my isr causes the TaskNotify to become unblocked, the line is set low and the code loops back to call the TaskNotify again, this will then call the Yeild and wait/block for the next Give. ~~~~ static portTASKFUNCTION(INT1ProcessInterrupt,pvParameters) { /* Just to stop compiler warnings. */ ( void ) pvParameters; while(1) { ulTaskNotifyTake(1,portMAX_DELAY); // show caught _LATA6 = 0; // led low } } ~~~~

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Yes, ulTaskNotifyTake() will yield again as it has a block time specified, but that should be after _LATA6 has been cleared.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Do you also have a timer task running (is configUSE_TIMERS set to 1)?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

No configUSE_TIMERS set . I’ll put it in and see what happens, what does it do? but that should be after LATA6 has been cleared Yes it does appear after the LATA6 is cleared.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

It will result in another task being created. In this case it should not make any different as the task will just be blocked, but I was trying to think what else could be inserting a yield.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I’m glad, because after I added it “configUSE_TIMERS” it required me so set up the timer stack, queue length and priorty. Once I guessed at what these should be the compile required xTimerCreateTimerTask which is hidden somewhere.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

I want to order your FreeRTOS book. We are using the PIC24, would it be better to order the Standard version or the oe that target the PIC32?

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

Standard.

Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

T’a