NXP LPC1768 Application on FreeRTOS
FreeRTOSの使用状況
プログラム構成
いくつかの事例
変更履歴
2010年10月10日11日 ほとんど新規しかし未完
2010年10月16日17日 いくつかの事例(UART&USB)
2010年11月6日 SDカード及びファイルシステムのBUG修正
動作チェックをしている様子
<現状>
現時点(10月10日時点)での最新版は、V.6.1.0です。
私はV.6.0.3をベースに使用しています。
解凍すると多くのディレクトリに展開されますが、LPC1768を使用する場合はRB1768の基板を利用したデモ用ファイルを流用します。
..\FreeRTOS.v.6.0.3\Demo\CORTEX_LPC1768_GCC_RedSuite\src
少し古い情報(2010年3月)ですが、ここに最初にインストールした内容を書き記しています。
その後の動作確認で、USB、TCP/IP等が動き始めました。
私の作成しているデータロガープログラムは、タスクを下記の様に分配しています。
タスク名 主な機能 優先付け スタックサイズ
(Byte)起動周期 vuIP_Task TCP/IP制御及びそのアプリケーションプログラムの実行 3 192 常時 vUSBTask USB制御及びそのアプリケーションプログラムの実行
現時点(2010年10月)では、CDCとMSCの動作が確認出来ています1 128 常時 vTask1 CAN通信に使用しますが、まだDummyプログラムを動かしています 0 128 25ms vTask2 Micro-SD制御
GPS、CAN、ADCの各データをQueueを使って受取り、ファイルに書き込んでいます0 144 vTask1
vTask4
vTask6
の要求にて順次起動vTask3 モニタープログラム
デバッグ目的のタスクで、色々な情報をPCへ表示しています0 144 PCからの文字入力毎 vTask4 GSP制御
GPSデータをUARTで受信して、Task2へQueueを使って送り出しています0 128 GPSのパケット送出
(現設定では25ms毎程度)vTask5 LCD制御
各種データを表示していますが、まだ暫定です0 128 1Sec毎が基本
但し、順次vTask6 ADC制御
Gセンサー(X、Y、Z三軸)、温度センサー及び電源電圧を計測しています0 128 25ms vTask7 10mSタイマー及びスイッチ状態監視
スイッチの状態に応じて、全体制御モードを変えています0 96 10ms
モニタープログラムを使用して、各タスクの状況を観測し、表として整理すると下記のような情報が得られます。
この例は、各タスクの最大負荷を想定して計測していません。従って、あくまでも参考としてご覧ください。
タスク スタック残り
サイズ初期値 残量 TASK/uIP 70 192 36.4% TASK/USB 74 128 57.8% Task1/CAN 54 128 42.2% Task2/MSD 94 144 65.3% Task3/MON 44 144 30.6% Task4/GPS 80 128 62.5% Task5/LCD 80 128 62.5% Task6/ADC 46 128 35.9% Task7/TIM 48 96 50.0%
タスクが占有している時間は下記の情報を参考にしてください。
task_running_condition.pdf
表で判るように、アプリケーションタスク(現在9個)以外に、システムが制御しているタスクが多く存在します。
IDLEが重要で、CPUの占有率がどんなときにも100%を越えるわけにはいきませんので、IDLE時間がどのくらい残っているかはシステムの安定性に影響します。
上記測定中は、USB経由でファイルをPCからMicro-SDへコピーしている場合で、コピー終了後はUSBタスクが23%から2%に減少しました。
その分、IDLEが18%から23%に増加しています。
現時点では、USBはPCからの要求をポーリング処理で監視し続けている為、占有率が増えていますが、割込み処理に移行出来ればもっと改善出来ると思います。
残念ながら、検討したところかなりの変更が必要で落ち着いてから再チャレンジ(多分出来ない?)とします。
<FreeRTOS提供のFunction使用例>
アプリケーションで使用しているFunctionを紹介します。
素人なので、FreeRTOSの提供する機能を充分に使いこなしていなくて、下記だけです。
機能の詳細は、FreeRTOSのホームページでpdfファイルを購入する必要があります。
但し、一般的な解説はホームページにて閲覧可能(API Reference)です(英語のみ)。
下記で確認出来るようにリアルタイムOSを簡単に使うには、それほど深い知識が無くても利用可能だと思いますので、pdfを購入して理解を深める前に先ずは使ってみることが重要だと思います。
むしろ難しいのは、スタック管理を含むメモリ管理でしょう。
私の経験では、プログラムが上手く動かない理由の多くがスタックの問題と、あるタスクがCPUを占有してリソースを解放しないでタスクがディスパッチ出来ずに動作不良を起こしていることが多いです。
No. 機能 機能名 機能の使い方 1 タスク生成 xTaskCreate
今回のアプリケーションでは、初期化の際に下記の様にタスク生成をしています。
// Web
xTaskCreate( vuIP_Task, ( signed char * ) "uIP", ( ( unsigned short )192 ), ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );
// USB Task (Selected function only)
#if (USB_DISK == 1)
// Mass Storage Class
xTaskCreate( vUSBTask, ( signed char * ) "USB", ( ( unsigned short ) 128 ), ( void * ) NULL, ( tskIDLE_PRIORITY +1 ), NULL );
#elif (USB_UART == 1)
// Serial
xTaskCreate( vUSBTask, ( signed char * ) "USB", ( ( unsigned short ) 128 ), ( void * ) NULL, ( tskIDLE_PRIORITY +1 ), NULL );
#endif
// CAN Task
xTaskCreate( vTask1, ( signed char * ) "Task1", ( ( unsigned short ) 128 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
// SD Card Control Task
xTaskCreate( vTask2, ( signed char * ) "Task2", ( ( unsigned short ) 144 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
// Monitor Task
xTaskCreate( vTask3, ( signed char * ) "Task3", ( ( unsigned short ) 144 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
// GPS Task
xTaskCreate( vTask4, ( signed char * ) "Task4", ( ( unsigned short ) 128 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
// LCD Control Task
xTaskCreate( vTask5, ( signed char * ) "Task5", ( ( unsigned short ) 128 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
// ADC Control Task
xTaskCreate( vTask6, ( signed char * ) "Task6", ( ( unsigned short ) 128 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
// Operation mode control Task
xTaskCreate( vTask7, ( signed char * ) "Task7", ( ( unsigned short ) 96 ), ( void * ) NULL, tskIDLE_PRIORITY, NULL );
2 キュー生成 xQueueCreate
タスク間の同期を保っての情報伝達に使用するキューを生成します。
今回は、下記のようにGPS情報、LCD表示、ADC情報用に3つのキューを用意しました。
// Create Queue buffer and Semaphore
sdcardQueue = xQueueCreate(4, 8); // 8Byte x 4
LcdQueue = xQueueCreate(4, 8); // 8Byte x 4
adctrgrQueue = xQueueCreate(4, 8); // 8Byte x 4
3 キュー送信 xQueueSendToBack
キューにデータをセットして、発行します。
例えば、
if (rec_status == RECD){
xQueueSendToBack(sdcardQueue, "ADC", portMAX_DELAY);
}
では、TASK6がADCデータの準備が出来たことを知らせています(TASK2のSDカード制御タスクが記録中あれば)。
4 キュー受信 xQueueReceive
キューにデータがセットされるまで、タスクは待ち状態となります。
例えば、上記に対応する部分では、
while(1){
xQueueReceive(sdcardQueue, qbuf, portMAX_DELAY);
if ( rec_status == RECD ){
if (memcmp(qbuf, "ADC", 3) == 0){
f_puts(MsgBuf_ADC, &File1);
} else if (memcmp(qbuf, "CAN", 3) == 0){
f_puts(MsgBuf_CAN, &File1);
} else if (memcmp(qbuf, "GGA", 3) == 0){
f_puts(MsgBuf_GGA, &File1);
} else if (memcmp(qbuf, "GSA", 3) == 0){
f_puts(MsgBuf_GSA, &File1);
}
f_sync(&File1);
vParTestToggleLED( LED2 ); // Show on logging
}
となって、データが送出されてくるまで待っています。
5 一定時間待ち vTaskDelay
指定した時間、タスクの制御が中断されます。
例えば、
// Get one character
uint8_t Uart_GetC2(void){
while(ring_getc (&ring_rx2)){
vTaskDelay(1/portTICK_RATE_MS ); // Wait 1mS
}
return ring_rx2.dt_got;
}
の場合は、リングバッファにデータが入っていない時に、1ms毎にタスクは制御を中断して、他のタスクを実行出来ることになる。
7 一定時間待ち vTaskDelayUntil
vTaskDelayとの違いも含め、ここに書いた内容を参照ください。ここも参照ください。
<ソースファイル構成>
現時点(2010年10月10日)で、私の作成しているデータロガーで使用しているファイルの構成を下記に示します。現在も開発完了していませんので、今後も変更する予定です。
gccのDirectoryには、
生成されるObjectが格納されます。
docは関係資料が入っていますが、
ソフトウェア開発には関係しません
より詳しい内容は、このファイルリストを参照ください。
<オリジナルファイル>
下記の多くのプログラムを直接もしくは間接的に参考にさせていただきました。
利用したプログラム一覧 プログラム名 作者
(管理者もしくは供給者)入手先 ライセンス条件 コメント FreeRTOS Richard Barry
(FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd.)SourceForge
FreeRTOS Real Time Kernel
by richardbarry
Modified GPL (Open Source) Licensing
FreeRTOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (version 2) as published by the Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute a combined work that includes FreeRTOS without being obliged to provide the source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details. You should have received a copy of the GNU General Public License and the FreeRTOS license exception along with FreeRTOS; if not it can be viewed here:
http://www.freertos.org/a00114.html and also obtained by writing to Richard Barry, contact details for whom are available on the FreeRTOS WEB site.RTOS関連ファイルは全てこの場所から入手後、一部修正して使用しています LPCUSB
LPC214x USB stack
Bertrik Sikken (bertrik@sikken.nl)
(LPCUSB, an USB device driver for LPC microcontrollers
Copyright (C) 2006 Bertrik Sikken)Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.ソース以外の関係情報に辿りつくことが出来ませんでした。
FatFsとの結合のために修正をしていますuIP
Adam Dunkels
(Ph D)
(Copyright (c) 2001, Adam Dunkels. All rights reserved.)Adam Dunkels' Homepage
Download page
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.FreeRTOSにDemoとして添付されているソースコードを利用して、間接的に利用しています FatFs ChaN(English)
ChaN(日本語)FatFs 汎用FATファイルシステム・モジュール
FatFs Generic File System Module/*----------------------------------------------------------------------------/
/ FatFs - FAT file system module R0.08a (C)ChaN, 2010
/-----------------------------------------------------------------------------/
/ FatFs module is a generic FAT file system module for small embedded systems.
/ This is a free software that opened for education, research and commercial
/ developments under license policy of following trems.
/
/ Copyright (C) 2010, ChaN, all right reserved.
/
/ * The FatFs module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/-----------------------------------------------------------------------------/
/*----------------------------------------------------------------------------/
/ FatFs - FAT file system module R0.08a (C)ChaN, 2010
/-----------------------------------------------------------------------------/
/ FatFsモジュールは、小規模な組み込みシステム向けの汎用FATファイルシステム・
/ モジュールです。これはフリー・ソフトウェアとして、教育・研究・開発のために
/ 以下のライセンス・ポリシーの下で公開されています。
/
/ Copyright (C) 2010, ChaN, all right reserved.
/
/ * FatFsモジュールはフリー・ソフトウェアであり、また無保証です。
/ * 用途に制限はありません。あなたの責任の下において、個人的・非営利的な
/ ものから商用製品の開発に及ぶ目的に使用・改変・再配布することができます。
/ * ソース・コードを再配布するときは、上記の著作権表示を保持しなければなりません。
/
/-----------------------------------------------------------------------------/NXPのアプリケーションノートAN10916で紹介されていて、使用し始めましたが、まさか日本人の方が作成したソフトウェアとは、2009年暮れまで知りませんでした。
このGPSデータロガーはすごいです。NXP
Sample programNXP All microcontrollers support documents for LPC1768
LPC1769_68_67_66_65_64.zip
lpc17xx.cmsis.driver.library.zip
LPCXpresso support
library.cmsis.lpc17xx.zip
Terms of Use . Code Red
Sample
programCode Red RDB1768 CMSIS-based Example Projects
RDB1768cmsis.zipSoftware License Agreement
The software is owned by Code Red Technologies and/or its suppliers, and is protected under applicable copyright laws. All rights are reserved.
Any use in violation of the foregoing restrictions may subject the user to criminal sanctions under applicable laws, as well as to civil liability for the breach of the terms and conditions of this license.
THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH CODE RED TECHNOLOGIES LTD.. ring.c
ring.hCopyright (C) 2003 Project Majingaa. (http://majingaa.dyndns.org/) . Copyright (C) 2003 Project Majingaa. (http://majingaa.dyndns.org/)
This file is part of majingaa-hos
majingaa-hos is free software; you can redistribute it and/or modify it under the terms of the GNU General PublicLicense as published by the Free Software Foundation; either version 2, or (at your option) any later version.
majingaa-hos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with majingaa-hos; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.2005年頃、Webで入手。現在情報がありません printf-stdarg.c Copyright 2001, 2002 Georges Menie (www.menie.org)
stdarg version contributed by Christian Ettinger. Copyright 2001, 2002 Georges Menie (www.menie.org)
stdarg version contributed by Christian Ettinger
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAFreeRTOSのダウンロードによって入手 spilcd.c
spilcd.h
font8.h
http://mbed.org/users/Sim/
http://blog.goo.ne.jp/sim00/
http://blog.goo.ne.jp/sim00
/c/5ea7bba8b30eb2dfb492f7289aa217d1
http://hamayan.ddo.jp
/~hamayan/so-net/font.htmlhttp://mbed.org/users/Sim/programs/FontTest/gpdz3d . 特にコメントを見つけ出せなせんでした
<ROM&RAM使用方法>
LPC1768には下記の様に、ROMとRAMがアサインされています。
種類 サイズ アドレス ROM 512KB 0x0 -> 0x7ffff RAM 32KB 0x10000000 -> 0x1007fff RAM 16KB 0x2007c000 -> 0x2007ffff RAM 16KB 0x20080000 -> 0x20083fff
問題は、RAMが合計64KBあるのも関わらず連続していないことです。
従って、64KBのRAMと言っても実際には使いずらい仕様になっており、最初使い始めた時には戸惑いました。
とは言っても今更ユーザーの立場で動的に配置変更出来ませんので、現実を直視して下記の作業をしました。
先ずは、Cソースファイル内で下記の様に宣言します。RAMの割付けにセクション指定します。
// Queue data buffer for LCD display
uint8_t GpsQBuff[20] __attribute__((section(".ex_ram2")));
uint8_t FileQBuff[20] __attribute__((section(".ex_ram2")));
uint8_t Othr1QBuff[20] __attribute__((section(".ex_ram2")));
uint8_t Othr2QBuff[20] __attribute__((section(".ex_ram2")));
MEMORY
{
FLASH (rx) : ORIGIN = 0x0 LENGTH = 0x80000
SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000
AHBRAM0(rwx) : ORIGIN = 0x2007c000, LENGTH = 0x4000
AHBRAM1(rwx) : ORIGIN = 0x20080000, LENGTH = 0x4000
}
------- 途中省略 ----------
SECTIONS
{
.ETHRAM (NOLOAD) :
{
*(.ex_ram1*)
_ex_ram1_end = .;
} > AHBRAM0
__eahb1_data_end =.;
.USBRAM (NOLOAD) :
{
*(.ex_ram2*)
} > AHBRAM1
}
/* EMAC Memory Buffer configuration for 16K Ethernet RAM. */
#define NUM_RX_FRAG 3 /* Num.of RX Fragments. */
#define NUM_TX_FRAG 2 /* Num.of TX Fragments. */
#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */
#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */
------- 途中省略 ----------
/* EMAC variables located in AHB SRAM bank 1*/
#define AHB_SRAM_BANK1_BASE 0x2007c000UL
#define RX_DESC_BASE (AHB_SRAM_BANK1_BASE )
#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */
#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */
#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */
#define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */
/* RX and TX descriptor and status definitions. */
#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i))
#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))
#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i))
#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))
#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i))
#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))
#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i))
#define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i )
#define ETH_NUM_BUFFERS ( NUM_TX_FRAG + NUM_RX_FRAG + 1 )
/* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */
種類 サイズ アドレス 使用量 サイズ 使用率 ROM 512KB 0x0 -> 0x7ffff 0x0 -> 0x00016584 91524B 17.5% RAM 32KB 0x10000000 -> 0x1007fff 0x10000000 -> 0x10006f8c 28556B 87.1% RAM 16KB 0x2007c000 -> 0x2007ffff . 9288B 56.7% RAM 16KB 0x20080000 -> 0x20083fff 0x20080000 -> 0x2008125c 4700B 28.7%
No. 分類 コマンド コマンド形式 解説 1 Help ? Help コマンドのヘルプ 2 d? Help 3 f? Help 4 r? Help 5 s? Help 6 m>? Help(メモリモードに入ってから) 7 メモリ
関連m m - Enter Memory Mode メモリコマンドモードへ 8 m>d d <address> [<count>] - Dump memory メモリ内容の128バイト毎のダンプ 9 m>s s - Show memory structure メモリ構造表示 10 m>(RET) <RET> - Dump memory / next 128 bytes 単純に<RET>=”Enter"で次の128バイト表示 11 m>(BS) <BS> - Dump memory / same as before 128 bytes 前の128バイト表示 12 m>(ESC) <BS> - Dump memory / same as before 128 bytes メモリコマンドモード終了 13 ADC
変換データa a - Show ADC data ADCデータ表示 14 GPS
情報g g - Show GPS latest data GPSデータ表示 15 スイッチ
状態p p - Show Port status スイッチ3個のON/OFF状況表示 16 1秒毎表示 / / - Show data every one second /a, /g, /p, /t 一秒間毎に同じコマンドを自動的に実行し表示する
このコマンドでは、ADC、GPS、スイッチ、時間を繰り返し表示17 時間表示
設定t t [<year> <mon> <mday> <hour> <min> <sec>]
e.g. 2010/8/13 13:5:20 -> t 2010 8 13 13 5 20<ENT>時間表示と設定 18 UART
設定状況u u - Show UART condition UARTの使用状況、ボーレート表示 19 FreeRTOS ri ri - Task information タスク状況表示 20 rs rs - Stack status スタック消費状況表示 21 rt rt - Run-Time statistics CPU占有率表示 22 CPU sc sc - System CPU information CPUの種類表示 23 sf sf - System Clock CPU動作周波数表示 24 DISK dd dd [<lba>] - Dump sector オリジナルのソースファイルに入っていたものを
そのまま使用しています。
但し、FatFsのリエントラント機能を使用していないために、
データロガーとして使用中にコマンドを実行するとフリーズ
してしまいます。
従って、ほとんど使用していません。25 di di - Initialize disk 26 ds ds - Show disk status 27 FILE fc fc - Close a file 28 fd fd <len> - read and dump file from current fp 29 fi fi - Force initialized the logical drive 30 fk fk <name> - Create a directory 31 fl fl [<path>] - Directory listing 32 fn fn <old_name> <new_name> - Change file/dir name 33 fo fo <mode> <file> - Open a file 34 fr fr <len> - read file 35 fs fs - Show logical drive status 36 fu fu <name> - Unlink a file or dir 37 fv fv - Truncate file 38 fw fw <len> <val> - write file 39 fx fx <src_name> <dst_name> - Copy file 40 fz fz [<rw size>] - Change R/W length for fr/fw/fx command 41 DISK IO bd bd <addr> - Dump R/W buffer 42 be be <addr> [<data>] ... - Edit R/W buffer 43 bf bf <val> - Fill working buffer 44 br br <lba> [<num>] - Read disk into R/W buffer
No. ソースファイル名 1 monitor_main.c 2 monitor.h 3 monitor.c
現在は、下記のように設定しています。
No. ソースファイル名 1 uart.c 2 uart.h 3 ring.c 4 ring.h
UART2は、モニタープログラム(上記のようにPCとの通信)用に使っています。
受信は、割込みを使用してリングバッファにデータを蓄えていますが、送信はバッファなしでそのまま書き込んでいます。
// Output one character
void Uart_PutCharBuf2(uint8_t c) {
/* THRE status, contain valid data */
while ( !(( LPC_UART2->LSR ) & LSR_THRE )); // Polling for write action
LPC_UART2->THR = (uint16_t)c & 0xFF;
}
修正版
void Uart_PutCharBuf2(uint8_t c) {
/* THRE status, contain valid data */
while ( !(( LPC_UART2->LSR ) & LSR_THRE )){
vTaskDelay(3/portTICK_RATE_MS ); // Wait 3mS
}
LPC_UART2->THR = (uint16_t)c & 0xFF;
}
受信の場合にはデータが無い時には、FreeRTOSに制御を渡しています。
// Get one character
uint8_t Uart_GetC2(){
while(ring_getc (&ring_rx2)){
vTaskDelay(1/portTICK_RATE_MS ); // Wait 1mS
}
return ring_rx2.dt_got;
}
UART3も同様な構造で、受信用にリングバッファを用意しています。
/*-----------------------------------------------------------
* USB MODE
*-----------------------------------------------------------*/
#define USB_HID 0
#define USB_CSTM 0
#define USB_UART 1
#define USB_DISK 0
/*-----------------------------------------------------------
* Monitor interface
*-----------------------------------------------------------*/
// Monitor On or Off
#define SET_MON 1
// Monitor via USB COM
#define MON_VIA_USB 1
// Monitor via UART
#define MON_VIA_UART 0
USBをCDCに設定して、仮想COMとしてPCへ接続。
Tera TermでCOM9を開けてモニタープログラムとの接続を設定する。
Tera TermでUARTの状況を確認して、UART2が使われていないことを確認。
USBをMSCとして設定しLPCXpresso(1768)に接続したMicro-SDをPCから覗けるようにした
ファイル main_serial.c
int main(void)
{
int c;
// PLL and MAM
Initialize();
途中省略
enableIRQ();
// connect to bus
USBHwConnect(TRUE);
// echo any character received (do USB stuff in interrupt)
while (1) {
c = VCOM_getchar();
if (c != EOF) {
// show on console
if ((c == 9) || (c == 10) || (c == 13) || ((c >= 32) && (c <= 126))) {
DBG("%c", c);
}
else {
DBG(".");
}
VCOM_putchar(c);
}
}
return 0;
}
当初は、mon()の入出力に、上記のVCOM_getchar()とVCOM_putchar()をそのまま使おうとしましたが、使えませんでした。
ファイル USB_CDC.c
uint16_t VCOM_getchar(void)
{
uint8_t c;
/* Block the task until a character is available. */
xQueueReceive( xRxedChars, &c, portMAX_DELAY );
return c;
}
更に、USBのタスクとMONタスクが別々に動作しているので、両タスク間でのデータやり取りの方法を考えなければなりません。リングバッファを3つ用意して対応しました。
void xputs (const char* str)
{
#if (MON_VIA_UART == 1)
while (*str)
xputc(*str++);
#elif (MON_VIA_USB == 1)
USB_PutStrBuf((char *)str);
#endif
}
更に、VCOM_getchar()が制御を戻さない問題も、下記のようにUSB_ChkESnd()を追加して解決
しています。
ファイル main_serial.c内の無限ループ
for( ;; ){
#if (MON_VIA_UART == 1)
省略
#elif (MON_VIA_USB == 1)
c = VCOM_getchar();
if ( c != 0 ){
USB_PutRcvBuf(c);
} else {
vTaskDelay( 1 / portTICK_RATE_MS );
}
while (!USB_ChkESnd()){
c = USB_GetSndBuf();
if ( c != 0 ){
VCOM_putchar( c );
} else {
break;
}
}
uxHiWtrMrk_usb = uxTaskGetStackHighWaterMark( NULL );
#endif
}
ファイル uart.c
// Check output
uint16_t USB_ChkESnd( void ){
return ring_is_empty (&ring_txu);
}
表の中で判りづらいところがありますので、下記コメントも参照ください。
No. ファンクション名 機能 修正のポイント 1 BlockDevInit() SDカードとのインターフェイス初期化
SPI機能の初期化に続いて初期化コマンドを実行FatFsには、disk_initialize()が実装されているので、それを呼び出すように修正
..\fat_sd\lpc17xx_sd.c内既存2 BlockDevGetSize() SDカードのサイズを返す 初期化の際に、
static SDCFG SDCfg;
の中にある情報を取り出すファンクションを新設しました
..\fat_sd\lpc17xx_sd.c内に新規3 BlockDevWrite() 512バイト単位の書込み disk_write()があるので、それを呼び出し
..\fat_sd\lpc17xx_sd.c内既存4 BlockDevRead() 512バイト単位の読出し disk_read()があるので、それを呼び出し
..\fat_sd\lpc17xx_sd.c内既存
ファイル main_serial.c
void USB_IRQHandler(void)
{
USBHwISR();
}
void vUSBTask( void *pvParameters ){
省略
// register descriptors // 割込み処理の呼出しルーチンの登録(ここから)
USBRegisterDescriptors(abDescriptors);
省略
// enable bulk-in interrupts on NAKs
USBHwNakIntEnable(INACK_BI);
// 割込み処理の呼出しルーチンの登録(ここまで)
NVIC_SetPriority( USB_IRQn, configUSB_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( USB_IRQn ); // ここで割込み許可
// connect to bus
USBHwConnect(TRUE);
// echo any character received (do USB stuff in interrupt)
c = '0';
for( ;; ){ // ここではUSBHwISR()は当然、呼ばれない → 上記USB_IRQHandler()内
c = VCOM_getchar();
if ( c != 0 ){
USB_PutRcvBuf(c);
} else {
vTaskDelay( 1 / portTICK_RATE_MS );
}
while (!USB_ChkESnd()){
c = USB_GetSndBuf();
if ( c != 0 ){
VCOM_putchar( c );
} else {
break;
}
}
uxHiWtrMrk_usb = uxTaskGetStackHighWaterMark( NULL );
}
}
これに対して、MSCでは、下記のように呼び出しています。
ファイル main_msc.c
void vUSBTask( void *pvParameters ){
省略
// enable bulk-in interrupts on NAKs
// these are required to get the BOT protocol going again after a STALL
USBHwNakIntEnable(INACK_BI);
// register descriptors
USBRegisterDescriptors(abDescriptors);
// register class request handler
USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData);
// register endpoint handlers
USBHwRegisterEPIntHandler(MSC_BULK_IN_EP, MSCBotBulkIn);
USBHwRegisterEPIntHandler(MSC_BULK_OUT_EP, MSCBotBulkOut);
// connect to bus
USBHwConnect(TRUE);
// call USB interrupt handler continuously // 割込みを登録していない
while (1) {
if (Check_Idle()){
vTaskDelay(1/portTICK_RATE_MS); // Wait
}
USBHwISR(); // ここで呼び出している
uxHiWtrMrk_usb = uxTaskGetStackHighWaterMark( NULL );
}
}
SPI経由で512バイト単位の読み書きもあり、割込み処理では対応できないとの判断だと思います。ChaNさん提供のソースファイルに対して、SPI経由のSDカード制御プログラムを下位レイヤ・インターフェイスを提供する必要があります。
No. ファイル名 コメント 1 ff.c FatFs-ELM by ChaN
http://elm-chan.org/fsw/ff/00index_j.html にて提供されているモジュール
2 ff.h 3 ffconf.h 4 integer.h 5 diskio.h 6 option/cc932.c 7 option/cc936.c 8 option/cc949.c 9 option/cc950.c 10 option/ccsbcs.c 11 option/syscall.c 12 lpc17xx_sd.c NXP
All microcontrollers support documents for LPC1768
AN10916 FAT library EFSL and FatFs port on NXP LPC1700 V2(Jul 6,2010) with software (Feb 3,2010)
内にあるサンプルプログラムベース13 lpc17xx_sd.h 14 lpc17xx_spi.c 15 lpc17xx_spi.h
速度は、まだ改良すべき課題です。現状は、537,400,028バイトの1つのファイルをPCからUSB経由でMicroSDに書き込んだところ45分かかった。
LPC1768信号名 LPC1768ピン配置 mbed信号名 mbedピン配置 P0[18]/DCD1/MOSI0/MOSI 60 SPI/mosi p11 P0[17]/CTS1/MISO0/MISO 61 SPI/miso p12 P0[15]/TXD1/SCK0/SCK 62 SPI/sck
Serial/txp13 P0[16]/RXD1/SSEL0/SSEL 63 Serial/rx p14
これで直ったと思ったのですが、下記の様な表示になります。
変更ファイル 変更前 変更内容 コメント lpc17xx_sd.c uint32_t disk_size_inf ( void ) uint64_t disk_size_inf ( void ) 64ビットでディスク容量を返すように
unit64_tとunsigned long longやU32などが混在していますが、流用元の流儀をあまり変えないようにしている為です。
FreeRTOSの形式(portBASE_TYPEなど)やDDWORDの表現も入っていて、全体としてはかなり混沌としています。lpc17xx_sd.h /* MMC device configuration */
typedef struct tagSDCFG{
uint32_t sernum; // serial number
uint32_t size; // size=sectorsize*sectorcnt/* MMC device configuration */
typedef struct tagSDCFG{
uint32_t sernum; // serial number
uint64_t size; // size=sectorsize*sectorcntblockdev.h U32 BlockDevGetSize(void) unsigned long long BlockDevGetSize(void) blockdev_sd.c U32 BlockDevGetSize(void) unsigned long long BlockDevGetSize(void) msc_scsi.c U32 dwDevSize, dwMaxBlock; U32 dwMaxBlock;
unsigned long long dwDevSize;
修正後に(私のPCの場合には)F:ドライブとして正しく認識されるようになりましたが、モニタープログラムで"fl"コマンドを実行すると未だ正しく表示されません。
これでようやく解決しました。少し気持ち悪いのは、PC(Windows XP)の認識容量とモニタープログラムの容量表示が微妙に違う!?
変更ファイル 変更前 変更内容 monitor_main.c static long p1, p2, p3;
UINT s1, s2, cnt;
xprintf("%4u File(s),%10lu bytes total\n%4u Dir(s)", s1, p1, s2);static long p1, p2, p3;
DDWORD pf;
p1 = pf%100;
xprintf("%4u file(s),%10lu%02lu bytes total\n%4u Dir(s)", s1, (DWORD)(pf/100), p1, s2);blockdev_sd.c int BlockDevGetSize(U32 *pdwDriveSize){
.....
}extern unsigned long long disk_size_inf( void );
// Get Device media size
unsigned long long BlockDevGetSize(){
return disk_size_inf();
}