FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [October 2010 Threads] Tick hook executed only oncePosted by Esorol on October 26, 2010 Hi
I have a piece of example code for the ATmega644 which behaves, in my opinion, somewhat unexpectedly. When the system starts up, I want to run the system with idle task only and see how many times the hook is called. After this, the system can continue initialization. For this reason, I create the task to init the system but request it to delay for 100 milliseconds right away.
In the tick hook, I keep track of some support info (not included in the code I intend to post) but also check to see when the 100 milliseconds have passed and I can continue initialization.
My problem is that the tick hook is called only once, during the entire execution of the program. Thus, the idle task remains the only task running and the rest of the firmware is never inited. From what I can gather, after executing the hook and the code in vPortYieldFromTick function, the "reti" command is not executed so the tick interrupt is not re-enabled.
In the next post I will attach a sample AVR Studio project which (for me) causes the problem.
Best regards,
// Esorol
RE: Tick hook executed only oncePosted by Esorol on October 26, 2010 Ok, it seems I need to open a bug (?) to post the project. So I thought I'd wait and see if someone has opinions.
The reason for wanting to check how many times the idle hook is called when the system is "idling" is that I can use this benchmark later in the firmware for estimating the CPU load. By counting the number of times the idle hook is called during normal execution, and comparing to the idling benchmark, I can get a rough idea of how much time is spent in the idle task.
// Esorol
RE: Tick hook executed only oncePosted by Esorol on October 26, 2010 Update: tried different optimization levels, and it seems that this might be the cause of the problem. In void SIG_OUTPUT_COMPARE1A( void ) { vPortYieldFromTick(); asm volatile ( "reti" ); } the "reti" instruction seems to have been optimized away. Is there a way to require that it not be optimized away? // Esorol
RE: Tick hook executed only oncePosted by MEdwards on October 26, 2010 As far as I thought, the only purpose of the volatile keyword after the asm was to prevent the reti being optimized away (and to prevent asm instructions from being reordered). Are you sure that is what is happening though? It might be that the reti is being placed inside vPortYieldFromTick(), I have seen that sort of behavior from GCC before and in this case would almost certainly cause a failure. Try looking at the assembly code in the debugger.
RE: Tick hook executed only oncePosted by Esorol on October 27, 2010 Hi Thanks for the reply. I compared the code which is generated with -O3 optimization level (does not work correctly) and that of -O2 optimization (works). In the -O2 optimization, the call to vPortYieldFromTick is compiled as a "subroutine" which is actually CALL-ed. The code snippet posted above thus generates two assembler instructions, CALL and RETI which is quite correct. At the -O3 level, however, the vPortYieldFromTick is inlined instead of CALL-ed. For some reason, the compiler then leaves out the RETI instruction, preferring the RET which is defined at the end of the vPortYieldFromTick function (see below). void vPortYieldFromTick( void ) __attribute__ ( ( naked ) ); void vPortYieldFromTick( void ) { portSAVE_CONTEXT(); vTaskIncrementTick(); vTaskSwitchContext(); portRESTORE_CONTEXT();
asm volatile ( "ret" ); }
So now that the error mechanism is detected, is there a need to "fix" this somehow? // Esorol
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|