Ticker Changeover to Real Time Timer on ATSAMG55

exgreyfox wrote on Thursday, September 08, 2016:

Hello,

I am currently doing development on the ATSAMG55 using FreeRTOS version 8.0.1 and I have a need for changing the RTOS ticker from using to default SysTick to use the ATSAMG55’s Real Time Timer (RTT). The reason for this is due to the fact that my application requires me to use the lowest power mode that the SAMG55 has (Wait Mode) however the Systick is not a wakeup source for this mode so a new tick source (RTT) that is supported by wait mode as a wakeup source is my goal.

I have followed the instructions here on how to do this regarding “Generating a tick interrupt from a clock other than SysTick”: http://www.freertos.org/low-power-ARM-cortex-rtos.html

I have dumbed things down by keeping tickless idle mode disabled so that I can install the RTT tick interrupt and watch it run a single task that toggles an LED then blocks for x ticks without any sleep modes for now.

I have enabled the tick hook and I am toggling a pin inside vApplicationTickHook at the rate of my RTT interrupt to verify that the ticker is working and it is. I see the pin toggle. The problem that I am having however is that my task does not run. When I swap back to the SysTick ticker source my task runs fine, but it does not seem to want to run from the RTT tick interrupt.

-I have made sure to comment out the following inside FreeRTOSConfig.h so that the kernel does not install the SysTick as the default interrupt : #define xPortSysTickHandler SysTick_Handler
-I have set configTICK_RATE_HZ to 128Hz
-I have verified that my RTT handler ticks at a rate of 128Hz to match configTICK_RATE_HZ

Here is my implementation. Thank you for any help:

int main (void)
{
	/* ASF function to setup clocking. */
	sysclk_init();
	board_init();
	
	/* Debugging traces */
	ioport_set_pin_dir(EXT1_PIN_3, IOPORT_DIR_OUTPUT); /* Task1 */
	ioport_set_pin_dir(EXT1_PIN_4, IOPORT_DIR_OUTPUT); /* TickHook */
	ioport_set_pin_dir(EXT1_PIN_5, IOPORT_DIR_OUTPUT); /* PreSleep PostSleep */
	ioport_set_pin_dir(EXT1_PIN_6, IOPORT_DIR_OUTPUT); /* IdleHook */
	ioport_set_pin_dir(EXT1_PIN_7, IOPORT_DIR_OUTPUT); /* RTT ISR */
	
	/* Create the queue. */
	xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
	configASSERT( xQueue );

	xTaskCreate( prvTask1, "Task1", configMINIMAL_STACK_SIZE, NULL, configTASK1_TASK_PRIORITY, NULL );

	/* Start the scheduler running running. */
	vTaskStartScheduler();

	/* If all is well the next line of code will not be reached as the
	scheduler will be running.  If the next line is reached then it is likely
	there was insufficient FreeRTOS heap available for the idle task and/or
	timer task to be created.  See http://www.freertos.org/a00111.html. */
	for( ;; ) {
		
	}
}

static void prvTask1( void *pvParameters )
{
	/* Remove compiler warning about unused parameter. */
	( void ) pvParameters;
	
	for( ;; )
	{
		ioport_set_pin_level(EXT1_PIN_3, IOPORT_PIN_LEVEL_HIGH);
		vTestToggleLED(mainQUEUE_LED);
		delay_ms(10); 
		ioport_set_pin_level(EXT1_PIN_3, IOPORT_PIN_LEVEL_LOW);
		vTaskDelay( task1Delay ); /* Delay 1000ms */
	}
}

void vPortSetupTimerInterrupt( void )
{
 	rtt_write_alarm_time(RTT,0x01);
 	configure_rtt();
}

void vApplicationTickHook( void )
{
	ioport_toggle_pin_level(EXT1_PIN_4);
}

void configure_rtt(void)
{
	uint32_t ul_previous_time;

	/* Configure RTT for a 128 Hz ticker */
	rtt_init(RTT,256); /* us_prescalar for 128Hz RTOS tick ISR */

	ul_previous_time = rtt_read_timer_value(RTT);
	while (ul_previous_time == rtt_read_timer_value(RTT));

	/* Enable RTT interrupt */
	NVIC_DisableIRQ(RTT_IRQn);
	NVIC_ClearPendingIRQ(RTT_IRQn);
	NVIC_SetPriority(RTT_IRQn, 10);
	NVIC_EnableIRQ(RTT_IRQn);
	rtt_enable_interrupt(RTT, RTT_MR_ALMIEN);
}

void RTT_Handler(void)
{
	uint32_t ul_status;
	uint32_t ul_previous_time;
	
	/* Protect incrementing the tick with an interrupt safe critical section. */
	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
	{
		if( xTaskIncrementTick() != pdFALSE )
		{
			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
		}

		/* Just completely clear the interrupt mask on exit by passing 0 because
		it is known that this interrupt will only ever execute with the lowest
		possible interrupt priority. */
	}
	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
	
	ioport_toggle_pin_level(EXT1_PIN_7);
	
	/* Get RTT status */
	ul_status = rtt_get_status(RTT);
	
	rtt_write_alarm_time(RTT,0x01);
	configure_rtt();
}

rtel wrote on Friday, September 09, 2016:

What a great support request - others please take note! The poster has
worked through the problem, and provided lots of information.

I am currently doing development on the ATSAMG55 using FreeRTOS version
8.0.1

You know the latest is V9?

and I have a need for changing the RTOS ticker from using to
default SysTick to use the ATSAMG55’s Real Time Timer (RTT).

This should be “easy” (ha), although the exact details depend on the
compiler you are using.

Which compiler are you using?

So as I understand it:

  • We know the RTT is interrupting at the correct frequency, because the
    tick hook function is toggling its pin at the correct frequency. That
    means the clock is configured correctly, and the interrupt handler is
    installed correctly.

  • If the tick hook is executing then xTaskIncrementTick() must be
    executing, which should unblock your task.

  • For some reason, even though xTaskIncrementTick() is executing the
    task isn’t, so we need to track that through.

Brainstorming why this might be:

  1. Perhaps, even though xTaskIncrementTick() is running, for some reason
    the tick count is not increasing. That could happen, for example, if
    the scheduler thought it was suspended (in which case the tick
    increments are held pending until the scheduler is unsuspended). Please
    let the system run for a short while, then put a break point in your
    tick hook function. When the break point is hit, use the debugger to
    step out of the tick hook. When the tick hook function returns you will
    end up in the tasks.c source file - when in the tasks.c source file
    inspect the xTickCount variable - its value should equal the number of
    tick interrupts that have occurred. Does it?

  2. Perhaps the PendSV interrupt is not executing (the context switch
    actually occurs in the PendSV interrupt. Try setting a break point on
    the line:

portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;

in RTT_Handler(). Does it get hit? If so, try running the system again
with a volatile counter variable that counts the number of times the
line executes.

If the line does execute, does the vPortPendSVHandler() (in
FreeRTOS/Source/portable/[compiler]/ARM_CM4F/port.c) ever execute?

  1. Perhaps something in your code is causing a problem. Try the following:

a) Remove the call to delay_ms(10); That is probably using the SysTick
and could conceivable cause an issue (or not, I don’t know how it is
implemented).

b) Ensure the priority of the RTT interrupt is set to the lowest
possible. That is done by the line NVIC_SetPriority(RTT_IRQn, 10); It
might be that 10 is the lowest priority, but I doubt it. Also check the
subpriority is set to 0, as you seem to leave that undefined, but will
probably default to 0.

exgreyfox wrote on Friday, September 09, 2016:

Greetings to you guys from FreeRTOS and thank you for the quick reply. To answer your questions:

I am using Atmel Studio 7 which uses the ARM/GNU C compiler.

I am aware that the latest FreeRTOS version is v9 however V9 is not available in the Atmel Software Framework. This is ok becuase V8.0.1 also supports tickless idle mode.

So as I understand it:
We know the RTT is interrupting at the correct frequency, because the
tick hook function is toggling its pin at the correct frequency. That
means the clock is configured correctly, and the interrupt handler is
installed correctly.
If the tick hook is executing then xTaskIncrementTick() must be
executing, which should unblock your task.
For some reason, even though xTaskIncrementTick() is executing the
task isn’t, so we need to track that through.

Yes these are all correct.

  1. Perhaps, even though xTaskIncrementTick() is running, for some reason
    the tick count is not increasing. That could happen, for example, if
    the scheduler thought it was suspended (in which case the tick
    increments are held pending until the scheduler is unsuspended). Please
    let the system run for a short while, then put a break point in your
    tick hook function. When the break point is hit, use the debugger to
    step out of the tick hook. When the tick hook function returns you will
    end up in the tasks.c source file - when in the tasks.c source file
    inspect the xTickCount variable - its value should equal the number of
    tick interrupts that have occurred. Does it?

The variable that I see is called uxPendedTicks and the debugger returns inside the folloiwing condition with uxPendedTicks = 0

#if ( configUSE_TICK_HOOK == 1 )
{
    /* Guard against the tick hook being called when the pended tick
    count is being unwound (when the scheduler is being unlocked). */
    if( uxPendedTicks == ( UBaseType_t ) 0U )
    {
        vApplicationTickHook();
    }
    else
    {
        mtCOVERAGE_TEST_MARKER();
    }
}
#endif /* configUSE_TICK_HOOK */
  1. Perhaps the PendSV interrupt is not executing (the context switch
    actually occurs in the PendSV interrupt. Try setting a break point on
    the line:
    portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
    in RTT_Handler(). Does it get hit? If so, try running the system again
    with a volatile counter variable that counts the number of times the
    line executes.

Yes this line is getting hit.

If the line does execute, does the vPortPendSVHandler() (in
FreeRTOS/Source/portable/[compiler]/ARM_CM4F/port.c) ever execute?

xPortPendSVHandler is not getting hit.

  1. Perhaps something in your code is causing a problem. Try the following:
    a) Remove the call to delay_ms(10); That is probably using the SysTick
    and could conceivable cause an issue (or not, I don’t know how it is
    implemented).

Removed the 10ms delay. No change in result.

b) Ensure the priority of the RTT interrupt is set to the lowest
possible. That is done by the line NVIC_SetPriority(RTT_IRQn, 10); It
might be that 10 is the lowest priority, but I doubt it. Also check the
subpriority is set to 0, as you seem to leave that undefined, but will
probably default to 0.

I set the priority to 10 in order to be graeter or equal to configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY which is defined as follows in FreeRTOSConfig.h:

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	10

I also set the RTT priority back to the lowest in NVIC which is 5.

To clarify something I have been wondering about…I am running this test with Tickless Idle Mode disabled becuse I am attempting to get things working incrementally. Before I enable tickless idle mode uisng the RTT, I would just like to get the ticker to be switched over to the RTT and then tackle getting tickless Idle mode working seperately. This should be fine right? In other words I am doing this effort assuming that RTOS allows me to switch over to a different ticker interrupt source with tickless Idle mode disabled. Another way to put it is that I am assuming that FreeRTOS’ capability to switch ticker sources isn’t exclusive only to tickless idle mode.

Another thing, as far as properly installing the RTT_Handler as the new ticker handler, I have commented out the following line in FreeRTOSConfig.c:

#define xPortSysTickHandler SysTick_Handler

Is it an absolute necessity for me to replace this with something like this? :

#define xPortSysTickHandler RTT_Handler

I noticed that in the FreeRTOSv9.0.0 demo example named CORTEX_M4_ATSAM4L_Atmel_Studio #define xPortSysTickHandler was left defined as SysTick_Handler despite the fact that they used the SAM4L’s AST timer as the source of the ticker so I wasn’t sure how to handle this aspect of the implementation. In my implementation I tried both commenting it out and leaving it defined with no difference in result. Also I was not able to do the #define xPortSysTickHandler RTT_Handler due to it creating multiple definitions of the RTT_Handler. I assume that as long as I have the xTaskIncrementTick() callback in my RTT_Handler I can leave the #define xPortSystickHandler defined as SysTick_Handler without it hurting anything. But please correct me if I’m wrong on any of these assumptions.

rtel wrote on Friday, September 09, 2016:

xPortPendSVHandler is not getting hit.

That would seem to be the issue then.

You correctly removed the following line from FreeRTOSConfig.h:

#define xPortSysTickHandler SysTick_Handler

but did you leave

#define xPortPendSVHandler PendSV_Handler

in? Assuming your vector table is using the default PendSV_Handler()
name for the PendSV handler, then that line maps the FreeRTOS handler to
the PendSV_Handler() name.

I set the priority to 10 in order to be graeter or equal to
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY which is defined as follows
in FreeRTOSConfig.h:

The timer interrupt needs to be the lowest priority possible (so a
higher numeric value), rather than the maximum sys call priority (which
is the highest that can use the FreeRTOS API) - but this is a future
attraction, I don’t think it is the issue right now.

To clarify something I have been wondering about…I am running this
test with Tickless Idle Mode disabled becuse I am attempting to get
things working icnremetnally.

Which is the best way of doing it. So presumably you have
configUSE_TICKLESS_IDLE set to 0.

Before I enable tickless idle mode uisng
the RTT, I would just like to get the ticker to be switched over to the
RTT and then tackle getting tickless Idle mode working seperately. This
should be fine right?

Yes, absolutely. That is how I would do it.

In other words I am doing this effort assuming

that RTOS allows me to switch over to a different ticker interrupt
source with tickless Idle mode disabled. Another way to put it is that I
am assuming that FreeRTOS’ capability to switch ticker sources isn’t
exclusive only to tickless idle mode.

In the GCC port vPortSetupTimerInterrupt() is simply defined as a weak
symbol. So defining vPortSetupTimerInterrupt() yourself is enough to
get your version called instead of the default. Then you just have to
ensure you install the interrupt handler and have the interrupt handler
call the correct code - which I think you are doing. In this case it
would seem the tick interrupt is working, but the PendSV is not.

exgreyfox wrote on Friday, September 09, 2016:

but did you leave
#define xPortPendSVHandler PendSV_Handler

Yes correct. I did leave this the way it was by default.

The timer interrupt needs to be the lowest priority possible (so a
higher numeric value), rather than the maximum sys call priority (which
is the highest that can use the FreeRTOS API) - but this is a future
attraction, I don’t think it is the issue right now.

I attempted to set the RTT interrupt priority as follows instead:

NVIC_SetPriority(RTT_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);

It was also done this way in the working SAM4L freertos demo example uisng the AST as the tick interrupt and it works for them, but for me, it causes my RTT interrupt to not fire at all so I left it at priority level 10 for now. This is actually strange as I dont see areason why setting the RTT interrupt priority in the NVIC to the minimum FreeRTOS defined level would completely kill the interrupt unless there is another one that is continuously firing and has the same or identical subpriority so to remove that doubt, I called the following before the kernel is started:

NVIC_SetPriorityGrouping( 0 );

But this has no effect either.

So at least now we have something that resembles a root cause and that would be the supervisory call handler PendSV handler not firing.

exgreyfox wrote on Friday, September 09, 2016:

Perhaps it would be of more help if I posted the entire contents of my FreeRTOSConfig.h file:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* For documentation for all the configuration symbols, go to:
 * http://www.freertos.org/a00110.html.
 */

#if defined (__GNUC__) || defined (__ICCARM__)
/* Important: put #includes here unless they are also meant for the assembler.
 */
#include <stdint.h>
#include "sysclk.h"
void assert_triggered( const char * file, uint32_t line );
#endif

#define ConfigFREERTOS_LOW_POWER				0

#if ConfigFREERTOS_LOW_POWER == 1
	#define configUSE_TICKLESS_IDLE				1
	#define configSYSTICK_CLOCK_HZ				( sysclk_get_cpu_hz() / 8 )
	#define configCPU_CLOCK_HZ					( sysclk_get_cpu_hz() )
	#define configTICK_RATE_HZ					( ( TickType_t ) 100 )
#else
	#define configUSE_TICKLESS_IDLE				0
	#define configCPU_CLOCK_HZ                  ( sysclk_get_cpu_hz() )
	#define configTICK_RATE_HZ                  ( ( TickType_t ) 100 )
#endif /* ConfigFREERTOS_LOW_POWER */

#define configUSE_PREEMPTION                    1
#define configUSE_IDLE_HOOK                     1
#define configUSE_TICK_HOOK                     1
#define configPRIO_BITS                         2
#define configMAX_PRIORITIES                    ( ( uint32_t ) 5 )
#define configMINIMAL_STACK_SIZE                ( ( uint16_t ) 100 )
/* configTOTAL_HEAP_SIZE is not used when heap_3.c is used. */
#define configTOTAL_HEAP_SIZE                   ( ( size_t ) ( 15000 ) )
#define configMAX_TASK_NAME_LEN                 ( 8 )
#define configUSE_TRACE_FACILITY                0
#define configUSE_16_BIT_TICKS                  0
#define configIDLE_SHOULD_YIELD                 1
#define configUSE_MUTEXES                       1
#define configQUEUE_REGISTRY_SIZE               0
#define configCHECK_FOR_STACK_OVERFLOW          0
#define configUSE_RECURSIVE_MUTEXES             1
#define configUSE_MALLOC_FAILED_HOOK            0
#define configUSE_COUNTING_SEMAPHORES           1
#define configUSE_QUEUE_SETS                    1
#define configGENERATE_RUN_TIME_STATS           0
#define configENABLE_BACKWARD_COMPATIBILITY     0

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

/* Software timer definitions. */
#define configUSE_TIMERS                        1
#define configTIMER_TASK_PRIORITY               ( 2 )
#define configTIMER_QUEUE_LENGTH                2
#define configTIMER_TASK_STACK_DEPTH            ( 80 )

/* 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               1
#define INCLUDE_vTaskDelete                     1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_xResumeFromISR                  1
#define INCLUDE_vTaskDelayUntil                 1
#define INCLUDE_vTaskDelay                      1
#define INCLUDE_xTaskGetSchedulerState          1
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_uxTaskGetStackHighWaterMark     0
#define INCLUDE_xTaskGetIdleTaskHandle          0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle  0
#define INCLUDE_pcTaskGetTaskName               0
#define INCLUDE_eTaskGetState                   0


/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) \
        if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
			
/* The configPRE_SLEEP_PROCESSING() and configPOST_SLEEP_PROCESSING() macros
allow the application writer to add additional code before and after the MCU is
placed into the low power state respectively.  The empty implementations
provided in this demo can be extended to save even more power. */
void vPreSleepProcessing( unsigned long xExpectedIdleTime );
void vPostSleepProcessing( unsigned long xExpectedIdleTime );
#define configPRE_SLEEP_PROCESSING( xExpectedIdleTime ) vPreSleepProcessing( xExpectedIdleTime );
#define configPOST_SLEEP_PROCESSING( xExpectedIdleTime ) vPostSleepProcessing( xExpectedIdleTime );

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler						  SVC_Handler
#define xPortPendSVHandler                    PendSV_Handler
//#define xPortSysTickHandler                   SysTick_Handler

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			0x0f

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	10

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

#endif /* FREERTOS_CONFIG_H */

rtel wrote on Saturday, September 10, 2016:

Your configPRIOR_BITS setting is almost certainly wrong.

I just looked at the SAMG55 user guide, where I find the statement

“The Cortex-M4 processor closely integrates a configurable NVIC, to
deliver industry-leading interrupt
performance. The NVIC includes a non-maskable interrupt (NMI), and
provides up to 256 interrupt priority levels.”

That would imply there were 8 bits, but I suspect that is not the case
either (it sounds like it is describing the maximum the NVIC can
support, not the number actually supported by the SAMG55. I would
expect the number to be in the range of 3 to 5 inclusive.

Do you have a cmsis header file for this part? If so it should define a
constant called __NVIC_PRIO_BITS, which should in theory give you the
correct setting (although I have known even the cmsis header files to
get this wrong sometimes).

Later versions of FreeRTOS have more asserts to try and catch this type
of misconfiguration.

Find the implementation of xPortStartScheduler() in the following file:
https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c#l318

It is on line 318 at the time of writing.

In that function you will see the lines:

while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
   ulMaxPRIGROUPValue--;
   ucMaxPriorityValue <<= ( uint8_t ) 0x01;
}

What this is doing is writing 255 to a priority register, then reading
the value held in the priority register back, and looping to see how
many bits are set. Any bits that are not implemented will be read back
as 0. The not implemented bits will be the least significant bits. So,
for example, if the value read back is binary 11100000 then
configPRIOR_BITS should be 3. If the value read back is 11110000 then
configPRIOR_BITS should be 4. Etc.

The two blocks that start with

#ifdef __NVIC_PRIO_BITS

then

#ifdef configPRIO_BITS

are new. If you cut and paste those into your code then the code will
get stuck in the assert if the constants are wrong in FreeRTOSConfig.h.

exgreyfox wrote on Saturday, September 10, 2016:

Your configPRIOR_BITS setting is almost certainly wrong.

Correct, I have since removed the erroneous leftover definition of configPRIO_BITS 2 and replaced it with the folloiwng in my FreeRTOSConfig.h

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __NVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS       		__NVIC_PRIO_BITS
#else
#define configPRIO_BITS       		4        /* 15 priority levels */
#endif

Do you have a cmsis header file for this part? If so it should define a
constant called __NVIC_PRIO_BITS, which should in theory give you the
correct setting (although I have known even the cmsis header files to
get this wrong sometimes).

Yes I did check the CMSIS header for my chip and NVIC_PRIO_BITS are in fact 4.

What this is doing is writing 255 to a priority register, then reading
the value held in the priority register back, and looping to see how
many bits are set. Any bits that are not implemented will be read back
as 0. The not implemented bits will be the least significant bits. So,
for example, if the value read back is binary 11100000 then
configPRIOR_BITS should be 3. If the value read back is 11110000 then
configPRIOR_BITS should be 4. Etc.
The two blocks that start with

> #ifdef __NVIC_PRIO_BITS
> then
> #ifdef configPRIO_BITS

I verified that this works when I set the configPRIO_BITS to an incorrect value so I will leave this in my code from now on as its a useful error trap.

So after proper initialization of configPRIO_BITS, xPortPendSVHandler is still not firing.

exgreyfox wrote on Friday, September 16, 2016:

Hello RTEL folks. Is there any chance that we might be able to get in touch with you regarding this issue? I’ve spent a couple of more days digging into but the efforts have been futile. The project we are currently working on will eventually hit a critical brick wall so due to that, we are willing to compensate you guys if we can take some of your time on the matter.

rtel wrote on Friday, September 16, 2016:

If you zip up a project that I can built ‘out of the box’ (without
having to set any paths to files, etc.) and send it to r [dot] barry
at freertos (dot) org, along with a description of the most
immediate issue, then I can take a look for you - but I can’t promise
any more than taking a look.

exgreyfox wrote on Friday, September 16, 2016:

Thanks sir. This will be an Atmel Studio 7 project that will build out of the box.

rtel wrote on Friday, September 16, 2016:

The PendSV handler is installed correctly, I can see that by viewing a disassembly of the vector table and comparing it to the address of the correct handler in the map file.

The first problem is that the RTT interrupt is executing before the scheduler starts - which should not be possible if the interrupt priority was set correctly. Commenting out:

NVIC_SetPriorityGrouping( 0 );

and updating the RTT initialisation function to replace the 20 with configLIBRARY_LOWEST_INTERRUPT_PRIORITY fixes that:

NVIC_SetPriority(RTT_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);

However, I don’t think either of those issues are your most immediate issue as the PendSV is still not executing.

I don’t think configure_rtt is a function you want to be calling from inside the RTT interrupt handler. It is doing all sorts that is not necessary, and contains loops that could take a long time to execute. It might be that you are just consuming too much time in the interrupt handler.

rtel wrote on Friday, September 16, 2016:

Actually, then PendSV interrupt is executing now. First the timer task
runs, then your application task, then the idle task…but that is all.
My best estimate is that the route of the problem is in the
RTT_Handler() implementation.

hassan789 wrote on Saturday, October 08, 2016:

Stan,
Not sure if this is still an issue or not…
your problem is this:

rtt_write_alarm_time(RTT,0x01); //wrong!!
configure_rtt()

should be this:

rtt_write_alarm_time(RTT, rtt_read_timer_value(RTT) + 1); //no need to reconfigure

I am running a tickless SAMG55… if your still have problems, post back here or PM me

eike2017 wrote on Monday, September 11, 2017:

Hello,
I am also trying to implement Tickless Mode on Atmel G55.
So i would highly appreciate a working code example.

Thanks in advance!

rtel wrote on Monday, September 11, 2017:

That is a Cortex-M4 part, so the generic Cortex-M tickless mode will
work on it (so there is nothing to do other than set
configUSE_TICKLESS_IDLE to 1). If you want to use a lower power mode
that switches the systick clock off then you will need to create your
own port, for which I would suggest using one of the examples in the
FreeRTOS download (for another part) as a reference.

eike2017 wrote on Monday, September 11, 2017:

Thanks for your answer,
to be more specific: I want to use the RTT (Real Time Timer) which source is an external 32 kHz Oscillator to generate the ticks. I use the code from this thread. The ticks are working, but the SAMG55 does not go into any sleep mode, since the current consumption stays steady.

So I have to rewrite vPortSuppressTicksAndSleep() to fulfill my needs?

rtel wrote on Monday, September 11, 2017:

Yes, are you are using a clock specific to that family of parts you will
have to write the piece of code that re-programs the clock to generate
an interrupt at the appropriate time when entering the tickless mode,
and then re-starts the regular tick when exiting sleep mode. This
provides an overview, and has links to examples you can use as a
reference http://www.freertos.org/low-power-tickless-rtos.html

hassan789 wrote on Wednesday, September 13, 2017:

Hello, I have posted a simple example to use tickless on the Microchip Atmel SamG55 chip here:
https://github.com/hchaudhary1/SAMG55_Tickless_example

Thanks