EtherCAT使用と解析-ethercatシステムカーネルモジュールのロードと初期化操作
linuxシステムにethercatシステムをインストール完了し、NIC MACと駆動を構成した後、sudo/etc/initを実行する.d/ethercat startはethercatシステムを起動し、このスクリプトでは本質的に2つのモジュールが呼び出されます.1つはマスタモジュールec_です.master.ko、一つは駆動モジュールec_generic.ko(ドライバモジュール部分についてはプロファイルのDEVICE_MODULESタイプによって決まりますが、ここでは一般的にgenericを選択します).
ec_master.ko:
このモジュールの初期化関数は./master/module.c/ec_init_module,このモジュールはethercatのマスタモジュールであり,主にethercatスレーブ情報の格納,domainsドメインの管理,スレーブ構成の管理などethercatシステムに関するリソースの管理,/etc/sysconfig/ethercatで構成されたMASTER 0_DEVICEはこのモジュールパラメータとしてマスタモジュールに伝達され、最終的にマスタモジュールとなるmacはネットワークアドレス、すなわちmaster->macsを使用する.マスタモジュールの初期化関数を順番に理解します.主に以下の部分があります.
1.文字デバイスの作成:文字デバイスを作成する目的は、アプリケーション層にインタフェースを提供し、アプリケーション層がカーネルを呼び出す機能を容易にすることです.作成された文字デバイスは、/dev/EtherCATx(/dev/EtherCAT 0、/dev/EtherCAT 1とすることができます.作成された文字デバイスは、マスタ局の数だけ作成されます)です.具体的な作成手順は、次のとおりです.
int alloc_の使用chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name);動的申請設備番号;
class_の使用createとdevice_createおよび上記申請したデバイスは、文字デバイス/dev/EtherCATを直接作成することができます.
2.マスタ構造の作成と初期化:
各MACアドレスは1つのマスタ空間に対応し、各マスタに対応する構造体は.master/master.hのec_master構造体、構造体は以下の通りです.
次に./master/master.c/ec_master_Init()関数は単一のマスタ構造体の初期化を行い,初期化内容は煩雑であり,その後の操作と結びつけて理解することが望ましい.この章ではこれ以上述べない.
ec_generic.ko:
このモジュールの初期化関数は./devices/generic.c/ec_gen_init_module()関数.この関数にはinit_があります.Netチェーンテーブル、このチェーンテーブルはカーネル空間の中で、すべてのNICデバイスを指しています.フィルタリングARPHRD_ETHERイーサネットカードのnetdevは、その後、これらのネットワークカード情報をマスタ局登録時に使用されるMACアドレスと照合して抽出し、照合が正常であればマスタ局をネットワーク装置に接続する、すなわちmaster->devices[0]->devは、照合されたnetdev構造体を指す(基本的にマスタ局に関連するnet_deviceタイプ構造体は、その構造情報を指す).マスタを使用してマスタとネットワーク機器をマッチングした後、ネットワーク通信を行うために、PF_を採用したソケットを申請する必要があるPACKETプロトコルファミリーの元のソケットは、元のソケットは、データフレームの送受信を行う際に完全なデータフレームであり、すなわち、受信したデータフレームは、ターゲットMAC+ソースMACおよびデータフレームタイプのような情報を含む.
ec_のロードgeneric.koモジュールは、ネットワーク構成が完了すると、マスタ局がネットワークデバイスを使用して通信することができ、ec_generic.koモジュールの初期化の最後に、ホスト局の送信、受信のコールバック関数を設定し、ホスト局を空き段階に切り替えた(これまでホスト局は孤児段階だった).次に、プライマリ・ステーションのアイドル・スレッド関数を開きます./master/master.c/ec_master_idle_thread().
ec_master.ko:
このモジュールの初期化関数は./master/module.c/ec_init_module,このモジュールはethercatのマスタモジュールであり,主にethercatスレーブ情報の格納,domainsドメインの管理,スレーブ構成の管理などethercatシステムに関するリソースの管理,/etc/sysconfig/ethercatで構成されたMASTER 0_DEVICEはこのモジュールパラメータとしてマスタモジュールに伝達され、最終的にマスタモジュールとなるmacはネットワークアドレス、すなわちmaster->macsを使用する.マスタモジュールの初期化関数を順番に理解します.主に以下の部分があります.
1.文字デバイスの作成:文字デバイスを作成する目的は、アプリケーション層にインタフェースを提供し、アプリケーション層がカーネルを呼び出す機能を容易にすることです.作成された文字デバイスは、/dev/EtherCATx(/dev/EtherCAT 0、/dev/EtherCAT 1とすることができます.作成された文字デバイスは、マスタ局の数だけ作成されます)です.具体的な作成手順は、次のとおりです.
int alloc_の使用chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name);動的申請設備番号;
class_の使用createとdevice_createおよび上記申請したデバイスは、文字デバイス/dev/EtherCATを直接作成することができます.
2.マスタ構造の作成と初期化:
各MACアドレスは1つのマスタ空間に対応し、各マスタに対応する構造体は.master/master.hのec_master構造体、構造体は以下の通りです.
struct ec_master
{
unsigned int index; /**< Index. ( ec_master mac ) */
/* , , 1 */
unsigned int reserved; /**< \a True, if the master is in use. */
ec_cdev_t cdev; /**< Master character device. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
struct device *class_device; /**< Master class device. ec_master /dev */
#else
struct class_device *class_device; /**< Master class device. */
#endif
#ifdef EC_RTDM
ec_rtdm_dev_t rtdm_dev; /**< RTDM device. */
#endif
struct semaphore master_sem; /**< Master semaphore. sema_init(&master->master_sem, 1); */
ec_device_t devices[EC_MAX_NUM_DEVICES]; /**< EtherCAT devices. EtherCAT */
const uint8_t *macs[EC_MAX_NUM_DEVICES]; /**< Device MAC addresses. mac , 0 1 */
#if EC_MAX_NUM_DEVICES > 1
unsigned int num_devices; /**< Number of devices. Access this always via
ec_master_num_devices(), because it may be
optimized!
mac , mac devices, mac 2, 1 */
#endif
struct semaphore device_sem; /**< Device semaphore. , */
ec_device_stats_t device_stats; /**< Device statistics. */
/* , ( 、 ), (fsm->state) 。 */
ec_fsm_master_t fsm; /**< Master state machine. */
ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */
/** Master phase. */
ec_master_phase_t phase;
/* , 0, , 1 */
unsigned int active; /**< Master has been activated. */
/* , config_changed 1,config_changed DC , configs */
unsigned int config_changed; /**< The configuration changed. */
/* 0, */
unsigned int injection_seq_fsm; /**< Datagram injection sequence number for the FSM side. FSM 。 */
/* 0, */
unsigned int injection_seq_rt; /**< Datagram injection sequence number for the realtime side. */
/* ethercat , , ethercat , 。 ec_master_init NULL, , ec_slave_t , */
ec_slave_t *slaves; /**< Array of slaves on the bus. */
/* ec_master_init 0, ( ) */
unsigned int slave_count; /**< Number of slaves on the bus. */
/* Configuration applied by the application. , ecrt_master_slave_config() configs */
/* list_head , , ec_slave_config_t( configs ) , ec_slave_config_t list_head, , */
struct list_head configs; /**< List of slave configurations. */
struct list_head domains; /**< List of domains. ( ) */
/* , ecrt_master_application_time() ioctl , linux , , examples/dc_user/main.c cycle_task() */
u64 app_time; /**< Time of the last ecrt_master_sync() call. */
/* */
u64 app_start_time; /**< Application start time. */
/* , , , */
u8 has_app_time; /**< Application time is valid. */
/* master/master.c/ec_master_find_dc_ref_clock() fpwr , 0x0910(4Byte) */
ec_datagram_t ref_sync_datagram; /**< Datagram used for synchronizing the reference clock to the master clock. */
/* master/master.c/ec_master_find_dc_ref_clock() frmw , , 0x0910(4Byte) */
ec_datagram_t sync_datagram; /**< Datagram used for DC drift compensation. */
ec_datagram_t sync_mon_datagram; /**< Datagram used for DC synchronisation monitoring. */
/* , , */
ec_slave_config_t *dc_ref_config; /**< Application-selected DC reference clock slave config. */
/* , dc_ref_config DC , dc_ref_config , , ethercat DC , */
ec_slave_t *dc_ref_clock; /**< DC reference clock slave. */
/* , allow_scan , scan_sem
:1. ( ) */
unsigned int scan_busy; /**< Current scan state. */
/* ,ec_master_init , , ec_master_init() 1, , , allow_scan 0, ec_master_leave_operation_phase() 1 */
unsigned int allow_scan; /**< \a True, if slave scanning is allowed. */
struct semaphore scan_sem; /**< Semaphore protecting the \a scan_busy
variable and the \a allow_scan flag. , scan_busy allow_scan */
wait_queue_head_t scan_queue; /**< Queue for processes that wait for slave scanning. */
unsigned int config_busy; /**< State of slave configuration. */
struct semaphore config_sem; /**< Semaphore protecting the \a config_busy
variable and the allow_config flag. */
wait_queue_head_t config_queue; /**< Queue for processes that wait for
slave configuration. */
/**
* 。 , read , ec_datagram_t->data 。 ( ); */
struct list_head datagram_queue; /**< Datagram queue. */
/* ec_master_init() index 0, , ;
datagram_index uint8_t, 255, ethercat ? */
uint8_t datagram_index; /**< Current datagram index. */
struct list_head ext_datagram_queue; /**< Queue for non-application datagrams. */
struct semaphore ext_queue_sem; /**< Semaphore protecting the ext_datagram_queue. */
/* , , */
ec_datagram_t ext_datagram_ring[EC_EXT_RING_SIZE]; /**< External datagram ring. ext-xx*/
/* , ec_datagram_t , SDO , sdo_requests SDO , , ec_datagram_t */
unsigned int ext_ring_idx_rt; /**< Index in external datagram ring for RT side. */
unsigned int ext_ring_idx_fsm; /**< Index in external datagram ring for FSM side. */
/* ecrt_master_send() (ms) */
unsigned int send_interval; /**< Interval(ms) between two calls to ecrt_master_send(). */
/* , , */
size_t max_queue_size; /**< Maximum size of datagram queue */
/* */
ec_slave_t *fsm_slave; /**< Slave that is queried next for FSM exec. FSM */
/* , ethercat/master/fsm_slave.h/ec_fsm_slave_t , , , ; , 。 */
struct list_head fsm_exec_list; /**< Slave FSM execution list. , master/fsm_slave.h/.c */
/* , fsm_exec_list */
unsigned int fsm_exec_count; /**< Number of entries in execution list. */
unsigned int debug_level; /**< Master debug level. */
ec_stats_t stats; /**< Cyclic statistics. */
/**
* , ec_master_idle_thread() ; ec_master_operation_thread() */
struct task_struct *thread; /**< Master thread. ,master.c NULL */
#ifdef EC_EOE
struct task_struct *eoe_thread; /**< EoE thread. */
struct list_head eoe_handlers; /**< Ethernet over EtherCAT handlers. */
#endif
struct semaphore io_sem; /**< Semaphore used in \a IDLE phase. */
// ,
/* NULL, master.c/ec_master_internal_send_cb */
void (*send_cb)(void *); /**< Current send datagrams callback. */
/* NULL, master.c/ec_master_internal_receive_cb */
void (*receive_cb)(void *); /**< Current receive datagrams callback. */
/* NULL, (ec_master ) */
void *cb_data; /**< Current callback data. */
void (*app_send_cb)(void *); /**< Application's send datagrams callback. NULL */
void (*app_receive_cb)(void *); /**< Application's receive datagrams callback. NULL */
void *app_cb_data; /**< Application callback data. NULL */
struct list_head sii_requests; /**< SII write requests. */
wait_queue_head_t request_queue; /**< Wait queue for external requests from user space. init_waitqueue_head() */
};
次に./master/master.c/ec_master_Init()関数は単一のマスタ構造体の初期化を行い,初期化内容は煩雑であり,その後の操作と結びつけて理解することが望ましい.この章ではこれ以上述べない.
ec_generic.ko:
このモジュールの初期化関数は./devices/generic.c/ec_gen_init_module()関数.この関数にはinit_があります.Netチェーンテーブル、このチェーンテーブルはカーネル空間の中で、すべてのNICデバイスを指しています.フィルタリングARPHRD_ETHERイーサネットカードのnetdevは、その後、これらのネットワークカード情報をマスタ局登録時に使用されるMACアドレスと照合して抽出し、照合が正常であればマスタ局をネットワーク装置に接続する、すなわちmaster->devices[0]->devは、照合されたnetdev構造体を指す(基本的にマスタ局に関連するnet_deviceタイプ構造体は、その構造情報を指す).マスタを使用してマスタとネットワーク機器をマッチングした後、ネットワーク通信を行うために、PF_を採用したソケットを申請する必要があるPACKETプロトコルファミリーの元のソケットは、元のソケットは、データフレームの送受信を行う際に完全なデータフレームであり、すなわち、受信したデータフレームは、ターゲットMAC+ソースMACおよびデータフレームタイプのような情報を含む.
ec_のロードgeneric.koモジュールは、ネットワーク構成が完了すると、マスタ局がネットワークデバイスを使用して通信することができ、ec_generic.koモジュールの初期化の最後に、ホスト局の送信、受信のコールバック関数を設定し、ホスト局を空き段階に切り替えた(これまでホスト局は孤児段階だった).次に、プライマリ・ステーションのアイドル・スレッド関数を開きます./master/master.c/ec_master_idle_thread().