組込みとともに -25ページ目

プロジェクト管理とガジェット

phpCollabというプロジェクト管理システムをご存知でしょうか?
phpとMySQLを利用したプロジェクト管理システムです


こういうシステムは入力をルール化してもなかなか思うように使えてなかったりします。
毎朝webサイトを開いてアクティブプロジェクトの各タスクの進捗や期限をチェックするのは少々手間ですし、効率が良くないと感じていました。
手間なことにより情報の入力し忘れの問題なんかもあります。
一番多いのはタスク完了後、完了に安心して完了フラグを発行し忘れることでしょうか。

もっと身近にプロジェクトのタスクが見えないといけないと感じました。
ホワイトボードを利用したソフトウェア看板方式などありますが、離れた事務所間での情報共有なども行いたいため、やはりネットを活用したいと思います。

そこで考えたのが、googleガジェットの利用です。
時計ガジェットやメモガジェットなど便利な機能がありますよね。
その一つとしてプロジェクト管理ガジェットを配置すればいつも目にすることになりますので完了フラグ忘れの防止になる気がします。また他者の作業遅れのフォローもしやすくなります。管理者的には管理が楽になります。

具体的にはphpCollabの未完タスクをRSSで配信できるようにしその情報をガジェット化します。

ガジェットは付箋紙が張り付くイメージで『タイトル』『担当者』『期限』『タスク名』『プロジェクト名』を表示します。
これを1件づつの表示でスクロールかフェイドイン・アウトで切り替えます
期限当日は赤色、前日は橙色で遅れを防止
クリックでphpCollabのwebサイトのタスク詳細ページを開く

試しにgoogleデスクトップガジェットデザイナー使ってみましたら、何とも簡単にアプリが出来そうです。

課題はphpCollabとの連携のRSS生成のところでしょうか。

時間の有るときにチャレンジしたいと思います(^-^)

xportip v1.0.0.1リリース

http://sourceforge.jp/projects/xportip/


sourceforge.jpで公開してますプロジェクト

XPORT検索アプリケーションのV1.0.0.1をリリースしました

ネットワーク環境によって複数クライアント(XPORT)を正しく検索できなかった問題を修正しました。


具体的には.NETでUdpClient.Client.Availableで次のクライアントのパケットを処理するか判定するのですが

クライアント(XPORT)のパケット間隔が開くと応答クライアントがあるのに、なしと処理してしまう場合があります。

ハードウェア的にはパケットの衝突が起こった場合に再送処理待ち時間で発生する可能があります。

対応策としてはUdpClient.Client.Availableの前に50ミリ秒ほどウェイトをかけて確認するようにしました。


XPORTユーザーはお試しください^^

FunkOSデバイスドライバーを書く

前回の日記からの続きでFunkOS の評価ボードの作成

今回からソフトウェアについて書いていきます。


このAVR8ビットマイコンの用のRTOS、ユーザーズマニュアルにはデバイスドライバーの仕様が記載されていますが実際にソースとして入っているわけではないのでマニュアルを熟読して自分で書く必要があります。


まずはダウンロードしたファイルの

\FunkOS_R1_Andromache\docs\Manual.pdf

を開きます。25ページあたりからDevice Driversの章が始まっています。


デバイスドライバーの構造体は下記の通り(都合上半角スペース4個を全角スペース2個で記載しています)

typedef struct
{
  UCHAR *szName; // Driver Name
  DRIVER_STATE eState; // Driver state
  DRIVER_TYPE eType; // Driver type enumeration
  DRIVER_CONSTRUCTOR pfConstructor; // Pointer to constructor fn
  DRIVER_START pfDriverStart; //Pointer to driver start fn
  DRIVER_STOP pfDriverStop; //Pointer to driver stop fn
  DRIVER_CONTROL pfControl; // Pointer to driver event fn
  MUTEX_STRUCT stMutex; // Resource protection mutex
} DRIVER_STRUCT;


今回搭載するUARTの機能としては

・UART初期化

・1文字送信

・文字列送信

・1文字受信

・受信バイト数取得

・受信バッファクリア

・受信は割り込み制御、32バイトのFIFOバッファ(超過分は破棄)

・送信は速度よりも同期受信のためブロッキング送信

・送受信ともフロー制御なし

とし、FunkOSのDRIVER構造体に定義すると


DRIVER_STRUCT stUartDriver =
{
  "Comm0", // Driver Name
  DRIVER_UNINIT, // Driver state
  DRIVER_TYPE_UART, // Driver type enumeration
  Uart_Iinit, // Pointer to constructor fn
  Uart_Start, //Pointer to driver start fn
  Uart_Stop, //Pointer to driver stop fn
  Uart_Ctrl, // Pointer to driver event fn

  // Do not initialize the mutex here...
};

といった感じです。


各メンバを簡単に解説します。

"Comm0"・・・ドライバ名、ユニークな名前なら何でもよさそうです。マニュアルでは"dev\\MyDevice"です

DRIVER_UNINIT・・・未初期化状態を表します。構造体定義時はこれでよいです

Uart_Init関数・・・UARTの設定を行います。具体的にはUARTの調歩同期式モード、ボーレート

Uart_Start関数・・・受信バッファ初期化、受信割り込み可、送受信可

Uart_Stop関数・・・受信割り込み禁止、送受信不可

Uart_Ctrl関数・・・下記の機能を実行します

            ・1文字送信 (driver.h DRIVER_TX_BYTE)

            ・文字列送信 (driver.h DRIVER_TX_STRING)

            ・1文字受信 (driver.h DRIVER_RX_BYTE)

            ・受信バイト数取得 (driver.h )

            ・受信バッファクリア (driver.h )

独自の実装として

DRIVER_EVENTに下記を追加します

  DRIVER_UART_LENGTH, // 受信バッファの受信バイト数
  DRIVER_UART_CLEAR // 受信バッファのクリア

と、いった感じでデバドラの設計を行っていきます。

実コード中で上記デバドラを使用すると殆どUart_Ctrl関数だらけになりそうなので受信用、送信用と関数をラッピングした方が可読性が上がるような気がします。そのあたりは実際の使い方によってカスタマイズしてゆけばよいかと思います。


ちなみにkernelcfg.hでKERNEL_USE_MUTEXを有効にするとデバイスアクセス中はMUTEXでデバイスのロック/リリースを行います


二つ用意したLEDはとりあえず下記のようにします

DRIVER_STRUCT stLedsDriver[] =
{

  {
    "LED0", // Driver Name
    DRIVER_UNINIT, // Driver state
    DRIVER_TYPE_LEDS, // Driver type enumeration
    Leds_Iinit0, // Pointer to constructor fn
    Leds_Start0, //Pointer to driver start fn
    Leds_Stop0, //Pointer to driver stop fn
    Leds_Ctrl0, // Pointer to driver event fn

    // Do not initialize the mutex here...

  },

  {
    "LED1", // Driver Name
    DRIVER_UNINIT, // Driver state
    DRIVER_TYPE_LEDS, // Driver type enumeration
    Leds_Iinit1, // Pointer to constructor fn
    Leds_Start1, //Pointer to driver start fn
    Leds_Stop1, //Pointer to driver stop fn
    Leds_Ctrl1, // Pointer to driver event fn

    // Do not initialize the mutex here...

  }

};


2つのLEDはそれぞれ2つのタスクから独立してアクセスさせる目的で別々にしています。
Leds_Init・・・IOポート設定、出力初期値設定(H:OFF)

Leds_Start・・・特になし(なしの場合でも関数の登録が必要)

Leds_Stop・・・特になし(なしの場合でも関数の登録が必要)

Leds_Ctrl・・・

 LEDドライバのイベントを下記に追加

 DRIVER_LED_ON

 DRIVER_LED_OFF


また2つのキーのデバイスドライバーの構造体は下記の通り

DRIVER_STRUCT stLedsDriver[] =
{

  {
    "KEY0", // Driver Name
    DRIVER_UNINIT, // Driver state
    DRIVER_TYPE_BUTTONS, // Driver type enumeration
    Keys_Iinit0, // Pointer to constructor fn
    Keys_Start0, //Pointer to driver start fn
    Keys_Stop0, //Pointer to driver stop fn
    Keys_Ctrl0, // Pointer to driver event fn

    // Do not initialize the mutex here...

  },

  {
    "KEY1", // Driver Name
    DRIVER_UNINIT, // Driver state
    DRIVER_TYPE_BUTTONS, // Driver type enumeration
    Keys_Iinit1, // Pointer to constructor fn
    Keys_Start1, //Pointer to driver start fn
    Keys_Stop1, //Pointer to driver stop fn
    Keys_Ctrl1, // Pointer to driver event fn

    // Do not initialize the mutex here...

  }

};


LED同様に2つのタスクに独立して割り当てる予定なので2つに分けています。

Keyはソフトウェアでチャタリングをフィルタする設計でいますのでInit関数ではタイマーの初期化などを含みます。

チャタリングフィルタは10ミリ秒間隔でKeyの状態を絶えずチェックして10回連続ONで論理状態をON

10回連続OFFで論理状態をOFFとします。つまり100ミリ秒同じ状態が継続した場合にのみ状態を確定します。

(このチャタリングフィルタの説明は時間があればまた補足説明したいと思います。)


Keys_Start関数・・・チャタリングフィルタ論理状態およびカウンタの初期化

Keys_Stop関数・・・カウンタ停止

Keys_Ctrl関数・・・

 BUTTONSドライバのイベントを下記に追加

 DRIVER_KEY_GET

キーの状態はpvData_経由で返されます。

typedef enum
{
DRIVER_KEY_OFF = 0,
DRIVER_KEY_ON,
} DRIVER_KEY_STATE;


ここまでで新しいDRIVER_EVENT(driver.h)は下記のようになります。

typedef enum
{
 DRIVER_RX_BYTE = 0,
 DRIVER_TX_BYTE,
 DRIVER_TX_STRING,


 DRIVER_UART_LENGTH, // 受信バッファの受信バイト数
 DRIVER_UART_CLEAR // 受信バッファのクリア

 DRIVER_LED_ON

 DRIVER_LED_OFF

 DRIVER_KEY_GET


 DRIVER_EVENTS
} DRIVER_EVENT;


キーのチャタリングフィルタは割り込み処理でもサイクリックハンドラ(FunkOSではTimerと呼ぶ?)でも処理できるのでもしかするとサイクリックハンドラーで実装することになるかもしれません。


あとはLCDですが、X,Y情報やカーソル情報の指定をイベントと用意すればよいので特別大変でもありません。

Initでバス幅指定などを行えばよいかと思います。Start_Stopは空でよいと思います。


次回はPort依存の

Software interrupt module – kernelswi.c/.h

Timer interrupt module – kerneltimer.c/.h

Watchdog timer module – kernelwdt.d/.h

あたりを攻めようかと思います。