« Parallels DesktopでWindows on Mac | トップページ | XBee APIモードライブラリのLPCXpressoへの移植 »

LPCXpresso LPC1769でFree RTOSを使う

既に多くの方が紹介していますが、LPCXpresso LPC1769でFree RTOSを動かしてみました。

ネタとしては、LPCXpresso supportにFree RTOSカーネルのLPC17XX版とデモが掲載されており、ダウンロードしたファイルからSimpleDemo, FreeRTOSプロジェクトをインポートするだけでLチカのデモが動きます。FreeRTOSプロジェクトをインポートすると、以下のようにFreeROTSカーネルがライブラリとして登録されます。このFreeRTOS_Libraryを使って、新規のFreeRTOSプロジェクトを作ってみます。

FreeRTOS_Library

 

LPCXPresso IDEの新規プロジェクト生成

執筆時点で最新のIDE Version 4.0.5にはNew Projectウイザードに「FreeRTOS Projcet」なるものがあります(3.xにありましたっけ。3.xは消してしまったので忘れました・・)。このウイザードはFreeRTOS 7.0.1のソースツリーをc:\FreeRTOSV7.0.1\FreeRTOS\Sourceに展開していることを前提にしているようです。そのため、このウイザードは使用しません。今回は、普通にC Projcetを選択します。

新規C Projectを起こしたら、SimpleDemoと同様に、Include path, Library, Library Pathを設定します。加えてsrcフォルダにFreeRTOSConfig.hをコピー。後は、main.cにFreeRTOSを使ったコードを書き込んでコンパイル!


何かが足りない

当初はライブラリの設定だけで動くと思ったのですが、これだけでは動きません。デバッガでトレースしてみるとタスクの登録は正しく出来ていますが、タスクが起動しないように見えます。

問題はスタートアップコードでした。新規プロジェクトを生成した際に自動的にsrcディレクトリに書き込まれるcr_startup_lpc176x.cではなく、SimpleDemoに添付されている、cr_startup_lpc17.cを使う必要があります。

cr_startup_lpc17.cでは、リストの最終行に示すとおり、SysTick handlerをFreeRTOSカーネル内のルーチンに変更しています。これがないと、FreeRTOSのスケジューラーが動かずタスクが起動しないというオチでした。

//*****************************************************************************
//
// The vector table.
// This relies on the linker script to place at correct location in memory.
//
//*****************************************************************************
extern void (* const g_pfnVectors[])(void);
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
	// Core Level - CM3
	&_vStackTop, // The initial stack pointer
	ResetISR,								// The reset handler
	NMI_Handler,							// The NMI handler
	HardFault_Handler,						// The hard fault handler
	MemManage_Handler,						// The MPU fault handler
	BusFault_Handler,						// The bus fault handler
	UsageFault_Handler,						// The usage fault handler
	0,										// Reserved
	0,										// Reserved
	0,										// Reserved
	0,										// Reserved
	vPortSVCHandler,                        // SVCall handler
	DebugMon_Handler,						// Debug monitor handler
	0,										// Reserved
	xPortPendSVHandler,                     // The PendSV handler of FreeRTOS kernel
	xPortSysTickHandler,                    // The SysTick handler of FreeRTOS kernel

Free RTOSを使ったサンプル

タスクを2つ起動して、周期的にコンソールにメッセージを出力するサンプルを作ってみました。シリアルポートへの書き込みが2つのタスクで同時に発生しないように、セマフォを使って排他処理を行っています。

/*
======================================================
  Free RTOS Demo
  Use semaphore
======================================================
*/

#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "uart0.h"

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

static void vTask1(void *pvParameters);
static void vTask2(void *pvParameter);

#define TASK_PRIORITY	( tskIDLE_PRIORITY + 1 )

xSemaphoreHandle semaphore = NULL;

// Variable to store CRP value in. Will be placed automatically
// by the linker when "Enable Code Read Protect" selected.
// See crp.h header for more information
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;

#include <stdio.h>

// TODO: insert other definitions and declarations here

int main(void) {
	UART0_Init(115200);
	printf("Main Start\n");

	semaphore = xSemaphoreCreateMutex();
	if (semaphore != NULL) {
		int res;
		res = xTaskCreate(vTask1, (signed char *)"Task1", 100, NULL, 1, NULL);
		res = xTaskCreate(vTask2, (signed char *)"Task2", 100, NULL, 1, NULL);

		vTaskStartScheduler();
	} else {
		printf("Semaphore creation failed\n");
	}
	
	// Enter an infinite loop
	while(1) { }
	return 0 ;
}


static void vTask1(void *pvParameters)
{
	static int count = 1;

	while(1) {
		if (xSemaphoreTake(semaphore, portMAX_DELAY) == pdTRUE) {
			printf("Task1:%d\n", count++);
			xSemaphoreGive(semaphore);
			vTaskDelay(2000);
		}
	}
}

void vTask2(void *pvParameter)
{
	static int count = 1;

	while(1) {
		if (xSemaphoreTake(semaphore, portMAX_DELAY) == pdTRUE) {
			printf("  Task2:%d\n", count++);
			xSemaphoreGive(semaphore);
			vTaskDelay(4000);
		}
	}
}

« Parallels DesktopでWindows on Mac | トップページ | XBee APIモードライブラリのLPCXpressoへの移植 »

NXP-ARM」カテゴリの記事

コメント

この記事へのコメントは終了しました。

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ