rt/msr_module.c
branchkernel2.6
changeset 28 801dc7eabf51
child 33 f4171b8aadf8
equal deleted inserted replaced
27:d75ef6b46e33 28:801dc7eabf51
       
     1 /**************************************************************************************************
       
     2 *
       
     3 *                          msr_module.c
       
     4 *
       
     5 *           Kernelmodul für 2.6 Kernel zur Meßdatenerfassung, Steuerung und Regelung
       
     6 *           Zeitgeber ist der Timerinterrupt (tq)
       
     7 *           
       
     8 *           Autor: Wilhelm Hagemeister
       
     9 *
       
    10 *           (C) Copyright IgH 2002
       
    11 *           Ingenieurgemeinschaft IgH
       
    12 *           Heinz-Bäcker Str. 34
       
    13 *           D-45356 Essen
       
    14 *           Tel.: +49 201/61 99 31
       
    15 *           Fax.: +49 201/61 98 36
       
    16 *           E-mail: hm@igh-essen.com
       
    17 *
       
    18 *
       
    19 *           $RCSfile: msr_module.c,v $
       
    20 *           $Revision: 1.1 $
       
    21 *           $Author: hm $
       
    22 *           $Date: 2005/11/14 20:32:57 $
       
    23 *           $State: Exp $
       
    24 *
       
    25 *
       
    26 *           $Log: msr_module.c,v $
       
    27 *           Revision 1.1  2005/11/14 20:32:57  hm
       
    28 *           Initial revision
       
    29 *
       
    30 *           Revision 1.13  2005/06/17 11:35:13  hm
       
    31 *           *** empty log message ***
       
    32 *
       
    33 *
       
    34 *
       
    35 *
       
    36 **************************************************************************************************/
       
    37 
       
    38 
       
    39 /*--includes-------------------------------------------------------------------------------------*/
       
    40  
       
    41 
       
    42 #ifndef __KERNEL__
       
    43 #  define __KERNEL__
       
    44 #endif
       
    45 #ifndef MODULE
       
    46 #  define MODULE
       
    47 #endif
       
    48 
       
    49 #include <linux/config.h>
       
    50 #include <linux/module.h>
       
    51 
       
    52 #include <linux/sched.h>
       
    53 #include <linux/kernel.h>
       
    54 #include <linux/vmalloc.h> 
       
    55 #include <linux/fs.h>     /* everything... */
       
    56 #include <linux/proc_fs.h>
       
    57 #include <linux/time.h>
       
    58 #include <linux/timer.h>
       
    59 #include <linux/timex.h>  /* fuer get_cycles */
       
    60 #include <linux/errno.h>  /* error codes */
       
    61 #include <asm/msr.h> /* maschine-specific registers */
       
    62 #include <linux/param.h> /* fuer HZ */
       
    63 #include <linux/ipipe.h>
       
    64 
       
    65 #include "msr_param.h"   //wird im Projektverzeichnis erwartet
       
    66 
       
    67 //#include <msr_control.h>
       
    68 #include <msr_lists.h>
       
    69 #include <msr_charbuf.h>
       
    70 #include <msr_reg.h>
       
    71 #include <msr_error_reg.h>
       
    72 #include <msr_messages.h>
       
    73 #include <msr_proc.h>
       
    74 #include <msr_utils.h>
       
    75 #include <msr_main.h>
       
    76 
       
    77 
       
    78 #include <msr_float.h>
       
    79 
       
    80 #include "../drivers/ec_master.h"
       
    81 #include "../drivers/ec_device.h"
       
    82 #include "../drivers/ec_types.h"
       
    83 #include "../drivers/ec_module.h"
       
    84 
       
    85 #include "msr_jitter.h"
       
    86 
       
    87 MODULE_AUTHOR("Wilhelm Hagemeister, Ingenieurgemeinschaft IgH");
       
    88 MODULE_LICENSE("GPL");
       
    89 
       
    90 /*--external functions---------------------------------------------------------------------------*/
       
    91 
       
    92 /*--external data--------------------------------------------------------------------------------*/
       
    93 
       
    94 #define HZREDUCTION (MSR_ABTASTFREQUENZ/HZ)
       
    95 
       
    96 extern wait_queue_head_t msr_read_waitqueue;
       
    97 
       
    98 extern struct msr_char_buf *msr_kanal_puffer;
       
    99 
       
   100 extern int proc_abtastfrequenz;
       
   101 
       
   102 /*--public data----------------------------------------------------------------------------------*/
       
   103 /*--local data-----------------------------------------------------------------------------------*/
       
   104 //struct timer_list timer;
       
   105 
       
   106 extern struct timeval process_time;           
       
   107 struct timeval msr_time_increment;                    // Increment per Interrupt
       
   108 
       
   109 //adeos
       
   110 
       
   111 static struct ipipe_domain this_domain;
       
   112 
       
   113 static struct ipipe_sysinfo sys_info;
       
   114 
       
   115 static EtherCAT_master_t *ecat_master = NULL;
       
   116 
       
   117 static EtherCAT_slave_t ecat_slaves[] =
       
   118 {
       
   119 
       
   120 
       
   121 #if 1
       
   122     // Block 1
       
   123     ECAT_INIT_SLAVE(Beckhoff_EK1100),
       
   124     ECAT_INIT_SLAVE(Beckhoff_EL4102),
       
   125     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   126     ECAT_INIT_SLAVE(Beckhoff_EL3162),
       
   127     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   128     ECAT_INIT_SLAVE(Beckhoff_EL3102),
       
   129     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   130     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   131     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   132     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   133     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   134 
       
   135     // Block 2
       
   136     ECAT_INIT_SLAVE(Beckhoff_EK1100),
       
   137     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   138     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   139     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   140     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   141     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   142     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   143     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   144     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   145     ECAT_INIT_SLAVE(Beckhoff_EL2004),
       
   146     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   147     ECAT_INIT_SLAVE(Beckhoff_EL1014),
       
   148     ECAT_INIT_SLAVE(Beckhoff_EL1014)
       
   149 #endif
       
   150 
       
   151 #if 1
       
   152     // Block 3
       
   153    ,ECAT_INIT_SLAVE(Beckhoff_EK1100),
       
   154     ECAT_INIT_SLAVE(Beckhoff_EL3162),
       
   155     ECAT_INIT_SLAVE(Beckhoff_EL3162),
       
   156     ECAT_INIT_SLAVE(Beckhoff_EL3162),
       
   157     ECAT_INIT_SLAVE(Beckhoff_EL3162),
       
   158     ECAT_INIT_SLAVE(Beckhoff_EL3102),
       
   159     ECAT_INIT_SLAVE(Beckhoff_EL3102),
       
   160     ECAT_INIT_SLAVE(Beckhoff_EL3102),
       
   161     ECAT_INIT_SLAVE(Beckhoff_EL3102),
       
   162 
       
   163     ECAT_INIT_SLAVE(Beckhoff_EL4102),
       
   164     ECAT_INIT_SLAVE(Beckhoff_EL4102),
       
   165     ECAT_INIT_SLAVE(Beckhoff_EL4102),
       
   166     ECAT_INIT_SLAVE(Beckhoff_EL4102)
       
   167 
       
   168 
       
   169 #endif
       
   170 };
       
   171 
       
   172 #define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t))
       
   173 
       
   174 #define USE_MSR_LIB
       
   175 
       
   176 #ifdef USE_MSR_LIB
       
   177 double value;
       
   178 int dig1;
       
   179 #endif
       
   180 
       
   181 /******************************************************************************
       
   182  *
       
   183  * Function: next2004
       
   184  *
       
   185  *****************************************************************************/
       
   186 
       
   187 
       
   188 
       
   189 static int next2004(int *wrap)
       
   190 {
       
   191     static int i = 0;
       
   192     unsigned int j = 0;
       
   193 
       
   194     *wrap = 0;
       
   195 
       
   196     for (j = 0; j < ECAT_SLAVES_COUNT; j++)
       
   197     {
       
   198         i++;
       
   199 
       
   200         i %= ECAT_SLAVES_COUNT;
       
   201 
       
   202         if (i == 0) *wrap = 1;
       
   203 
       
   204         if (ecat_slaves[i].desc == Beckhoff_EL2004)
       
   205         {
       
   206             return i;
       
   207         }
       
   208     }
       
   209 
       
   210     return -1;
       
   211 }
       
   212 
       
   213 
       
   214 /******************************************************************************
       
   215  *
       
   216  * Function: msr_controller_run()
       
   217  *
       
   218  *****************************************************************************/
       
   219 
       
   220 static void msr_controller_run(void)
       
   221 {
       
   222     static int ms = 0;
       
   223     static int cnt = 0;
       
   224     static unsigned long int k = 0;
       
   225     static int firstrun = 1;
       
   226 
       
   227     static int klemme = 0;
       
   228     static int kanal = 0;
       
   229     static int up_down = 0;
       
   230     int wrap = 0;
       
   231 
       
   232 
       
   233     // Prozessdaten lesen
       
   234     msr_jitter_run(MSR_ABTASTFREQUENZ);
       
   235 
       
   236     if (!firstrun)
       
   237     {
       
   238         EtherCAT_read_process_data(ecat_master);
       
   239 
       
   240         // Daten lesen und skalieren
       
   241 #ifdef USE_MSR_LIB
       
   242         value = EtherCAT_read_value(&ecat_master->slaves[5], 0) / 3276.0; 
       
   243         dig1 = EtherCAT_read_value(&ecat_master->slaves[2], 0);
       
   244 #endif
       
   245     }
       
   246     else
       
   247         klemme = next2004(&wrap);
       
   248 
       
   249 
       
   250     ms++;
       
   251     ms %= 1000;
       
   252     if (cnt++ > 20)
       
   253     {
       
   254         cnt = 0;
       
   255 
       
   256         if (++kanal > 3)
       
   257         {
       
   258             kanal = 0;
       
   259             klemme = next2004(&wrap);
       
   260 
       
   261             if (wrap == 1)
       
   262             {
       
   263                 if (up_down == 1) up_down = 0;
       
   264                 else up_down = 1;
       
   265             }
       
   266         }
       
   267     }
       
   268 
       
   269     if (klemme >= 0) {
       
   270         EtherCAT_write_value(&ecat_master->slaves[klemme], kanal,up_down);
       
   271 	//printk("ECAT write: Klemme: %d, Kanal: %d, Wert: %d\n",klemme,kanal,up_down); 
       
   272     }
       
   273 
       
   274 #if 0
       
   275     EtherCAT_write_value(&ecat_master->slaves[13], 1, ms > 500 ? 0 : 1);
       
   276     EtherCAT_write_value(&ecat_master->slaves[14], 2, ms > 500 ? 0 : 1);
       
   277     EtherCAT_write_value(&ecat_master->slaves[15], 3, ms > 500 ? 1 : 0);
       
   278 #endif
       
   279 
       
   280     // Prozessdaten schreiben
       
   281     rdtscl(k);
       
   282     EtherCAT_write_process_data(ecat_master);
       
   283     firstrun = 0;
       
   284 
       
   285 }
       
   286 
       
   287 /*
       
   288 ***************************************************************************************************
       
   289 *
       
   290 * Function: msr_run(_interrupt)
       
   291 *
       
   292 * Beschreibung: Routine wird zyklisch im Timerinterrupt ausgeführt
       
   293 *               (hier muß alles rein, was Echtzeit ist ...)
       
   294 *
       
   295 * Parameter: Zeiger auf msr_data
       
   296 *
       
   297 * Rückgabe: 
       
   298 *               
       
   299 * Status: exp
       
   300 *
       
   301 ***************************************************************************************************
       
   302 */
       
   303 
       
   304 
       
   305 void msr_run(unsigned irq)
       
   306 {
       
   307 
       
   308     static int counter = 0;
       
   309 #ifdef USE_MSR_LIB
       
   310 
       
   311     timeval_add(&process_time,&process_time,&msr_time_increment); 
       
   312 
       
   313     MSR_ADEOS_INTERRUPT_CODE(
       
   314 	msr_controller_run();
       
   315 	msr_write_kanal_list();
       
   316 	);
       
   317 #else
       
   318     msr_controller_run();
       
   319 #endif
       
   320     /* und wieder in die Timerliste eintragen */
       
   321     /* und neu in die Taskqueue eintragen */    
       
   322 //    timer.expires += 1;
       
   323 //    add_timer(&timer);
       
   324 
       
   325     ipipe_control_irq(irq,0,IPIPE_ENABLE_MASK);  //nicht weiterreichen
       
   326     if(counter++ > HZREDUCTION) {
       
   327 	ipipe_propagate_irq(irq);  //wie lange braucht der Rest der Pipeline ??
       
   328 	counter = 0;
       
   329     }
       
   330 
       
   331 
       
   332 }
       
   333 
       
   334 void domain_entry (int iflag) {
       
   335     printk("Domain %s started.\n",	ipipe_current_domain->name);
       
   336 
       
   337 
       
   338     ipipe_get_sysinfo(&sys_info);
       
   339     ipipe_virtualize_irq(ipipe_current_domain,sys_info.archdep.tmirq,
       
   340 			 &msr_run, NULL, IPIPE_HANDLE_MASK);
       
   341 
       
   342     ipipe_tune_timer(1000000000UL/MSR_ABTASTFREQUENZ,0); 
       
   343 
       
   344 }
       
   345 
       
   346 /*
       
   347 *******************************************************************************
       
   348 *
       
   349 * Function: msr_register_channels
       
   350 *
       
   351 * Beschreibung: KanŽäle registrieren
       
   352 *
       
   353 * Parameter:
       
   354 *
       
   355 * RŽückgabe: 
       
   356 *               
       
   357 * Status: exp
       
   358 *
       
   359 *******************************************************************************
       
   360 */
       
   361 
       
   362 int msr_globals_register(void)
       
   363 {
       
   364 #ifdef USE_MSR_LIB
       
   365     msr_reg_kanal("/value", "V", &value, TDBL);
       
   366     msr_reg_kanal("/dig1", "", &dig1, TINT);
       
   367 #endif
       
   368 /*  msr_reg_kanal("/Taskinfo/Ecat/TX-Delay","us",&ecat_tx_delay,TUINT);
       
   369   msr_reg_kanal("/Taskinfo/Ecat/RX-Delay","us",&ecat_rx_delay,TUINT);
       
   370   msr_reg_kanal("/Taskinfo/Ecat/TX-Cnt","",&tx_intr,TUINT);
       
   371   msr_reg_kanal("/Taskinfo/Ecat/RX-Cnt","",&rx_intr,TUINT);
       
   372   msr_reg_kanal("/Taskinfo/Ecat/Total-Cnt","",&total_intr,TUINT);
       
   373 */
       
   374   return 0;
       
   375 }
       
   376 
       
   377 
       
   378 /****************************************************************************************************
       
   379  * the init/clean material
       
   380  ****************************************************************************************************/
       
   381 
       
   382 
       
   383 int __init init_module()
       
   384 {
       
   385     int result = 0;
       
   386 
       
   387     struct ipipe_domain_attr attr; //ipipe
       
   388 
       
   389     //als allererstes die RT-lib initialisieren    
       
   390 #ifdef USE_MSR_LIB
       
   391     result = msr_rtlib_init(1,MSR_ABTASTFREQUENZ,10,&msr_globals_register); 
       
   392 
       
   393     if (result < 0) {
       
   394         msr_print_warn("msr_modul: can't initialize rtlib!");
       
   395         return result;
       
   396     }
       
   397 #endif
       
   398 
       
   399     msr_jitter_init();
       
   400   printk(KERN_INFO "=== Starting EtherCAT environment... ===\n");
       
   401 
       
   402   if ((ecat_master = EtherCAT_master(0)) == NULL)
       
   403   {
       
   404     printk(KERN_ERR "No EtherCAT master available!\n");
       
   405     msr_rtlib_cleanup();    
       
   406     return -1;
       
   407   }
       
   408 
       
   409   printk("Checking EtherCAT slaves.\n");
       
   410 
       
   411   if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0)
       
   412   {
       
   413     printk(KERN_ERR "EtherCAT: Could not init slaves!\n");
       
   414     msr_rtlib_cleanup();    
       
   415     return -1;
       
   416   }
       
   417 
       
   418   printk("Activating all EtherCAT slaves.\n");
       
   419 
       
   420   if (EtherCAT_activate_all_slaves(ecat_master) != 0)
       
   421   {
       
   422     printk(KERN_ERR "EtherCAT: Could not activate slaves!\n");
       
   423     msr_rtlib_cleanup();    
       
   424     return -1;
       
   425   }
       
   426 
       
   427 
       
   428   do_gettimeofday(&process_time);			       
       
   429   msr_time_increment.tv_sec=0;
       
   430   msr_time_increment.tv_usec=(unsigned int)(1000000/MSR_ABTASTFREQUENZ);
       
   431 
       
   432     ipipe_init_attr (&attr);
       
   433     attr.name     = "IPIPE-MSR-MODULE";
       
   434     attr.priority = IPIPE_ROOT_PRIO + 1;
       
   435     attr.entry    = &domain_entry;
       
   436     ipipe_register_domain(&this_domain,&attr);
       
   437 
       
   438     //den Timertakt
       
   439 /*
       
   440   init_timer(&timer);
       
   441 
       
   442   timer.function = msr_run;
       
   443   timer.data = 0;
       
   444   timer.expires = jiffies+10; // Das erste Mal sofort feuern
       
   445   add_timer(&timer);
       
   446 */
       
   447   return 0; /* succeed */
       
   448 }
       
   449 
       
   450 
       
   451 //****************************************************************************
       
   452 void __exit cleanup_module()
       
   453 
       
   454 {
       
   455     msr_print_info("msk_modul: unloading...");
       
   456 
       
   457 
       
   458 //    del_timer_sync(&timer);
       
   459     ipipe_tune_timer(1000000000UL/HZ,0); //alten Timertakt wieder herstellen
       
   460 
       
   461     ipipe_unregister_domain(&this_domain);
       
   462 
       
   463 
       
   464 
       
   465     printk(KERN_INFO "=== Stopping EtherCAT environment... ===\n");
       
   466 
       
   467     if (ecat_master)
       
   468     {
       
   469       EtherCAT_clear_process_data(ecat_master);
       
   470       printk(KERN_INFO "Deactivating slaves.\n");
       
   471       EtherCAT_deactivate_all_slaves(ecat_master);
       
   472     }
       
   473 
       
   474     printk(KERN_INFO "=== EtherCAT environment stopped. ===\n");
       
   475 
       
   476 //    msr_controller_cleanup(); 
       
   477 #ifdef USE_MSR_LIB
       
   478     msr_rtlib_cleanup();    
       
   479 #endif
       
   480 }
       
   481 
       
   482 MODULE_LICENSE("GPL");
       
   483 MODULE_AUTHOR ("Wilhelm Hagemeister <hm@igh-essen.com>");
       
   484 MODULE_DESCRIPTION ("EtherCAT test environment");
       
   485 
       
   486 module_init(init_module);
       
   487 module_exit(cleanup_module);
       
   488  
       
   489 
       
   490 
       
   491 
       
   492 
       
   493 
       
   494 
       
   495 
       
   496 
       
   497 
       
   498 
       
   499 
       
   500 
       
   501 
       
   502 
       
   503