« 2011年5月 | トップページ | 2011年10月 »

2011年7月の記事

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

6月に自宅PCをiMacにリプレースし、当初はWinodwsを動かすためにBoot Campを使っていたのですが、Parallelsを使った仮想環境に変更しました。Parallelsの使用は当初考えたのですが、Windowsの起動回数はきっと減ると思っていたため結構お高いParallelsはペイしないと考えて回避していました。ここに至る変遷と試行錯誤を記載します。


我が家におけるWindowsの必要シーン

Mac OSのきびきびした動作ときれいな画面に慣れると、できるだけ多くの作業をMacに移したくなるのですが、我が家の場合、以下のソフト・作業はWindowsベースとなります:

  1. LPCExpressoのIDEとVisual Studio (主にC#)
  2. かみさんが使う家計簿ソフト(家計簿マム): Macの家計簿ソフトへの移行も考えましたが、データ移行が難しく(どうしても欠落してしまうデータが発生)断念
  3. はがき印刷 :年に1回なのでソフトを買い換えるまでもない
  4. このブログ作成(Windows Live Writerを使用): そのうちMacのソフト(Mars Editあたりかな)に変わるかも
  5. ゲームはやらない: グラフィック性能は重視しない

あと外せない条件は、かみさんとアカウントを分けてMacを共有するため、Windowsもそれぞれのアカウントから起動できる必要があります。そのため仮想環境を使った場合、仮想ディスクイメージを共有フォルダに置くなどして、複数アカウントで共有できる必要があります。

冒頭に書いたとおり、Windows環境にあまりお金をかけたくなかったため、先ずはフリーのVirtualBoxを使った仮想化を検討しました。グーグルさまで、マルチアカウントにてVMを共有した事例があるかを調べたのですがヒットせず。インストール回数を浪費しないよう、試しにUbuntuを使って共有を実験したのですがうまくいかない感じ(VirtualBoxでのUSBの認識に問題があり、早々に放棄したため突っ込んで調べてはいません)。

頻繁に起動することはないのでBoot Campを使ったデュアルブートに決定。


Boot Camp

アップル純正のデュアルブート環境なので当然ちゃんと動きますが、使ってみると以下の点が不満。

  • やっぱり起動が遅い: EFIによるハードの認識や初期化時間がばかにならい
  • Mac OSに戻すもの再起動になるため時間がかかる。やっぱり、Mac OSとWindowsの間を行ったり来たりするのでこのオーバーヘッドが無視できない
  • Mac用のMouse, Trackpadを使うとなにやら動きがギクシャク。普通のUSBマウスを使った方がスクロールなどが滑らかに動きます。アップルさん、Windows用ドライバ開発でわざと手を抜いてないか?

結局Parallelsに

Boot Campが今一つなので、Parallelsの情報をあさっていると、複数ユーザで仮想環境を共有できることが分かりました。あと、Boot Campパーティションから仮想マシンを起動することもできるため、これまでに構築したWindows環境も有効に使えそうです。試用版があるのでお試しに使ってみることにしました。

1. Boot Campパーティションからの起動

Boot Camp領域を使う仮想マシンを作ると数MB程度の仮想ディスクイメージ(実体はboot campパーティションにあるので、管理情報だけでしょうか)が作られます。仮想マシンを作成する際に「共有」を選択すると、自動的にUsers/Shared配下にファイルを作成し適切なアクセス権を設定してくれるのですが、サブアカからの起動がどうもうまくいかず。ファイルサイズは小さいので各ユーザフォルダー配下に仮想マシンをつくれば複数アカウントでWindowsを起動できました。

これで運用ができるのですが、制約はサスペンドです。Parallelsのサスペンド・復帰は非常に高速で、自分の環境では10秒以下。Windowsの休止だとブートとたいして時間が変わらない印象があるのですが、これなら十分使えます。Boot Campパーティションから起動した場合、サスペンドはできるのですが、別アカウントから復帰を試みると起動に失敗します。この際、ディスクに不整合が発生する可能性があるようなので危険です。

あと、Boot Campを使った仮想マシンからアプリを立ち上げると、アクティベーションを必要とするアプリの場合、再アクティベーションが発生します。どうも、最初にインストールした生のBoot Campと異なる環境で起動されたと思うようです。自分は気がつかなかったのですが、Web情報ではWindowsも再アクティベーションが発生するようで、その場合マイクロソフトは仮想環境は別ライセンスとみなしアクティベーションを許可しないとのこと。

2. Boot Campを仮想ディスクにインポート

サスペンドとライセンスの問題を考えると、結局仮想ディスクにWindows全体をインストールするのが最善です。一からインストールし直すのもきついので、仮想マシンへのインポート機能を使って、Boot Camp領域のファイルを仮想マシン(仮想ディスク)に取り込んでみました。

インポートはうまくいったのですが、ファイルがホームディレクトリ配下にできてしまいました。これではアカウント間で共有ができないため、共有フォルダに移動してアクセス権を変更。Everyoneやstaffに対して読み書きを許可するも、非オーナのアカウントからはアクセス権違反でVMを起動できず。仮想ディスクファイルにはACLを使ったカスタムアクセス権が設定されており、このあたりをあわせこまないとだめなのか。

アクセス権をうまく設定できないため、インポート作戦も結局放棄。

3. 仮想ディスクに再インストール

仕方なく、Boot Campパーティションを削除して1からやり直しです・・ やっと目的の動作を実現。

仮想マシンを共有環境で動かすと、以下の通りなかなか快適で、やっぱりこれがベストです:

  • マウス・トラックパッドの動きが滑らか。LionのゲストOSにすれば、3本指ドラッグやナチュラルスクロール(Windowsとタッチの方向が逆になるやつ)など、OS Xネイティブの操作も使えます
  • サスペンドと復帰が高速。サスペンドと復帰を別のアカウントで行っても問題なし
  • OS XとWindowsを同時に使えるので、両OS間を行ったり来たりする際のオーバーヘッドが殆どない
  • Boot CampパーティションからVMを起動する場合に比べて、仮想ディスクだとI/O速度が落ちることを懸念しましたが殆ど気にならないレベル

ということで、Parallels正規ライセンスの購入決定。


4. 使用マシンのスペック

項目 スペック
マシン iMac Mid 2011(27インチ)
CPU Core i5 2.7GHz
メモリ 12GB
グラフィックス Radeon HD 6770M
仮想化ソフト Parallels Desktop 6  (6.0.12094)
ホストOS OS X 10.7 (Lion)
ゲストOS Windows 7 SP1

 

5. Windowsエクスペリエンス値

当初、メモリ4Gで仮想環境を動かしたのですが、さすがにメモリ不足。メモリを8G追加して12Gにしたところパフォーマンスが改善されました。仮想環境は8G以上が必須ですね。Windows 7のエクスペリエンス値を以下に示します。

メモリ4Gで仮想マシンに1G割り当て(CPUコアは2個割り当て)

Win7Experience4G-1G


メモリ 12Gで仮想マシンに2G割り当て(CPUコアは2個割り当て)

Win7Experience12G-2G

メモリ増設でメモリ性能が改善しました。仮想環境を使わずに直接Windowsを起動した場合の値を忘れてしまったのですが、殆ど遜色がないレベルかもです(少なくともMac以前に使っていたCore2 Quad 3.0GHzより上です)。


おわりに

短期間にWindowsを2回もクリーンインストールしたので、しばらくはやりたくないです。SP1より前のインストールメディアだとアップデートが超面倒。後、久々にインストール回数が超過して電話でアクティベーションを依頼するはめになりました(MSさまには夜中の3時過ぎに電話してしまいました)。

今考えると、Boot Campからインポートした仮想ディスクファイルに実行許可ビットを立てればよかったのかも。GUIの設定では実行許可は出てこないので見落としました。後々の手間を考えるともう少し粘るべきだったか・・

色々変遷があり手間もかかりました。Parallelsに関しては、ちとお高いですが価格相応の価値はあり満足です。

LPCXpresso LPC1769でFatFsを動かす–USB Host編

LPCXpresso LPC1769でmicro SDカードの読み書きとDMA転送の実験を行いましたが、借用したコードにNXP提供のUSB Hostドライバ(USB Host Lite)が入っていることが分かりました。こいつを使えば、LPCXpressoでUSBメモリーの読み書きもできるということなので、遅まきながら試してみました。


使用したコード

これまで使用した、ChaN's FAT-code with interface for NXP LPC17xx (LPC1766, LPC1768 and others)を使っています。USBドライバの部分はそのまま使用できましたが、以下の2箇所は変更が必要でした。

1. USB Host Liteの有効化とパラメータの変更

USB Host Liteはデフォルトでは無効になっているため、プロジェクトのプロパティー → Build Settings → Symbolsに”WITH_USB_MS=1”を追加します。加えて、ffconf.hの以下の部分を変更します。

/*---------------------------------------------------------------------------/
/ Physical Drive Configurations
/----------------------------------------------------------------------------*/

#if WITH_USB_MS
#define _DRIVES		2   // 2に変更
/* Number of volumes (logical drives) to be used. */
#else
#define _DRIVES		1
#endif

(2011/7/20修正)
2. ff_test_term.cの変更

fiコマンドで論理ドライブを初期化した際に、FatFSのf_mount()関数を呼んでいますが、FatFSのドライブ変更を行っていないため、FatFSは依然としてデフォルトのDrive = 0をポイントしたままになっています。そのため、f_chdrive()を呼んでカレントドライブの変更を行う処理を追加しました。変更した箇所は以下の部分です:

int ff_test_term(void)
{
  
  // ---- snip -----

	for (;;) {
		xputc('>');
		get_line(Line, sizeof(Line));

		ptr = Line;
		switch (*ptr++) {

  // ---- snip -----

		case 'f' :
			switch (*ptr++) {

			case 'i' :	/* fi <log drv#> - Initialize logical drive */
				if (!xatoi(&ptr, &p1)) break;
				put_rc(f_mount((BYTE)p1, &Fatfs[p1]));
				res = f_chdrive((BYTE)p1);							// Added by todotani
				if (res) {
					xprintf("Failed to change current drive.\n");
				}
				break;

		}

	}
}

当初はFatFSのf_mount()関数を修正することで対処したのですが、アプリ部分のが正しくFatFSのAPIを使っていなかったことになります。

ff.cのf_mount()を一箇所だけ変更しています。このサンプルではff_test_term.cという対話型のshellを使いますが、SDカードを使用する場合はDrive 0, USBメモリはDrive 1を指定します。Drive 1を指定した場合でも、内部的に初期値のDrive 0を指定したままになっておりUSBメモリのFAT構造体を参照できないため、f_mount()関数に1行追加を行いました。神のごときChaN様のコードをいじるなど恐れ多きことですが、この変更で動いてくれました。追加を行った部分を以下に示します。32行目が追加したコードです。

コード全体はこちらからダウンロードできます: LPC1769_FatFS_USBv2.zipをダウンロード


LPCXpressoとUSBコネクタの接続

以前自作したLPCXpresso用拡張基盤の空きスペースにUSB Aコネクタを追加しました。コネクタを追加した写真を以下に示します。

FatFS_USB_20110718

USBコネクタとの接続はmbed用Starboard Orangeの回路を参考にして、以下のように行いました:

  • MCU (LPC1769)のUSB D+/D-ピンを直接USBコネクタに接続しています。LPC17xxのUser manual 13.7.2章では、D+/D-に33Ωの抵抗を直列に挿入すること、D+/D-を15KΩの抵抗でプルダウンすることが示されており抵抗を入れたほうがよいかもしれませんが、USBケーブルの引き回しがない写真の状態ではとりあえず動いています。
  • +5Vの給電を行っているため、5Vラインに保護用のポリスイッチを入れています
  • +5V – GND間に47uF, 0.1uFのコンデンサを挿入


動作試験

これまでと同様にff_test_term.cを使って転送速度を計ってみます。結果は以下のとおりでした。

Hello from the ChaN FatFs Demo on LPC1700
Version 0.0.2, Martin Thomas 7/2010
xprintf is working
CPU Clock:        120MHz
Peripheral Clock: 60MHz
SPI Clock:        30MHz

FatFs module test monitor for LPC17xx/SSP
LFN Enabled, Code page: 1252

>di 1
rc=0
>
>fi 1
rc=0 FR_OK
>
>fs
FAT type = FAT16
Bytes/Cluster = 32768
Number of FATs = 2
Root DIR entries = 512
Sectors/FAT = 239
Number of clusters = 60986
FAT start (lba) = 8066
DIR start (lba,clustor) = 8544
Data start (lba) = 8576

...1 files, 30000000 bytes.
0 folders.
1951552 KB total disk space.
1922240 KB available.
>
>
>fl
----A 2010/07/15 11:58  30000000  test1.txt     
   1 File(s),  30000000 bytes total
   0 Dir(s), 1968373760 bytes free
>
>fo 10 test2.txt
rc=0 FR_OK
>
>fw 10000000 62
10000000 bytes written with 576 kB/sec.
>fw 10000000 63
10000000 bytes written with 393 kB/sec.
>fw 10000000 64
10000000 bytes written with 398 kB/sec.
>
>
>fc
rc=0 FR_OK
>
>fl
----A 2010/07/15 11:58  30000000  test1.txt     
----A 2010/07/15 11:58  30000000  test2.txt     
   2 File(s),  60000000 bytes total
   0 Dir(s), 1938358272 bytes free
>
>
>fo 1 test2.txt
rc=0 FR_OK
>
>fr 10000000
10000000 bytes read with 682 kB/sec.
>fr 10000000
10000000 bytes read with 442 kB/sec.
>fc
rc=0 FR_OK
>
>fo 1 test1.txt
rc=0 FR_OK
>fr 10000000
10000000 bytes read with 682 kB/sec.
>fr 10000000
10000000 bytes read with 442 kB/sec.
>fr 1000000
1000000 bytes read with 442 kB/sec.
>
>fc
rc=0 FR_OK
>

結果はリードで682KB/sec (5.4Mbps)とあまりふるわず。SDメモリでは2149KB/sec出たため、1/3以下の性能です。LPC17xxのUSB Hostは12Mbps動作(Full speed)なので、USBプロトコルのオーバヘッド(詳細分かっていませんが)を加味すると妥当な線なのかも知れません。


おわりに

USB Hostの制御をどのようにやっているのかソースを追ってみたのですが、サッパリ分かりませんでした。

usbhost_lpc17xx.cのHost_ProcessTD()関数の中でTransfer descriptorを組み立て、転送をキックしているように見えるのですが、パラメータの意味が分かりません。LPC17xxのマニュアルを見ると、詳細はOHCI (Open Host Controller Interface)のドキュメント参照とさらっと書いてあるだけなので、OHCIの仕様書を読まないとだめそうです。ドキュメントはダウンロードしましたが、160ページの英語文書なのでハードル高そうです。

« 2011年5月 | トップページ | 2011年10月 »

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      
無料ブログはココログ