UDP/IP アプリケーション

Japanese

このシステムは、 UDP/IP プロトコルによりデータシステムソフトウエアより制御のためのメソッド(パラメータ値の集合)や動作すべき命令を受け取り、質量分析装置の電源制御ハードウエアを駆動するとともに、現在の状態、電圧などのモニター値・設定値などをデータシステムに返送する単純なものである。

この試作制御ボードはコンソールとして使用できるシリアルインタフェースを持たず Ethernet で通信をする以外に外部とやりとりするすべを持たない。

このシステムは比較的単純な制御を目的としており、高価なリアルタイム OS を搭載しないいわゆる bare metal に構築する。

main

main() ルーチンでは、最初にアプリケーションのための初期化を行ったのち、無限ループで周期タイマーの処理、UDP/IP の入出力処理をシングルスレッドで行う。 OS が搭載されていないためセマフォなどの同期プリミティブが使えない。したがって割り込み処理内部で .bss セグメントへのアクセスはアトミックな操作(マシンサイクルで割り込まれない操作)しか行えない。

メインルーチン(抜粋)は以下のようである。

 

#include "lwip/init.h"
#include "lwip/netif.h"
#include "netif/etharp.h"
#include "ethif.h"
#include "timer.h"
#include "debug.h"
#include <string.h>
static struct netif eth0;
static ip_addr_t ipaddr, netmask, gw;
static unsigned char trap_flag;
static ip_addr_t trap_addr;
int
main()
{
    app_ctor();
    IP4_ADDR( &gw, 194,168,1,1 );
    IP4_ADDR( &ipaddr, 192,168,1,129 );
    IP4_ADDR( &netmask, 255,255,255,0 );

    enum FEATURE feature = app_initialize();
    if ( feature == FEATURE_IONSOURCE )
        IP4_ADDR( &ipaddr, 192,168,1,130 );

    // start sys_jiffies & enabling interrupts
    portio_enable_interrupts();
    app_activate(); // periodic process init & enable time a0
    smsc9210_insmod();

    // lwIP initialization
    lwip_init();
    ethif_insmod(); // insmod for eth0 interface (virtualize smsc9210)

    // add eth0 inteface into lwIP protocol stack
    netif_add( &eth0, &ipaddr, &netmask, &gw, NULL, 1, 0 );
    netif_set_default( &eth0 );
    netif_set_up( &eth0 );

    // activating lwIP ethernet hardware 
    ethif_init( &eth0 );
    netif_set_link_up( &eth0 );

    // initialize virtual debug console on UDP DST-PORT 20001
    debug_init( ipaddr );

    // lwIP timer initialize
    timer_init();
#if LWIP_ARP
    timer_set_interval( TIMER_EVT_ETHARPTMR, ARP_TMR_INTERVAL );
#endif
#if LWIP_TCP
    timer_set_interval( TIMER_EVT_TCPTMR, TCP_TMR_INTERVAL );
#endif

    // CONGLATURATIONS, your bare-metal system is fully initialized.
    if ( feature == FEATURE_IONSOURCE )
        debug_print( 0
                     , "POWER SUPPLY for Ion Source is up and running on %a"
                     , ipaddr.addr );
    else
        debug_print( 0
                     , "POWER SUPPLY for Analyzer is up and running on %a"
                     , ipaddr.addr );
    debug_print( 0, "Copyright(C) 2013 MS-Cheminformatics LLC" );
    debug_print( 0, "info@ms-cheminfo.com" );
    
    // start service
    app_main_loop( &eth0 );

    app_dtor();
}

 

main 処理フロー

  1. app_ctor() -- アプリケーションデータ構造体を初期化。
  2. IP4_ADDR -- lwIP で定義されたマクロを使用して IPv4 アドレスをハードコード
  3. enum FEATURE feature = app_initialize(); -- ディップスイッチからファームウエアがイオン源・アナライザーどちらの機能を提供すべきか読み取る
  4. portio_enable_interrupts(); -- PORT IO 割り込みを許可
  5. app_activate(); -- 周期起動用タイマを開始
  6. smsc9210_insmod(); -- SMSC-9210 Eternet PHY を初期化(初期化にタイマが必要)
  7. lwip_init(); -- lwIP モジュールを初期化
  8. IP スタックの起動 -- ethif (Ethenet IF) モジュールを初期化し SMSC-9201 ハードウエアと lwIP プロトコルスタックとを連携させる。
    1. ethif_insmod();
    2. netif_add( &eth0, &ipaddr, &netmask, &gw, NULL, 1, 0 );
    3. netif_set_default( &eth0 );
    4. netif_set_up( &eth0 );
      1. ethif (Ethernet) モジュールを初期化し、SMSC-9210 ハードウエアと lwIP プロトコルスタックを連携させる。
  9. ethif_init( &eth0 );
  10. netif_set_link_up( &eth0 );
  11. debug_init( ipaddr ) -- UDP PORT 20001 にファームウエアからのデバッグメッセージを出力するための初期化
  12. timer_init();
  13. timer_set_interval( TIMER_EVT_ETHARPTMR, ARP_TMR_INTERVAL );
  14. timer_set_interval( TIMER_EVT_TCPTMR, TCP_TMR_INTERVAL );
  15. app_main_loop( &eth0 ); -- アプリケーションの無限ループ
  16. app_dtor() -- アプリケーションの破棄(実際に呼ばれることはない)

 

User login