Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on September 8, 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 SysTickHandler -I have set configTICKRATEHZ to 128Hz -I have verified that my RTT handler ticks at a rate of 128Hz to match configTICKRATE_HZ

Here is my implementation. Thank you for any help:

~~~ int main (void) { /* ASF function to setup clocking. */ sysclkinit(); boardinit();

/* 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 ) { rttwritealarmtime(RTT,0x01); configurertt(); }

void vApplicationTickHook( void ) { ioporttogglepinlevel(EXT1PIN_4); }

void configurertt(void) { uint32t ulprevioustime;

/* 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 RTTHandler(void) { uint32t ulstatus; uint32t ulprevioustime;

/* 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();

} ~~~


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on September 9, 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:

portNVICINTCTRLREG = portNVICPENDSVSET_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?

3) 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 NVICSetPriority(RTTIRQn, 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on September 9, 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 ( configUSETICKHOOK == 1 )

{ /* Guard against the tick hook being called when the pended tick count is being unwound (when the scheduler is being unlocked). */ if( uxPendedTicks == ( UBaseTypet ) 0U ) { vApplicationTickHook(); } else { mtCOVERAGETEST_MARKER(); } }

endif /* configUSETICKHOOK */

~~~

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: portNVICINTCTRLREG = portNVICPENDSVSETBIT; in RTTHandler(). 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.

3) 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 NVICSetPriority(RTTIRQn, 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 configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 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 configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 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 CORTEXM4ATSAM4LAtmelStudio #define xPortSysTickHandler was left defined as SysTickHandler 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 RTTHandler due to it creating multiple definitions of the RTTHandler. I assume that as long as I have the xTaskIncrementTick() callback in my RTTHandler 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on September 9, 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 PendSVHandler() name for the PendSV handler, then that line maps the FreeRTOS handler to the PendSVHandler() name.

I set the priority to 10 in order to be graeter or equal to configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 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 configUSETICKLESSIDLE 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on September 9, 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on September 9, 2016

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

~~~

ifndef FREERTOSCONFIGH
define FREERTOSCONFIGH

/* 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
include "sysclk.h"

void asserttriggered( const char * file, uint32t line );

endif
define ConfigFREERTOSLOWPOWER 0
if ConfigFREERTOSLOWPOWER == 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 /* ConfigFREERTOSLOWPOWER */
define configUSE_PREEMPTION 1
define configUSEIDLEHOOK 1
define configUSETICKHOOK 1
define configPRIO_BITS 2
define configMAXPRIORITIES ( ( uint32t ) 5 )
define configMINIMALSTACKSIZE ( ( uint16_t ) 100 )

/* configTOTALHEAPSIZE is not used when heap_3.c is used. */

define configTOTALHEAPSIZE ( ( size_t ) ( 15000 ) )
define configMAXTASKNAME_LEN ( 8 )
define configUSETRACEFACILITY 0
define configUSE16BIT_TICKS 0
define configIDLESHOULDYIELD 1
define configUSE_MUTEXES 1
define configQUEUEREGISTRYSIZE 0
define configCHECKFORSTACK_OVERFLOW 0
define configUSERECURSIVEMUTEXES 1
define configUSEMALLOCFAILED_HOOK 0
define configUSECOUNTINGSEMAPHORES 1
define configUSEQUEUESETS 1
define configGENERATERUNTIME_STATS 0
define configENABLEBACKWARDCOMPATIBILITY 0

/* Co-routine definitions. */

define configUSECOROUTINES 0
define configMAXCOROUTINE_PRIORITIES ( 2 )

/* Software timer definitions. */

define configUSE_TIMERS 1
define configTIMERTASKPRIORITY ( 2 )
define configTIMERQUEUELENGTH 2
define configTIMERTASKSTACK_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 configPRESLEEPPROCESSING() and configPOSTSLEEPPROCESSING() 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 configPRESLEEPPROCESSING( xExpectedIdleTime ) vPreSleepProcessing( xExpectedIdleTime );
define configPOSTSLEEPPROCESSING( 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 configLIBRARYLOWESTINTERRUPT_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 configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 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 configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )
define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )
endif /* FREERTOSCONFIGH */

~~~


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on 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 _NVICPRIO_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 & portTOPBITOFBYTE ) == portTOPBITOFBYTE ) { 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 configPRIORBITS should be 3. If the value read back is 11110000 then configPRIORBITS should be 4. Etc.

The two blocks that start with

~~~

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


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on 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 _NVICPRIO_BITS

/* _NVICPRIO_BITS will be specified when CMSIS is being used. */

define configPRIOBITS __NVICPRIO_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 _NVICPRIO_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 NVICPRIOBITS 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 configPRIORBITS should be 3. If the value read back is 11110000 then configPRIORBITS should be 4. Etc. The two blocks that start with ~~~

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


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by exgreyfox on September 16, 2016

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


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on 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 configLIBRARYLOWESTINTERRUPT_PRIORITY fixes that:

~~~ NVICSetPriority(RTTIRQn, configLIBRARYLOWESTINTERRUPT_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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by hassan789 on October 8, 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


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by eike2017 on 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!


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on 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 configUSETICKLESSIDLE 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.


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by eike2017 on 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?


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by rtel on 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


Ticker Changeover to Real Time Timer on ATSAMG55

Posted by hassan789 on September 13, 2017

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

Thanks


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS