cphus wrote on Wednesday, September 19, 2012:
Hello freeRTOS,
This is my first experience ever with an RTOS. I managed to build a custom freeRTOS project for this board
The MCU is LPC1768 and the version of freeRTOS I use is 7.1.1. Compiler is from CodeSourcery Lite (arm-none-eabi-gcc v4.5.2)
I modified a blinking example that succesively blinks four led’s to blink another four in another task at an another rate just to see that the task switching mechanism works.
Then I tried to output something on UART in one of the tasks but the code hangs and the LED’s don’t blink anymore.
I must state that the code for UART is from another example for this particular board that works: I tested it with minicom - so nothing is wrong with the driver…
Next, I’ll reproduce the code from main.c. Note at the end of function vHB1 the calls for initializing the UART 0 and sending a string on it. I have intentionately put it at the end to see that the led’s blink in the order 0-1-2-3-2-1 and then hang.
/* ---- Include Files ---------------------------------------------------- */
#include "stdio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "serial.h"
/* ----------------------------------------------------------------------- */
#define HEARBEAT_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define HEARTBEAT_STACK_SIZE configMINIMAL_STACK_SIZE
#define LED_0 ( 1UL << 0UL )
#define LED_1 ( 1UL << 1UL )
#define LED_2 ( 1UL << 2UL )
#define LED_3 ( 1UL << 3UL )
#define LED_4 ( 1UL << 4UL )
#define LED_5 ( 1UL << 5UL )
#define LED_6 ( 1UL << 6UL )
#define LED_7 ( 1UL << 7UL )
static unsigned long gLed[] = { LED_0, LED_1, LED_2, LED_3, LED_4, LED_5, LED_6, LED_7 };
/***************************************************************************
*
* Initialize the GPIO pin that the LED is connected to.
*
***************************************************************************/
static void LED_Init( void )
{
LPC_GPIO2->FIODIR = LED_0 | LED_1 | LED_2 | LED_3 | LED_4 | LED_5 | LED_6 | LED_7;
LPC_GPIO2->FIOCLR = LED_0 | LED_1 | LED_2 | LED_3 | LED_4 | LED_5 | LED_6 | LED_7;
}
/***************************************************************************
*
* Turns the LED on or off. On the robovero, driving the pin low turns the
* LED on.
*
***************************************************************************/
static void SetLED( unsigned led, unsigned value )
{
if( value )
LPC_GPIO2->FIOSET = gLed[led];
else
LPC_GPIO2->FIOCLR = gLed[led];
}
/***************************************************************************
*
* Initializes the chip.
*
***************************************************************************/
static void InitHardware( void )
{
/* Disable peripherals power. */
LPC_SC->PCONP = 0;
/* Enable GPIO power. */
LPC_SC->PCONP = PCONP_PCGPIO;
/* Disable TPIU. */
LPC_PINCON->PINSEL10 = 0;
if ( LPC_SC->PLL0STAT & ( 1 << 25 ) )
{
/* Enable PLL, disconnected. */
LPC_SC->PLL0CON = 1;
LPC_SC->PLL0FEED = PLLFEED_FEED1;
LPC_SC->PLL0FEED = PLLFEED_FEED2;
}
/* Disable PLL, disconnected. */
LPC_SC->PLL0CON = 0;
LPC_SC->PLL0FEED = PLLFEED_FEED1;
LPC_SC->PLL0FEED = PLLFEED_FEED2;
/* Enable main OSC. */
LPC_SC->SCS |= 0x20;
while( !( LPC_SC->SCS & 0x40 ) );
/* select main OSC, 12MHz, as the PLL clock source. */
LPC_SC->CLKSRCSEL = 0x1;
LPC_SC->PLL0CFG = 0x20031;
LPC_SC->PLL0FEED = PLLFEED_FEED1;
LPC_SC->PLL0FEED = PLLFEED_FEED2;
/* Enable PLL, disconnected. */
LPC_SC->PLL0CON = 1;
LPC_SC->PLL0FEED = PLLFEED_FEED1;
LPC_SC->PLL0FEED = PLLFEED_FEED2;
/* Set clock divider. */
LPC_SC->CCLKCFG = 0x03;
/* Configure flash accelerator. */
LPC_SC->FLASHCFG = 0x403a;
/* Check lock bit status. */
while( ( ( LPC_SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );
/* Enable and connect. */
LPC_SC->PLL0CON = 3;
LPC_SC->PLL0FEED = PLLFEED_FEED1;
LPC_SC->PLL0FEED = PLLFEED_FEED2;
while( ( ( LPC_SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );
/* Configure the clock for the USB. */
if( LPC_SC->PLL1STAT & ( 1 << 9 ) )
{
/* Enable PLL, disconnected. */
LPC_SC->PLL1CON = 1;
LPC_SC->PLL1FEED = PLLFEED_FEED1;
LPC_SC->PLL1FEED = PLLFEED_FEED2;
}
/* Disable PLL, disconnected. */
LPC_SC->PLL1CON = 0;
LPC_SC->PLL1FEED = PLLFEED_FEED1;
LPC_SC->PLL1FEED = PLLFEED_FEED2;
LPC_SC->PLL1CFG = 0x23;
LPC_SC->PLL1FEED = PLLFEED_FEED1;
LPC_SC->PLL1FEED = PLLFEED_FEED2;
/* Enable PLL, disconnected. */
LPC_SC->PLL1CON = 1;
LPC_SC->PLL1FEED = PLLFEED_FEED1;
LPC_SC->PLL1FEED = PLLFEED_FEED2;
while( ( ( LPC_SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );
/* Enable and connect. */
LPC_SC->PLL1CON = 3;
LPC_SC->PLL1FEED = PLLFEED_FEED1;
LPC_SC->PLL1FEED = PLLFEED_FEED2;
while( ( ( LPC_SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );
/* Setup the peripheral bus to be the same as the PLL output (64 MHz). */
LPC_SC->PCLKSEL0 = 0x05555555;
}
void vHB1( void * pvParameters )
{
unsigned int led[] = { 0, 1, 2, 3, 2, 1 };
unsigned int led_idx = 0;
/* Setup the LED */
LED_Init();
for(;;)
{
SetLED(led[led_idx], 1);
vTaskDelay( 100 / portTICK_RATE_MS );
SetLED(led[led_idx], 0);
vTaskDelay( 100 / portTICK_RATE_MS );
SetLED(led[led_idx], 1);
vTaskDelay( 100 / portTICK_RATE_MS );
SetLED(led[led_idx], 0);
vTaskDelay( 700 / portTICK_RATE_MS );
led_idx++;
if( led_idx >=6 )
{
led_idx = 0;
SER_init(0);
SER_putString(0, "vHB2...\n\r");
}
}
}
void vHB2( void * pvParameters )
{
unsigned int led[] = { 7, 6, 5, 4, 5, 6 };
unsigned int led_idx = 0;
/* Setup the LED */
LED_Init();
for(;;)
{
SetLED(led[led_idx], 1);
vTaskDelay( 60 / portTICK_RATE_MS );
SetLED(led[led_idx], 0);
vTaskDelay( 60 / portTICK_RATE_MS );
SetLED(led[led_idx], 1);
vTaskDelay( 60 / portTICK_RATE_MS );
SetLED(led[led_idx], 0);
vTaskDelay( 420 / portTICK_RATE_MS );
led_idx++;
if( led_idx >=6 )
{
led_idx = 0;
}
}
}
/***************************************************************************
*
* main
*
***************************************************************************/
int main( void )
{
InitHardware();
xTaskCreate( vHB1, // Task Function
"Heartbeat1", // Task Name
HEARTBEAT_STACK_SIZE, // Stack Size
NULL, // Parameters
HEARBEAT_PRIORITY, // Task Priority
NULL ); // Place to store task handle
xTaskCreate( vHB2, // Task Function
"Heartbeat2", // Task Name
HEARTBEAT_STACK_SIZE, // Stack Size
NULL, // Parameters
HEARBEAT_PRIORITY, // Task Priority
NULL ); // Place to store task handle
vTaskStartScheduler();
/* Will only get here if there was insufficient memory to create the idle
* task. The idle task is created within vTaskStartScheduler().
*/
for( ;; )
;
}