mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-09-22 18:13:46 +08:00
Improved the callback mechanism.
This commit is contained in:
@@ -58,7 +58,6 @@
|
||||
// EtherCAT
|
||||
static ec_master_t *master = NULL;
|
||||
static ec_master_state_t master_state = {};
|
||||
spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
static ec_domain_t *domain1 = NULL;
|
||||
static ec_domain_state_t domain1_state = {};
|
||||
@@ -125,9 +124,9 @@ void check_domain1_state(void)
|
||||
{
|
||||
ec_domain_state_t ds;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_domain_state(domain1, &ds);
|
||||
spin_unlock(&master_lock);
|
||||
rt_sem_signal(&master_sem);
|
||||
|
||||
if (ds.working_counter != domain1_state.working_counter)
|
||||
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
|
||||
@@ -143,9 +142,9 @@ void check_master_state(void)
|
||||
{
|
||||
ec_master_state_t ms;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_master_state(master, &ms);
|
||||
spin_unlock(&master_lock);
|
||||
rt_sem_signal(&master_sem);
|
||||
|
||||
if (ms.slaves_responding != master_state.slaves_responding)
|
||||
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
|
||||
@@ -239,21 +238,26 @@ void run(long data)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int request_lock(void *data)
|
||||
void send_callback(ec_master_t *master)
|
||||
{
|
||||
// too close to the next real time cycle: deny access...
|
||||
if (get_cycles() - t_last_cycle > t_critical) return -1;
|
||||
|
||||
// allow access
|
||||
rt_sem_wait(&master_sem);
|
||||
return 0;
|
||||
if (get_cycles() - t_last_cycle <= t_critical) {
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_master_send_ext(master);
|
||||
rt_sem_signal(&master_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void release_lock(void *data)
|
||||
void receive_callback(ec_master_t *master)
|
||||
{
|
||||
rt_sem_signal(&master_sem);
|
||||
// too close to the next real time cycle: deny access...
|
||||
if (get_cycles() - t_last_cycle <= t_critical) {
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_master_receive(master);
|
||||
rt_sem_signal(&master_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -277,7 +281,7 @@ int __init init_mod(void)
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
ecrt_master_callbacks(master, request_lock, release_lock, NULL);
|
||||
ecrt_master_callbacks(master, send_callback, receive_callback);
|
||||
|
||||
printk(KERN_INFO PFX "Registering domain...\n");
|
||||
if (!(domain1 = ecrt_master_create_domain(master))) {
|
||||
|
||||
+22
-18
@@ -29,7 +29,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
// EtherCAT
|
||||
static ec_master_t *master = NULL;
|
||||
static ec_master_state_t master_state = {};
|
||||
spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
|
||||
struct semaphore master_sem;
|
||||
|
||||
static ec_domain_t *domain1 = NULL;
|
||||
static ec_domain_state_t domain1_state = {};
|
||||
@@ -192,9 +192,9 @@ void check_domain1_state(void)
|
||||
{
|
||||
ec_domain_state_t ds;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
down(&master_sem);
|
||||
ecrt_domain_state(domain1, &ds);
|
||||
spin_unlock(&master_lock);
|
||||
up(&master_sem);
|
||||
|
||||
if (ds.working_counter != domain1_state.working_counter)
|
||||
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
|
||||
@@ -210,9 +210,9 @@ void check_master_state(void)
|
||||
{
|
||||
ec_master_state_t ms;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
down(&master_sem);
|
||||
ecrt_master_state(master, &ms);
|
||||
spin_unlock(&master_lock);
|
||||
up(&master_sem);
|
||||
|
||||
if (ms.slaves_responding != master_state.slaves_responding)
|
||||
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
|
||||
@@ -230,9 +230,9 @@ void check_slave_config_states(void)
|
||||
{
|
||||
ec_slave_config_state_t s;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
down(&master_sem);
|
||||
ecrt_slave_config_state(sc_ana_in, &s);
|
||||
spin_unlock(&master_lock);
|
||||
up(&master_sem);
|
||||
|
||||
if (s.al_state != sc_ana_in_state.al_state)
|
||||
printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
|
||||
@@ -300,10 +300,10 @@ void read_voe(void)
|
||||
void cyclic_task(unsigned long data)
|
||||
{
|
||||
// receive process data
|
||||
spin_lock(&master_lock);
|
||||
down(&master_sem);
|
||||
ecrt_master_receive(master);
|
||||
ecrt_domain_process(domain1);
|
||||
spin_unlock(&master_lock);
|
||||
up(&master_sem);
|
||||
|
||||
// check process data state (optional)
|
||||
check_domain1_state();
|
||||
@@ -336,10 +336,10 @@ void cyclic_task(unsigned long data)
|
||||
EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
|
||||
|
||||
// send process data
|
||||
spin_lock(&master_lock);
|
||||
down(&master_sem);
|
||||
ecrt_domain_queue(domain1);
|
||||
ecrt_master_send(master);
|
||||
spin_unlock(&master_lock);
|
||||
up(&master_sem);
|
||||
|
||||
// restart timer
|
||||
timer.expires += HZ / FREQUENCY;
|
||||
@@ -348,17 +348,20 @@ void cyclic_task(unsigned long data)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int request_lock(void *data)
|
||||
void send_callback(ec_master_t *master)
|
||||
{
|
||||
spin_lock(&master_lock);
|
||||
return 0; // access allowed
|
||||
down(&master_sem);
|
||||
ecrt_master_send_ext(master);
|
||||
up(&master_sem);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void release_lock(void *data)
|
||||
void receive_callback(ec_master_t *master)
|
||||
{
|
||||
spin_unlock(&master_lock);
|
||||
down(&master_sem);
|
||||
ecrt_master_receive(master);
|
||||
up(&master_sem);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -382,7 +385,8 @@ int __init init_mini_module(void)
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
ecrt_master_callbacks(master, request_lock, release_lock, NULL);
|
||||
init_MUTEX(&master_sem);
|
||||
ecrt_master_callbacks(master, send_callback, receive_callback);
|
||||
|
||||
printk(KERN_INFO PFX "Registering domain...\n");
|
||||
if (!(domain1 = ecrt_master_create_domain(master))) {
|
||||
|
||||
+20
-17
@@ -59,7 +59,6 @@
|
||||
// EtherCAT
|
||||
static ec_master_t *master = NULL;
|
||||
static ec_master_state_t master_state = {};
|
||||
spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
static ec_domain_t *domain1 = NULL;
|
||||
static ec_domain_state_t domain1_state = {};
|
||||
@@ -146,9 +145,9 @@ void check_domain1_state(void)
|
||||
{
|
||||
ec_domain_state_t ds;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_domain_state(domain1, &ds);
|
||||
spin_unlock(&master_lock);
|
||||
rt_sem_signal(&master_sem);
|
||||
|
||||
if (ds.working_counter != domain1_state.working_counter)
|
||||
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
|
||||
@@ -164,9 +163,9 @@ void check_master_state(void)
|
||||
{
|
||||
ec_master_state_t ms;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_master_state(master, &ms);
|
||||
spin_unlock(&master_lock);
|
||||
rt_sem_signal(&master_sem);
|
||||
|
||||
if (ms.slaves_responding != master_state.slaves_responding)
|
||||
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
|
||||
@@ -184,9 +183,9 @@ void check_slave_config_states(void)
|
||||
{
|
||||
ec_slave_config_state_t s;
|
||||
|
||||
spin_lock(&master_lock);
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_slave_config_state(sc_ana_in, &s);
|
||||
spin_unlock(&master_lock);
|
||||
rt_sem_signal(&master_sem);
|
||||
|
||||
if (s.al_state != sc_ana_in_state.al_state)
|
||||
printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
|
||||
@@ -244,21 +243,26 @@ void run(long data)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int request_lock(void *data)
|
||||
void send_callback(ec_master_t *master)
|
||||
{
|
||||
// too close to the next real time cycle: deny access...
|
||||
if (get_cycles() - t_last_cycle > t_critical) return -1;
|
||||
|
||||
// allow access
|
||||
rt_sem_wait(&master_sem);
|
||||
return 0;
|
||||
if (get_cycles() - t_last_cycle <= t_critical) {
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_master_send_ext(master);
|
||||
rt_sem_signal(&master_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void release_lock(void *data)
|
||||
void receive_callback(ec_master_t *master)
|
||||
{
|
||||
rt_sem_signal(&master_sem);
|
||||
// too close to the next real time cycle: deny access...
|
||||
if (get_cycles() - t_last_cycle <= t_critical) {
|
||||
rt_sem_wait(&master_sem);
|
||||
ecrt_master_receive(master);
|
||||
rt_sem_signal(&master_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -277,7 +281,6 @@ int __init init_mod(void)
|
||||
|
||||
t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000;
|
||||
|
||||
|
||||
master = ecrt_request_master(0);
|
||||
if (IS_ERR(master)) {
|
||||
ret = PTR_ERR(master);
|
||||
@@ -285,7 +288,7 @@ int __init init_mod(void)
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
ecrt_master_callbacks(master, request_lock, release_lock, NULL);
|
||||
ecrt_master_callbacks(master, send_callback, receive_callback);
|
||||
|
||||
printk(KERN_INFO PFX "Registering domain...\n");
|
||||
if (!(domain1 = ecrt_master_create_domain(master))) {
|
||||
|
||||
Reference in New Issue
Block a user