UDPプロトコル通信での使い方


【UDPプロトコルモジュール内の動作概要】

TCP/IPスタック内のUDPプロトコルモジュールは、UDPの送受信の処理を
実行する関数群から構成されています。
特にユーザーAPI関数としてユーザーが使う関数群となっており、ユーザー
がUDP通信タスクを作成するときに使う関数です。
全体の構成は下図のようなフローとなっており、いくつかの関数の集まりと
なっています。

まず、初期化の関数Init_UDP()はUDPの全ユーザバッファのクリアを行います。

UDP_Process()がUDP受信のメイン関数で、受信したデータをバッファに
コピーしてバッファを受信処理待ちとします。

UDPisReady()関数は、ユーザーがUDPでの受信があったことを知るための
関数です。

Send_UDP()関数は、UDP通信でユーザーデータを送信するときに使う関数
です。 ユーザーバッファに用意したデータを送信出力します。

Release_UDP()は指定した番号のUDPバッファをクリアし空の状態にします。






UDPで使用するユーザー用バッファの構造は、下図のようになっています。
バッファの個数をMAX_UDP_USRBUFに設定することで増やせます
デフォルトの個数は2個です。
さらにその最大サイズもユーザーの設定が可能で、MAX_UDP_USRSIZEに
最大値をバイト単位で設定します。デフォルト値は64バイトとなっています。
ここでユーザー用に開放しているバッファにはユーザーが直接書き込むことが
可能です。









ユーザーバッファには直接書き込みが
可能。
その最大サイズもユーザーが設定する



【UDPプロトコル通信での使い方】

UDPプロトコルを使ってPICROS配下のアプリケーションを作る場合には、
下記のようにします。

(1) UDPのユーザータスクを作成する。
   受信したUDPデータを処理し、必要であればデータを返送する
   返送のための関数はあらかじめ用意されている。(Send_UDP(socket))
   
(2) ユーザータスクをPICROSのタスクとして追加する
   タスクリンク用のヘッダファイル(tasklink.h)と、タスクディスパッチテーブル
  である(tdt.h)にUDPユーザータスクを追加する。

これでUDP通信アプリケーションが出来ます。


【UDPユーザ処理タスクの作り方】

 UDPプロトコルでデータを送受信することで動作するタスクは、ユーザ自身が
作成する必要があります。
このユーザー処理タスクの構成は下記のようにします。

(1) ユーザー関数の定義とそれを含むユーザータスクファイルの作成
  ユーザー関数を作成し、C言語のファイルとして格納します。
  ファイル名、関数名は自由です。

(2) 受信データの格納されているバッファの番号を取り出す
  UDPで送られて来たデータを格納しているバッファの番号を
  UDPisReady()関数で取り出します。
  
    ☆UDP受信チェック関数のフォーマット
     socket = UDPisReady()
      socket:受信データのあるバッファの番号(int型)
           受信データバッファが無いときは0xFFが返る

(3) ポート番号による処理分岐
  ユーザーポートとして、10000から17000を使うこととしています。
  そのユーザーポート番号をコマンド番号とする使い方ができます。 
  そのポート番号は「UDPuser[socket].PORTNO」として格納されて
  いますので、それをUDPバッファから取り出してswitch文で分岐します。
  
    ☆指定ポート番号
      UDPuser[socket].PORTNO に格納

(4) 受信データは UDPuser[socket].user_data[i] に格納されている
  UDPでホストから送られて来たデータは配列データとして、UDPバッファ
  内の「user_data[i]」に格納されています。
  そして格納されているデータ個数は「user_size」として格納されています。

    ☆ユーザーバッファのフォーマット
      格納バッファ名称 UDPuser[socket].user_data[i]
      データ個数     UDPuser[socket].user_size
         iは変数 socketはUDPバッファ番号

(5) ホストへ送信するときには、Send_UDP(socket)関数を使う
  UDPでデバイスから送信する場合には、データを用意してUDPバッファ
  に保存してから下記の関数で送信を実行します。
  この関数はLANライブラリに用意されているので記述するだけで
  大丈夫です。

    ☆UDP送信関数のフォーマット
      Send_UDP (socket)
        socket : UDPバッファの番号(int型)

(6) バッファの使用が完了したらバッファ開放
  バッファ開放には、Release_UDP(socket)関数を使います。

    ☆バッファ開放関数のフォーマット
      Release_UDP(socket)
 
       socket : UDPバッファの番号(int型)

【実際のアプリ例】

では実際にアプリケーションを作成してみましょう。UDP通信のテスト用の
簡単なアプリケーションを作成してみます。
まず機能は下表のようなものとします。

《UDPテストアプリ機能》
No 機能名 使用ポート 機 能 内 容
1 データ受信
と送信
10001 UDP通信で受信したデータ(文字列)を液晶表示器に表示し、
'0'から始まる64文字のASCII文字をUDP通信で返送する。
返送後UDPバッファを開放する。
2 データ受信 10002 受信したデータ(文字列)を液晶表示器に表示する。
表示後UDPバッファを開放する。

 この機能をPICROSの1つのタスクの形で作成します。 このタスクのリストが
下記です。

(1) 最初に受信バッファ番号を求めます。
  UDPisReady()関数を実行すると、受信処理待ちのバッファの番号が
 返されますので、これでバッファ番号を入手します。
 処理待ちが無いときは0xFFが返されますのでこのときは何もしません。

(2) このバッファ中にあるポート番号を取り出して処理を分岐する。
  バッファ番号が求まったら、UDPuser[socket].PORTNOでポート番号が
  求められますので、このポート番号で上表のような機能に分岐します。

(3) 各機能の実行
  受信したデータは、UDPuser[socket].user_data[i] にありますので
  ここから1文字づつ取り出しては液晶表示器に出力します。

(4) データ送信
 折り返しにデータ送信がある場合には、送信データをユーザーバッファ
 UDPuser[socket].user_data[i]にセットし、データバイト数をやはり
 UDPuser[socket].user_sizeにセットしてから、Send_UDP()関数を実行します。
 これで送信が自動的に実行されます。

(5) 最後にバッファを開放
  バッファを使い終わったら Release_UDP[socket]で指定バッファを
  開放します。


  ☆ユーザーアプリの製作例  ファイル名 udp_task.c
void udp_user(void)
{
  int i,  socket;

  //// UDP使用中フラグチェック
  
socket = UDPisReady();               //戻り値ソケット番号
  if(socket != 0xFF)                  //空で無いか?
  {
    //// 使用中のバッファの処理
    switch (
UDPuser[socket].PORTNO)     //ポート番号で分岐
    {
      case 10001:         //<-----ポート番号で処理内容を区別する
        lcd_clear();
        //// 受信した文字列データの表示
        for(i=0; i<
UDPuser[socket].user_size; i++)
          lcd_data(
UDPuser[socket].user_data[i]);
        //// 折り返し、0から64文字のASCII文字列を返送
        for (i=0; i<63; i++)
          
UDPuser[socket].user_data[i] = 0x30 + i;
        UDPuser[socket].user_data[63] = 0;
        UDPuser[socket].user_size = 64;
        
Send_UDP(socket);
        ///// バッファの開放
        
Release_UDP(socket);          //release this socket
        break;

      case 10002:
        //// 受信した文字列データの表示
        lcd_clear();
        for(i=0; i<
UDPuser[socket].user_size; i++)
          lcd_data(
UDPuser[socket].user_data[i]);
        
Release_UDP(socket);         //release this socket
        break;
      default:
        break;
    }
  }
  Exit_Task();     //<--------- これで本タスク終了
}


【PICROSコンフィギュレーション設定】

 上記ユーザーアプリのタスクを用意した上で、PICROSでLANライブラリ、
UDPユーザタスクを動作させるためには、下記のPICROSのヘッダファイルで
リンク指定をしてリンクを行います。

(1) PICROSのユーザーコンフィギュレーションでTCP/IPの使用を宣言追加
  コンフィギュレーションファイル(usrconf.h)に下記部分を追加する。
  これを記述すると、あとは初期化関数やアイドルループでのStackプロセス
  の起動など、自動的に追加されます。

 ////// Define LAN Controller Use ////////////
 // If define USE_STACK, then link LAN library
 #define USE_STACK     //スタックの使用宣言

 /////// Define Task ID Name and Priority ////////
 #define  task_number 5
 #define  task1 1         //testtsk1()
 #define  task2 2         //testtsk2()
 #define  task3 3         //testtsk3()
 #define  task4 4       //udp_user()
 #define  task6 6
 #define  task7 7
 #define  task8 8

 ////// task prototyping ////
 void  testtsk1(void);
 void  testtsk2(void);
 void  testtsk3(void);
 void  udp_user(void);    //UDP関数のプロトタイプ


(2) UDPユーザ処理タスクをリンクする。
  PICROSの「tasklink.h」にユーザ処理関数のタスクファイルをリンクします。
  tsklink.hファイルの作成例は下記のようになります。

 《tasklink.hの例》
 /////// Task Link //////
 #include <testtsk1.c>
 #include <testtsk2.c>
 #include <testtsk3.c>
 #IFDEF USE_UDP
 #include <udp_task.c>     <--- これがユーザー処理関数のファイル名
 #ENDIF 


(3) タスクディスパッチテーブルにユーザー処理関数を追加
  PICROSの「tdt.h」にユーザー処理関数名の追加をします。この関数が
 上記のユーザー処理タスクファイルの中に含まれていることになります。
 実際の追加例は下記のようになりますが、この記述順がタスク優先順位と
 なります。

   《tdt.hの例》
 ////////// Task Dispatch Tabel /////
 dispatch(1,testtsk1())
 dispatch(2,testtsk2())
 dispatch(3,testtsk3())

 #IFDEF USE_UDP
 dispatch(4,udp_user())      <--- これがユーザー処理関数名
 #ENDIF 


【制限事項】

 UDPをデータ送受信に使ってユーザー処理をするときには下記の制限が
ありますので守る必要があります。

(1) UDPのデバイス側ポート番号は 10000〜17000 を使うこと。
  本来は0〜65535まで使えますが、上記範囲に制限しています。
  ホスト側は特に制限していませんが、Well Known Portは使えません。

(2) 一度に送信できるデータ数は送受信とも最大制限があります。
  MAX_UDP_USRSIZE以上のデータを指定してもそれ以上は無視されます。

(3) 使えるPICは、PIC18シリーズに限定されています。
  現状ではRAM容量制限のため、PIC18シリーズのみで動作可能と
  なっています。

(4) 使用言語はCCS社C言語のPCH
  PIC用のCコンパイラである、CCS社の中の PIC18用である PCH を
  使用してコンパイルするものとしています。
  PCHをMPLABに統合した環境にして、MPLABでコンパイル、デバッグ
  作業をして下さい。

【LANライブラリソースファイル】

PICROSでUDP通信をするアプリケーション製作例のソースファイルは下記です。
PICROS本体とデバッグ用のライブラリも含んでいます。
MPLAB + PCHコンパイラ の環境を前提にしています。


UDPプロトコルモジュールの部分をポインタを使ってサイズを縮小しました。
その分高速になりました。約1kW小さくなりました。

ソースファイル変更分です。下記のファイルを前バージョンに上書きして下さい。
同じファイル名ですので気をつけて下さい。


  ★ ポインタを用いてサイズ縮小したUDP部分



ソースファイル1式は下記にあります。圧縮してあります。

  ★ PICROSとTCP/IPスタックライブラリででUDP通信するデモアプリ


この中には下表のソースファイルが含まれています。

ファイル名 機 能 内 容 概 要
stckdemo.c PICROS本体でTCP/IPスタックデモ用です。
アイドルループ内にStack_Process関数などが追加されています。
usrconf.h PICROSのユーザーコンフィギュレーションファイルです。
ここで、Stackの使用を宣言します。
tasklink.h
tdt.h
PICROSのタスクの追加をするときのコンフィギュレーション
ファイルです。ここにtask名や関数名を追加します。
usrini.c ユーザー初期化関数で、物理的な初期化処理を記述します。
最後に最初に起動しておくタスクの起動を行います。
lcd_lib.h
lcd_lib.c
PICROSの液晶表示器制御用のライブラリ関数
timer1.c PICROSの基本タイマの割り込み処理関数です。
debug77.c PICROSのデバッグ用の関数ライブラリです。
printf文でデバッグ文を挿入するときには必要です。
使用するときはusrconf.hで指定します。
usartrcv.c デバッグ用のUSARTの受信割り込み処理関数です。
testtask1.c
testtask2.c
tetstask3.c
PICROSを使ったときのユーザータスク関数です。
ここで実際に実行する処理を記述します。

testtask3は実際には起動していません。
udp_task.c UDPのテスト用のタスク関数で、UDPの処理はここに
記述します。



        目次に戻る