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

MSR example finished.

parent bc19dca4
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,8 @@
#
# Makefile
#
# Sample module for use with IgH MSR library.
#
# $Id$
#
# Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH
......@@ -23,21 +25,17 @@
#
#------------------------------------------------------------------------------
ifneq ($(KERNELRELEASE),)
MODULE := ec_msr_sample
#------------------------------------------------------------------------------
# kbuild section
#------------------------------------------------------------------------------
ifneq ($(wildcard $(src)/rt.conf),)
include $(src)/rt.conf
else
MODULENAME := rt
endif
ifneq ($(KERNELRELEASE),)
obj-m := $(MODULENAME).o
obj-m := $(MODULE).o
$(MODULENAME)-objs := msr_rt.o \
$(MODULE)-objs := msr_sample.o \
rt_lib/msr-core/msr_lists.o \
rt_lib/msr-core/msr_main.o \
rt_lib/msr-core/msr_charbuf.o \
......@@ -52,22 +50,18 @@ $(MODULENAME)-objs := msr_rt.o \
rt_lib/msr-math/msr_hex_bin.o \
libm.o
EXTRA_CFLAGS := -I$(src)/rt_lib/msr-include -D_SIMULATION \
-I/usr/include -mhard-float \
-DSVNREV=$(shell svnversion $(src)) -DUSER=$(USER)
#------------------------------------------------------------------------------
else
EXTRA_CFLAGS := -I$(src)/rt_lib/msr-include -I/usr/realtime/include \
-D_SIMULATION -mhard-float
#------------------------------------------------------------------------------
# default section
#------------------------------------------------------------------------------
ifneq ($(wildcard rt.conf),)
include rt.conf
else
MODULENAME := msr_rt
ifneq ($(wildcard kernel.conf),)
include kernel.conf
else
KERNEL := $(shell uname -r)
endif
......@@ -80,8 +74,8 @@ clean:
$(MAKE) -C $(KERNELDIR) M=`pwd` clean
install:
@./install.sh $(MODULENAME) $(KERNEL)
#------------------------------------------------------------------------------
@./install.sh $(MODULE) $(KERNEL)
endif
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#
# Configuration file for msr realtime modules
# Configuration file for MSR realtime modules
#
# $Id$
#
# This file is a versioned template configuration. Copy it to "rt.conf"
# This file is a versioned template configuration. Copy it to "kernel.conf"
# (which is ignored by Subversion) and adjust it to your needs.
#
#------------------------------------------------------------------------------
# Module name (without extension)
MODULENAME := ec_rt_sample
# The kernel to compile the EtherCAT sources against
# Kernel sources for module compilation
KERNEL := `uname -r`
#------------------------------------------------------------------------------
#!/bin/sh
module="msr_rt"
module="ec_msr_sample"
device="msr"
mode="664"
......
/******************************************************************************
*
* m s r _ r t . c
*
* Kernelmodul fr 2.6 Kernel zur Medatenerfassung, Steuerung und Regelung.
* Sample module for use with IgH MSR library.
*
* $Id$
*
......@@ -27,18 +25,14 @@
// Linux
#include <linux/module.h>
#include <linux/ipipe.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
// RTAI
#include "rtai_sched.h"
#include "rtai_sem.h"
// RT_lib
#include <msr_main.h>
#include <msr_utils.h>
#include <msr_messages.h>
#include <msr_float.h>
#include <msr_reg.h>
#include <msr_time.h>
#include "msr_param.h"
// EtherCAT
......@@ -46,15 +40,21 @@
#define ASYNC
// Defines/Makros
#define HZREDUCTION (MSR_ABTASTFREQUENZ / HZ)
#define TIMERTICKS (1000000000 / MSR_ABTASTFREQUENZ)
/*****************************************************************************/
/* Globale Variablen */
// Adeos
static struct ipipe_domain this_domain;
static struct ipipe_sysinfo sys_info;
// RTAI
RT_TASK task;
SEM master_sem;
cycles_t t_start = 0, t_critical;
// MSR
extern unsigned long msr_controller_execution_time;
extern unsigned long msr_controller_call_time;
extern wait_queue_head_t msr_read_waitqueue;
int count_wakeup = 0;
// EtherCAT
ec_master_t *master = NULL;
......@@ -64,7 +64,7 @@ ec_domain_t *domain1 = NULL;
void *r_ssi;
void *r_ssi_st;
// Kanle
// Channels
uint32_t k_ssi;
uint32_t k_ssi_st;
......@@ -76,35 +76,64 @@ ec_field_init_t domain1_fields[] = {
/*****************************************************************************/
static void msr_controller_run(void)
void msr_run(long data)
{
cycles_t t_last_start;
while (1)
{
t_last_start = t_start;
t_start = get_cycles();
rt_sem_wait(&master_sem);
#ifdef ASYNC
// Empfangen
ecrt_master_async_receive(master);
ecrt_domain_process(domain1);
// Empfangen
ecrt_master_async_receive(master);
ecrt_domain_process(domain1);
#else
// Senden und empfangen
ecrt_domain_queue(domain1);
ecrt_master_run(master);
ecrt_master_sync_io(master);
ecrt_domain_process(domain1);
// Senden und empfangen
ecrt_domain_queue(domain1);
ecrt_master_run(master);
ecrt_master_sync_io(master);
ecrt_domain_process(domain1);
#endif
// Prozessdaten verarbeiten
k_ssi = EC_READ_U32(r_ssi);
k_ssi_st = EC_READ_U8 (r_ssi_st);
// Prozessdaten verarbeiten
k_ssi = EC_READ_U32(r_ssi);
k_ssi_st = EC_READ_U8 (r_ssi_st);
#ifdef ASYNC
// Senden
ecrt_domain_queue(domain1);
ecrt_master_run(master);
ecrt_master_async_send(master);
// Senden
ecrt_domain_queue(domain1);
ecrt_master_run(master);
ecrt_master_async_send(master);
#endif
rt_sem_signal(&master_sem);
/* write data to MSR ring buffers */
msr_write_kanal_list();
/* wake up MSR read queue */
if(++count_wakeup >= MSR_ABTASTFREQUENZ / 10) {
wake_up_interruptible(&msr_read_waitqueue);
count_wakeup = 0;
}
/* calculate timing */
msr_controller_execution_time =
(unsigned long) (get_cycles() - t_start) * 1000 / cpu_khz;
msr_controller_call_time =
(unsigned long) (t_start - t_last_start) * 1000 / cpu_khz;
rt_task_wait_period();
}
}
/*****************************************************************************/
int msr_globals_register(void)
int msr_reg(void)
{
msr_reg_kanal("/ssi_position", "", &k_ssi, TUINT);
msr_reg_kanal("/ssi_status", "", &k_ssi_st, TUINT);
......@@ -113,43 +142,38 @@ int msr_globals_register(void)
/*****************************************************************************/
void msr_run(unsigned irq)
int request_lock(void *data)
{
static int counter = 0;
MSR_ADEOS_INTERRUPT_CODE(msr_controller_run(); msr_write_kanal_list(););
// too close to the next RT cycle: deny access...
if (get_cycles() - t_start > t_critical) return -1;
ipipe_control_irq(irq, 0, IPIPE_ENABLE_MASK); // Interrupt besttigen
if (++counter >= HZREDUCTION) {
ipipe_propagate_irq(irq); // und weiterreichen
counter = 0;
}
// allow access
rt_sem_wait(&master_sem);
return 0;
}
/*****************************************************************************/
void domain_entry(void)
void release_lock(void *data)
{
printk("Domain %s started.\n", ipipe_current_domain->name);
ipipe_get_sysinfo(&sys_info);
ipipe_virtualize_irq(ipipe_current_domain,sys_info.archdep.tmirq,
&msr_run, NULL, IPIPE_HANDLE_MASK);
ipipe_tune_timer(1000000000UL / MSR_ABTASTFREQUENZ, 0);
rt_sem_signal(&master_sem);
}
/*****************************************************************************/
int __init init_rt_module(void)
int __init init_mod(void)
{
struct ipipe_domain_attr attr; //ipipe
#if 1
RTIME ticks;
#if 0
ec_slave_t *slave;
#endif
// Als allererstes die RT-Lib initialisieren
if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, &msr_globals_register) < 0) {
printk(KERN_INFO "=== Starting EtherCAT RTAI MSR sample module... ===\n");
rt_sem_init(&master_sem, 1);
t_critical = cpu_khz * 800 / MSR_ABTASTFREQUENZ; // ticks for 80%
if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, &msr_reg) < 0) {
printk(KERN_ERR "Failed to initialize rtlib!\n");
goto out_return;
}
......@@ -159,7 +183,7 @@ int __init init_rt_module(void)
goto out_msr_cleanup;
}
//ecrt_master_print(master, 2);
ecrt_master_callbacks(master, request_lock, release_lock, NULL);
printk(KERN_INFO "Creating domains...\n");
if (!(domain1 = ecrt_master_create_domain(master))) {
......@@ -179,13 +203,6 @@ int __init init_rt_module(void)
goto out_release_master;
}
#if 0
if (ecrt_master_start_eoe(master)) {
printk(KERN_ERR "Failed to start EoE processing!\n");
goto out_deactivate;
}
#endif
#if 0
if (ecrt_master_fetch_sdo_lists(master)) {
printk(KERN_ERR "Failed to fetch SDO lists!\n");
......@@ -196,7 +213,7 @@ int __init init_rt_module(void)
ecrt_master_print(master, 0);
#endif
#if 1
#if 0
if (!(slave = ecrt_master_get_slave(master, "0:3"))) {
printk(KERN_ERR "Failed to get slave!\n");
goto out_deactivate;
......@@ -235,62 +252,63 @@ int __init init_rt_module(void)
ecrt_master_prepare_async_io(master);
#endif
ipipe_init_attr(&attr);
attr.name = "IPIPE-MSR-MODULE";
attr.priority = IPIPE_ROOT_PRIO + 1;
attr.entry = &domain_entry;
ipipe_register_domain(&this_domain, &attr);
if (ecrt_master_start_eoe(master)) {
printk(KERN_ERR "Failed to start EoE processing!\n");
goto out_deactivate;
}
printk("Starting cyclic sample thread...\n");
ticks = start_rt_timer(nano2count(TIMERTICKS));
if (rt_task_init(&task, msr_run, 0, 2000, 0, 1, NULL)) {
printk(KERN_ERR "Failed to init RTAI task!\n");
goto out_stop_timer;
}
if (rt_task_make_periodic(&task, rt_get_time() + ticks, ticks)) {
printk(KERN_ERR "Failed to run RTAI task!\n");
goto out_stop_task;
}
printk(KERN_INFO "=== EtherCAT RTAI MSR sample module started. ===\n");
return 0;
#if 1
out_stop_task:
rt_task_delete(&task);
out_stop_timer:
stop_rt_timer();
out_deactivate:
ecrt_master_deactivate(master);
#endif
out_release_master:
ecrt_release_master(master);
out_msr_cleanup:
msr_rtlib_cleanup();
out_return:
rt_sem_delete(&master_sem);
return -1;
}
/*****************************************************************************/
void __exit cleanup_rt_module(void)
void __exit cleanup_mod(void)
{
printk(KERN_INFO "Cleanign up rt module...\n");
printk(KERN_INFO "=== Unloading EtherCAT RTAI MSR sample module... ===\n");
ipipe_tune_timer(1000000000UL / HZ, 0); // Alten Timertakt wiederherstellen
ipipe_unregister_domain(&this_domain);
printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n");
rt_task_delete(&task);
stop_rt_timer();
ecrt_master_deactivate(master);
ecrt_release_master(master);
printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
rt_sem_delete(&master_sem);
msr_rtlib_cleanup();
printk(KERN_INFO "=== EtherCAT RTAI MSR sample module unloaded. ===\n");
}
/*****************************************************************************/
#define EC_LIT(X) #X
#define EC_STR(X) EC_LIT(X)
#define COMPILE_INFO "Revision " EC_STR(SVNREV) \
", compiled by " EC_STR(USER) \
" at " __DATE__ " " __TIME__
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION ("EtherCAT real-time test environment");
MODULE_VERSION(COMPILE_INFO);
MODULE_DESCRIPTION ("EtherCAT RTAI MSR sample module");
module_init(init_rt_module);
module_exit(cleanup_rt_module);
module_init(init_mod);
module_exit(cleanup_mod);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/
#!/bin/sh
module="msr_rt"
module="ec_msr_sample"
device="msr"
# invoke rmmod with all arguments we got
......
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