Trying to apply configUSE_PORT_OPTIMISED_TASK_SELECTION to my PIC24 port

mqn wrote on Friday, March 18, 2016:

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

rtel wrote on Friday, March 18, 2016:

No - its fine in this case - provided people read the whole thread :o)

Regards,
Richard.

mqn wrote on Friday, March 18, 2016:

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 configUSE_PORT_OPTIMISED_TASK_SELECTION, 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 configUSE_IDLE_HOOK				1
#define configUSE_TICK_HOOK				0
#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )
#define configCPU_CLOCK_HZ				( ( unsigned long ) 16000000 )  // fosc /2 ?????
#define configMAX_PRIORITIES			( 5 )

#define configMINIMAL_STACK_SIZE		( 128 )
#define configTOTAL_HEAP_SIZE			( ( size_t ) 5120 )
#define configMAX_TASK_NAME_LEN			( 16 )
#define configUSE_TRACE_FACILITY		0
#define configUSE_16_BIT_TICKS			1
#define configIDLE_SHOULD_YIELD			1
#define configCHECK_FOR_STACK_OVERFLOW  2
#define configTICK_INTERRUPT_HANDLER _T1Interrupt
//#define configUSE_TASK_NOTIFICATIONS    1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 		1
#define configMAX_CO_ROUTINE_PRIORITIES ( 1 )

//#define configUSE_PORT_OPTIMISED_TASK_SELECTION 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 configKERNEL_INTERRUPT_PRIORITY	0x01

#define portPOINTER_SIZE_TYPE uint16_t // mqn

Mark

ltran2016 wrote on Friday, March 18, 2016:

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 configKERNEL_INTERRUPT_PRIORITY   0x01

to:

#define configKERNEL_INTERRUPT_PRIORITY   0x04

This will cause an error in originating in “port.c”. Comment out as shown:

//#if configKERNEL_INTERRUPT_PRIORITY != 1
//	#error If configKERNEL_INTERRUPT_PRIORITY is not 1 then the #32 in the following macros needs changing to equal the portINTERRUPT_BITS value, which is ( configKERNEL_INTERRUPT_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.

mqn wrote on Monday, March 21, 2016:

Thanks for that. Unfortunatly this did not help in my particular situation.
One thing I did discover is if I set configCHECK_FOR_STACK_OVERFLOW 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 portasm_PIC24. 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.

mqn wrote on Monday, March 21, 2016:

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

rtel wrote on Monday, March 21, 2016:

…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)

mqn wrote on Tuesday, March 22, 2016:

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

rtel wrote on Tuesday, March 22, 2016:

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?

mqn wrote on Tuesday, March 22, 2016:

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 portTASK_FUNCTION(INT1_ProcessInterrupt,pvParameters)
{
    /* Just to stop compiler warnings. */
	( void ) pvParameters;
    while(1)
    {
        ulTaskNotifyTake(1,portMAX_DELAY);
        // show caught
         _LATA6 = 0; // led low
    }
}

rtel wrote on Tuesday, March 22, 2016:

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

rtel wrote on Tuesday, March 22, 2016:

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

mqn wrote on Tuesday, March 22, 2016:

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.

rtel wrote on Tuesday, March 22, 2016:

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.

mqn wrote on Tuesday, March 22, 2016:

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.

mqn wrote on Tuesday, March 22, 2016:

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?

rtel wrote on Tuesday, March 22, 2016:

Standard.

mqn wrote on Tuesday, March 22, 2016:

T’a