Quality RTOS & Embedded Software

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




Loading

Simple test is ending up in WWDG_IRQHandler

Posted by Luke Peterson on September 23, 2011
I have a very basic piece of code that compiles and links without any errors:


// FreeRTOS includes
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

// STM32 Library includes
#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"

void configureUSART2();
void writebytesTask(void *params);

int main(void)
{
configureUSART2();
xTaskCreate(writebytesTask, (signed char *) "Task0", 100, (void *) 0, 1, NULL);
xTaskCreate(writebytesTask, (signed char *) "Task1", 100, (void *) 1, 1, NULL);
vTaskStartScheduler();
while(1){}
}

void writebytesTask(void *params)
{
long i = (long) params;
while (1) {
USART2->DR = i;
while (!(USART2->SR & USART_FLAG_TC)) {}
}
}


I have left out the definition of configureUSART2(), but I have tested it and know it works properly. When I flash this to my board (Olimex STM32-H107), I get no bytes sent out on USART2. When I run OpenOCD and gdb to see what is going on, I can step through each line, up to the call to vTaskStartScheduler(). After that point, it doesn't return (as expected), but no data is sent out either. When I hit CTRL-C in gdb to halt it, I get this:


Program received signal SIGINT, Interrupt.
WWDG_IRQHandler () at /home/luke/repos/roboticbicycle/MCP/src/startup_STM32F10X_CL.s:112


I haven't implemented WWDG_IRQHandler(), it is aliased to the Default_Handler in the startup assembly code (provided by STM and unmodified by me).

If I remove all the FreeRTOS code and replace the tasks with a single simple while loop that simply writes to USART2->DR and waits for the transmission to complete, I receive a continuous stream of data on the machine that I have connected to the Olimex board, so I am confident that this isn't merely some communication configuration problem.

What might be going on here and what am I doing wrong? Any ideas on how to debug this? I'm new to FreeRTOS and am not sure exactly how to debug things once the scheduler has started (any tips/pointers on this would be welcome).

Thanks,
~Luke

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Richard on September 23, 2011
Is WWDG the watchdog? Disable the watchdog.

Regards.

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Jack Peacock on September 23, 2011
WWDG is the Windowed Watchdog timer for the STM32 series controllers. The IRQ is an early warning interrupt that the timer is about to cause a reset. If you don't enable the interrupt in your code then most likely the error message is not reliable.

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Luke Peterson on September 23, 2011
WWDG is the Watchdog. I have not enabled it.

I think the reason it is jumping to that location may have to do with the fact that FreeRTOS needs a few of its functions put into the vector table of the startup code, and since I haven't done that, it happens to be jumping to the WWDG handler (aliased to Default_Handler) instead of the proper FreeRTOS handler. I will examine the startup files in the demos to make sure of this.

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Richard on September 23, 2011
“WWDG is the Watchdog. I have not enabled it.”


Try disabling it all the same. It might be enabled by default (not uncommon) or enabled in the start up code.

“I think the reason it is jumping to that location may have to do with the fact that FreeRTOS needs a few of its functions put into the vector table of the startup code, and since I haven't done that, it happens to be jumping to the WWDG handler (aliased to Default_Handler) instead of the proper FreeRTOS handler. I will examine the startup files in the demos to make sure of this.”


You need the SysTick, PendSV and SVC handlers installed. If the vector table is CMSIS compliant you can install them simply by adding the following lines to FreeRTOSConfig.h:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler


Regards.

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Richard on September 23, 2011
It also looks like both your tasks are trying to access the same volatile UART registers simultaneously. That will be unpredictable, at least.

Regards.

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Luke Peterson on September 23, 2011
Adding this to FreeRTOSConfig.h did the trick:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler


I see what you mean about the two tasks accessing the same register. I changed it to just one task, and now it streams the data out reliably. I suppose the proper way to protect the USART data register and the USART status register would be to use a semaphore or a mutex, correct?

~Luke

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Richard Damon on September 23, 2011
Normally I don't use semaphores to protect a device, but keep the device under the control of a single task, and only that task directly controls the device. For serial output like this, another option (for many architectures) is to define an output subroutine (callable by any task) that puts the data in a queue and if the serial channel is inactive, forces a serial interrupt. The interrupt routine then is what has exclusive control to the hardware, and it check if data is waiting, and the port is available, and if so, sends the character out. This keeps that tasks from going into a spin wait, waiting to send their character, but they instead block on the queue, letting other tasks have time.

RE: Simple test is ending up in WWDG_IRQHandler

Posted by lafleur on September 23, 2011
Richard

Do you have any sample code that you might share on how you build your serial interface??

thanks

RE: Simple test is ending up in WWDG_IRQHandler

Posted by Richard Damon on September 24, 2011
A lot of details a processor specific, but here is a general outline:


xQueueHandle txque; /* Init to a queue to hold characters to send */
void putchar(char c){
xQueueSendToBack(txque, &c, portMAX_DELAY);
if( __serial_tx_empty__){ /* test for transmitter possible stopped */
__force_serial_tx_interrrupt__;
}
}

void serial_tx_intterrupt_handler(){
portBASE_TYPE woken = 0;
portBASE_TYPE flag;
char c;

while(__tx_buffer_not_full__){
flag = xQueueReceiveFromISR(txque, &c, &waswoken);
if(flag){
__tx_buffer__ = c;
} else {
break; /* no more to send */
}
portEND_SWITCHING_ISR(woken);
}



[ 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