On adding…
'#'define configUSE_PORT_OPTIMISED_TASK_SELECTION 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 to _portRESET_READY_PRIORITY’
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
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.**
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…
BaseType_t task_woken = 0;
xSemaphoreGiveFromISR(binary_sem_INT1,&task_woken);
if(task_woken)
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 configUSE_PORT_OPTIMISED_TASK_SELECTION 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?
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.
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.
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.
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.
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
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?
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?
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
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.
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.