# HG changeset patch # User Florian Pose # Date 1168268478 0 # Node ID 37aa1bfa0dee0580b58a03d2a97a41af1897c82d # Parent 3e5989834735b19ce650580601a8c446dc5ca18a Internal locking callbacks, improved locking. diff -r 3e5989834735 -r 37aa1bfa0dee master/master.c --- a/master/master.c Mon Jan 08 14:24:33 2007 +0000 +++ b/master/master.c Mon Jan 08 15:01:18 2007 +0000 @@ -330,10 +330,37 @@ /*****************************************************************************/ /** + Internal locking callback. +*/ + +int ec_master_request_cb(void *master /**< callback data */) +{ + spin_lock(&((ec_master_t *) master)->internal_lock); + return 0; +} + +/*****************************************************************************/ + +/** + Internal unlocking callback. +*/ + +void ec_master_release_cb(void *master /**< callback data */) +{ + spin_unlock(&((ec_master_t *) master)->internal_lock); +} + +/*****************************************************************************/ + +/** */ int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */) { + master->request_cb = ec_master_request_cb; + master->release_cb = ec_master_release_cb; + master->cb_data = master; + master->mode = EC_MASTER_MODE_IDLE; queue_delayed_work(master->workqueue, &master->idle_work, 1); return 0; @@ -455,9 +482,9 @@ ec_master_destroy_domains(master); - master->request_cb = NULL; - master->release_cb = NULL; - master->cb_data = NULL; + master->request_cb = ec_master_request_cb; + master->release_cb = ec_master_release_cb; + master->cb_data = master; master->mode = EC_MASTER_MODE_IDLE; queue_delayed_work(master->workqueue, &master->idle_work, 1); @@ -739,21 +766,22 @@ ec_master_t *master = (ec_master_t *) data; cycles_t cycles_start, cycles_end; - // aquire master lock + cycles_start = get_cycles(); + + // receive spin_lock_bh(&master->internal_lock); - - cycles_start = get_cycles(); ecrt_master_receive(master); + spin_unlock_bh(&master->internal_lock); // execute master state machine ec_fsm_exec(&master->fsm); + // send + spin_lock_bh(&master->internal_lock); ecrt_master_send(master); + spin_unlock_bh(&master->internal_lock); cycles_end = get_cycles(); - // release master lock - spin_unlock_bh(&master->internal_lock); - master->idle_cycle_times[master->idle_cycle_time_pos] = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; master->idle_cycle_time_pos++; @@ -1111,36 +1139,22 @@ } if (!active) goto queue_timer; - // aquire master lock... - if (master->mode == EC_MASTER_MODE_OPERATION) { - // request_cb must return 0, if the lock has been aquired! - if (master->request_cb(master->cb_data)) - goto queue_timer; - } - else if (master->mode == EC_MASTER_MODE_IDLE) { - spin_lock(&master->internal_lock); - } - else - goto queue_timer; - - // actual EoE processing + // receive datagrams + if (master->request_cb(master->cb_data)) goto queue_timer; cycles_start = get_cycles(); ecrt_master_receive(master); - + master->release_cb(master->cb_data); + + // actual EoE processing list_for_each_entry(eoe, &master->eoe_handlers, list) { ec_eoe_run(eoe); } + // send datagrams + if (master->request_cb(master->cb_data)) goto queue_timer; ecrt_master_send(master); cycles_end = get_cycles(); - - // release lock... - if (master->mode == EC_MASTER_MODE_OPERATION) { - master->release_cb(master->cb_data); - } - else if (master->mode == EC_MASTER_MODE_IDLE) { - spin_unlock(&master->internal_lock); - } + master->release_cb(master->cb_data); master->eoe_cycle_times[master->eoe_cycle_time_pos] = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;