Quality RTOS & Embedded Software

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




Loading

vTaskDelay() does not work as expected

Posted by Murat Ursavas on January 26, 2012
Hi,

I'm a newbie about FreeRTOS and checked the forum for my problem but couldn't find anything.

My purpose is simply making FreeRTOS run two tasks concurrently with different frequencies. I'm using vTaskDelay to create frequency difference. From my readings, tasks should wait with (given value) * (tick period). In the mean time, while in the DELAYED state, the other task should run (both tasks have the same priority).

Here is my code:

main.c
#include 

#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"

xTaskHandle TaskHandle1;
xTaskHandle TaskHandle2;

void TaskFunction1(void *);
void TaskFunction2(void *);

int main(void)
{
SystemInit();

printf("Hello World!\n");

xTaskCreate(TaskFunction1, // pointer to function
"Task1", // Task name string for debug purposes
100, // Stack depth as word
NULL, // function parameter (like a generic object)
1, // Task Priority (Greater value has higher priority)
&TaskHandle1); // Task handle

xTaskCreate(TaskFunction2, // pointer to function
"Task2", // Task name string for debug purposes
100, // Stack depth as word
NULL, // function parameter (like a generic object)
1, // Task Priority (Greater value has higher priority)
&TaskHandle2); // Task handle

printf("Task Handles: Task1=%u, Task2=%u\n", TaskHandle1, TaskHandle2);

vTaskStartScheduler();

for(;;);
}


void TaskFunction1(void *pvParameters)
{
for(;;)
{
vTaskDelay(10);
printf("Task 1\n");
}
}

void TaskFunction2(void *pvParameters)
{
for(;;)
{
vTaskDelay(30);
printf("Task 2\n");
}
}


FreeRTOSConfig.h
#define configUSE_PREEMPTION1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( portTickType ) 10000 )
#define configMAX_PRIORITIES( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN( 16 )
#define configUSE_TRACE_FACILITY0
#define configUSE_16_BIT_TICKS0
#define configIDLE_SHOULD_YIELD1

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

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet1
#define INCLUDE_uxTaskPriorityGet1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources0
#define INCLUDE_vTaskSuspend1
#define INCLUDE_vTaskDelayUntil1
#define INCLUDE_vTaskDelay 1

/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY 255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */


/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15. This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY15


I'm using IAR 6.3 and debugging with it's simulator. Everything compiles fine. But I just receive some errors from debugger:

Here is the debugger log:
Thu Jan 26, 2012 09:39:57: Download complete. 
Thu Jan 26, 2012 09:39:57: Loaded debugee: D:\RASATRON\Projects\Experiments\IAR FreeRTOS Trial 1\Debug\Exe\IAR_FreeRTOS_T1.out
Thu Jan 26, 2012 09:39:57: Target reset
Thu Jan 26, 2012 09:39:57: non-empty line in wrong state
Thu Jan 26, 2012 09:39:57: There was 1 errors during the initialization of the debugging session.
Thu Jan 26, 2012 09:39:57: Error (col 15): No such field.
Thu Jan 26, 2012 09:39:57: Error (col 15): No such field.
Thu Jan 26, 2012 09:39:57: Error (col 15): No such field.
Thu Jan 26, 2012 09:39:57: Error (col 1): Unknown or ambiguous symbol. uxTaskNumber


RE: vTaskDelay() does not work as expected

Posted by Richard on January 26, 2012
You have not said what microcontroller you are using, what debugger you are using, what compiler you are using, or even what your problem is. Any answer will be pure guesswork, which is not an efficient way of proceeding. That said, having looked at your code, I would suggest the biggest problem you are going to have is your use of printf(). Try flashing LEDs instead. Printf is likely to overflow your stack, try using a non-existent heap, not be reentrant, take a long time to complete, and depending on the output mechanism do really weird things to interrupts/execution profile/stalling the CPU/etc. Of course, none of those things might be true, but like I said, the information you provide only allows guess work.

Regards.

RE: vTaskDelay() does not work as expected

Posted by Murat Ursavas on January 26, 2012
Sorry Richard,

You're right, I've left many things a bit vague.

Micro is STM32F107VC
Compiler is already mentioned as IARCC. (EWARM 6.30.3)
Debugger is already mentioned as C-SPY Debugger / Simulator. (with semihosting)

My problem is, with given code, I can trace to vTaskStartScheduler(), then the tasks stay at DELAYED state and never run the code. (Tried it with both heap_1.c and heap_2.c)

printf is a suspicious function like you said, but not this time. Without vTaskDelay(), printf works just fine. I can see the terminal output.

I'll try it with real hardware and LED's like you suggested.

P.S: If I change tasks like below, can see "Task1" and "Task2" strings in the terminal.


void TaskFunction1(void *pvParameters)
{
for(;;)
{
printf("Task 1\n");
taskYIELD();
}
}

void TaskFunction2(void *pvParameters)
{
for(;;)
{
printf("Task 2\n");
taskYIELD();
}
}

RE: vTaskDelay() does not work as expected

Posted by Dave on January 26, 2012
“My problem is, with given code, I can trace to vTaskStartScheduler(), then the tasks stay at DELAYED state and never run the code.”


Do you mean the tasks run to the vTaskDelay(), but never return from that? If so, is your tick interrupt running? Is the FreeRTOS tick interrupt handler installed in the vector table?

If you are using printf like that, disable the scheduler first, then call printf, then flush the output, then enable the scheduler again. That is ok for a test app, but I would not do it in a real ap as most of the time the scheduler wont be running.

RE: vTaskDelay() does not work as expected

Posted by Dave on January 26, 2012
Just noticed you are using the simulator. That might be ok, but I don't think you will get much more from Richard until you try it on real hardware.

RE: vTaskDelay() does not work as expected

Posted by Murat Ursavas on January 26, 2012
Hi Dave and Richard,

Turns out, everything works fine with real hardware, even with printf. It means the IAR simulator does not get along with FreeRTOS (or maybe with STM32 and/or it's interrupt sources)... That's a pity...

Thanks for your generous help.

RE: vTaskDelay() does not work as expected

Posted by Richard on January 26, 2012
It is nothing to do with FreeRTOS - FreeRTOS is just source code that runs on the CPU, and the simulator is simulating the CPU. That is normally the problem - it simulates the CPU and just the CPU. If you want IAR to simulate interrupts you have to configure the debugger using scripts (or some other method, I forget exactly). I don't think it will do it otherwise.

Happy to hear you have your code running.

Regards.

RE: vTaskDelay() does not work as expected

Posted by Murat Ursavas on January 27, 2012
Hi,

I've successfuly managed to run the code on C-SPY Simulator and writing down here to help others.

As you said Richard, Interrupts can be enabled by macros, but with IAR 6.3 you can directly create and edit an interrupt via dialog boxes.

Here is the sequence:

Enable Simulator from Target Options/Debugger Section.
Simulator menu will appear in the main menu bar.
Choose Simulator / Interrupt Setup
In a default situation there won't be an interrupt source. Click "New"
"Edit Interrupt" dialog will appear.
Choose SysTick Interrupt from the list.
Leave the description as it is
Write 2 x configTICK_RATE_HZ to the "First Activation" section (To simulate SystemInit() time)
Write configTICK_RATE_HZ to the "Repeat Interval"
And then OK everything and RUN your simulation.

P.S: I saw that just SysTick interrupt is not enough to run and as you know FreeRTOS also needs PendSV. If you do the setup above, PendSV appears automatically. But if it wouldn't, just add PendSV interrupt to the sources with Repeat interval as "configTICK_RATE_HZ + 5" (that's what I saw with the automatic source creation)


[ 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