Skip to content
Snippets Groups Projects
Commit b9b128b8 authored by Florian Pose's avatar Florian Pose
Browse files

Applied RTAI interface to RTAI example.

parent 0c343785
No related branches found
No related tags found
No related merge requests found
...@@ -35,6 +35,8 @@ obj-m := ec_rtai_sample.o ...@@ -35,6 +35,8 @@ obj-m := ec_rtai_sample.o
ec_rtai_sample-objs := rtai_sample.o ec_rtai_sample-objs := rtai_sample.o
EXTRA_CFLAGS := -I/usr/realtime/include
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
else else
......
/****************************************************************************** /******************************************************************************
* *
* m i n i . c * RTAI sample for the IgH EtherCAT master.
*
* Minimal module for EtherCAT.
* *
* $Id$ * $Id$
* *
...@@ -28,22 +26,26 @@ ...@@ -28,22 +26,26 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "rtai.h"
#include "rtai_sched.h"
#include "rtai_sem.h"
#include "../../include/ecrt.h" // EtherCAT realtime interface #include "../../include/ecrt.h" // EtherCAT realtime interface
#define ASYNC #define ASYNC
#define FREQUENCY 100 #define TIMERTICKS 1000000
/*****************************************************************************/ /*****************************************************************************/
struct timer_list timer; // RTAI
RT_TASK task;
SEM master_sem;
// EtherCAT // EtherCAT
ec_master_t *master = NULL; ec_master_t *master = NULL;
ec_domain_t *domain1 = NULL; ec_domain_t *domain1 = NULL;
spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
// data fields // data fields
//void *r_ssi_input, *r_ssi_status, *r_4102[3]; //void *r_ssi_input, *r_ssi_status, *r_4102[3];
...@@ -60,76 +62,63 @@ ec_field_init_t domain1_fields[] = { ...@@ -60,76 +62,63 @@ ec_field_init_t domain1_fields[] = {
/*****************************************************************************/ /*****************************************************************************/
void run(unsigned long data) void run(long data)
{ {
static unsigned int counter = 0; while (1) {
rt_sem_wait(&master_sem);
spin_lock(&master_lock);
#ifdef ASYNC #ifdef ASYNC
// receive // receive
ecrt_master_async_receive(master); ecrt_master_async_receive(master);
ecrt_domain_process(domain1); ecrt_domain_process(domain1);
#else #else
// send and receive // send and receive
ecrt_domain_queue(domain1); ecrt_domain_queue(domain1);
ecrt_master_run(master); ecrt_master_run(master);
ecrt_master_sync_io(master); ecrt_master_sync_io(master);
ecrt_domain_process(domain1); ecrt_domain_process(domain1);
#endif #endif
// process data // process data
//k_pos = EC_READ_U32(r_ssi); //k_pos = EC_READ_U32(r_ssi);
#ifdef ASYNC #ifdef ASYNC
// send // send
ecrt_domain_queue(domain1); ecrt_domain_queue(domain1);
ecrt_master_run(master); ecrt_master_run(master);
ecrt_master_async_send(master); ecrt_master_async_send(master);
#endif #endif
spin_unlock(&master_lock); rt_sem_signal(&master_sem);
if (counter) { rt_task_wait_period();
counter--;
}
else {
counter = FREQUENCY;
//printk(KERN_INFO "k_pos = %i\n", k_pos);
//printk(KERN_INFO "k_stat = 0x%02X\n", k_stat);
} }
// restart timer
timer.expires += HZ / FREQUENCY;
add_timer(&timer);
} }
/*****************************************************************************/ /*****************************************************************************/
int request_lock(void *data) int request_lock(void *data)
{ {
unsigned int tries = 0; rt_sem_wait(&master_sem);
while (1) { return 0;
if (spin_trylock(&master_lock)) {
if (tries) printk(KERN_INFO "lock: %i tries needed.\n", tries);
return 1;
}
tries++;
}
} }
/*****************************************************************************/ /*****************************************************************************/
void release_lock(void *data) void release_lock(void *data)
{ {
spin_unlock(&master_lock); rt_sem_signal(&master_sem);
} }
/*****************************************************************************/ /*****************************************************************************/
int __init init_mini_module(void) int __init init_mod(void)
{ {
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n"); RTIME tick_period, requested_ticks, now;
printk(KERN_INFO "=== Starting EtherCAT RTAI sample module... ===\n");
rt_sem_init(&master_sem, 1);
if ((master = ecrt_request_master(0)) == NULL) { if ((master = ecrt_request_master(0)) == NULL) {
printk(KERN_ERR "Requesting master 0 failed!\n"); printk(KERN_ERR "Requesting master 0 failed!\n");
...@@ -200,56 +189,71 @@ int __init init_mini_module(void) ...@@ -200,56 +189,71 @@ int __init init_mini_module(void)
ecrt_master_prepare_async_io(master); ecrt_master_prepare_async_io(master);
#endif #endif
#if 1 #if 0
if (ecrt_master_start_eoe(master)) { if (ecrt_master_start_eoe(master)) {
printk(KERN_ERR "Failed to start EoE processing!\n"); printk(KERN_ERR "Failed to start EoE processing!\n");
goto out_deactivate; goto out_deactivate;
} }
#endif #endif
printk("Starting cyclic sample thread.\n"); printk("Starting cyclic sample thread...\n");
init_timer(&timer); requested_ticks = nano2count(TIMERTICKS);
timer.function = run; tick_period = start_rt_timer(requested_ticks);
timer.expires = jiffies + 10; printk(KERN_INFO "RT timer started with %i/%i ticks.\n",
add_timer(&timer); (int) tick_period, (int) requested_ticks);
if (rt_task_init(&task, run, 0, 2000, 0, 1, NULL)) {
printk(KERN_ERR "Failed to init RTAI task!\n");
goto out_stop_timer;
}
now = rt_get_time();
if (rt_task_make_periodic(&task, now + tick_period, tick_period)) {
printk(KERN_ERR "Failed to run RTAI task!\n");
goto out_stop_task;
}
printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n"); printk(KERN_INFO "=== EtherCAT RTAI sample module started. ===\n");
return 0; return 0;
#if 1 out_stop_task:
rt_task_delete(&task);
out_stop_timer:
stop_rt_timer();
out_deactivate: out_deactivate:
ecrt_master_deactivate(master); ecrt_master_deactivate(master);
#endif
out_release_master: out_release_master:
ecrt_release_master(master); ecrt_release_master(master);
out_return: out_return:
rt_sem_delete(&master_sem);
return -1; return -1;
} }
/*****************************************************************************/ /*****************************************************************************/
void __exit cleanup_mini_module(void) void __exit cleanup_mod(void)
{ {
printk(KERN_INFO "=== Stopping Minimal EtherCAT environment... ===\n"); printk(KERN_INFO "=== Stopping EtherCAT RTAI sample module... ===\n");
if (master) { printk(KERN_INFO "Stopping RT task...\n");
del_timer_sync(&timer); rt_task_delete(&task);
printk(KERN_INFO "Deactivating master...\n"); stop_rt_timer();
ecrt_master_deactivate(master); printk(KERN_INFO "Deactivating EtherCAT master...\n");
ecrt_release_master(master); ecrt_master_deactivate(master);
} ecrt_release_master(master);
rt_sem_delete(&master_sem);
printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n"); printk(KERN_INFO "=== EtherCAT RTAI sample module stopped. ===\n");
} }
/*****************************************************************************/ /*****************************************************************************/
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>"); MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("EtherCAT minimal test environment"); MODULE_DESCRIPTION ("EtherCAT RTAI sample module");
module_init(init_mini_module); module_init(init_mod);
module_exit(cleanup_mini_module); module_exit(cleanup_mod);
/*****************************************************************************/ /*****************************************************************************/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment