Hi everybody,

I use NMT-RTL v.2 with kernel 2.2.13 on a P200 + 64 Meg RAM.

I always work on my first program and receive a stupid during the
compilation phase. I don't know why? I mean then the function exist and I
have the right include files. My code is in attachment.

[root@localhost test_pci]# make
...
CBCtrl.c: In function `CBISR':
CBCtrl.c:70: warning: implicit declaration of function
`rtl_hard_disable_global_irq'
CBCtrl.c:105: warning: implicit declaration of function
`rtl_hard_enable_global_irq'
CBCtrl.c: In function `CBConfigure':  
CBCtrl.c:186: warning: assignment from incompatible pointer type (forget
this one, I must do this)

If you have an idea about it, send me a reply.

I also interest to know what time units are used as third argument of the
function pthread_suspend_np.

In my real time task, the priority is not important (the thread can be done
in late with not important consequences, every important things are done in
interrupt service routine). Can I set a very low priority or, in my case,
with only one thread, the priority will be high?

Thanks a lot,

Stephane Bouchard
[EMAIL PROTECTED]
Universite Laval
Quebec, Canada
#Automatically generated by rtl Makefile
RTL_DIR = /usr/src/rtlinux-2.0/rtl
RTLINUX_DIR = /usr/src/rtlinux-2.0/linux
RTL_MODULES=/lib/modules/2.2.13-rtl2.0/misc
INCLUDE= -I/usr/src/rtlinux-2.0/linux/include \
-I/usr/src/rtlinux-2.0/rtl/include \
-I/usr/src/rtlinux-2.0/rtl
CFLAGS = -I/usr/src/rtlinux-2.0/linux/include \
-I/usr/src/rtlinux-2.0/rtl/include \
-I/usr/src/rtlinux-2.0/rtl \
-I/usr/src/rtlinux-2.0/rtl/include/posix \
-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -D__RTL__ -D__KERNEL__ \
-DMODULE -pipe -fno-strength-reduce -m486 -malign-loops=2 -malign-jumps=2 \
-malign-functions=2 -DCPU=586 
ARCH = i386
CC = gcc


/* *********************************************************************** */
/*     ComputerBoard PCI-DAS1602/16 DAQ Board Driver / Controller          */
/* Stephane Bouchard                                                       */
/* [EMAIL PROTECTED] / [EMAIL PROTECTED]                               */
/* Laboratoire de Recherche en BioIngenierie                               */
/* Universite Laval, Quebec, Canada                                        */
/*                                                                         */
/* Tested and compiled with NMT-RT-Linux v2.0 with kernel 2.2.13           */
/* Special thanks to all people from RT-Linux mailing list                  */
/* only the need functionality for my project is implemented... you can    */
/* continue.                                                               */
/* *********************************************************************** */

#include <linux/pci.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/io.h>

#include <rtl_core.h>
#include <rtl_time.h>
#include <rtl_sched.h>
#include <rtl_fifo.h>
#include <rtl_sync.h>

#include "CBCommun.h"
#include "CBCtrl.h"

/* ************************************************************************ */
/* global variables                                                         */
/* ************************************************************************ */

BoardInfo board;
static unsigned int countIRQ;
pthread_t thread;
unsigned int numberscan;
unsigned char countChannel;
unsigned short regIntCp;
unsigned int dataRead[CHANNELNUMBER];

/* ************************************************************************ */
/* global variables and macro commands for FP operation in ISR              */

/* ************************************************************************ */

unsigned int cr0;
unsigned int linux_fpe[27];
unsigned int task_fpe[27];

#define save_cr0_and_ctls(x) __asm__ __volatile__ ("movl %%cr0,%0; clts" :"=r" (x))
#define restore_cr0(x)       __asm__ __volatile__ ("movl %0,%%cr0": :"r" (x))
#define save_fpenv(x)        __asm__ __volatile__ ("fnsave %0" : "=m" (x))
#define restore_fpenv(x)     __asm__ __volatile__ ("frstor %0" : "=m" (x))


/* ************************************************************************ */
/* volatile void CBISR();                                                   */
/* This function is call by the interrupt                                   */
/* args in          :                                                       */
/* args out         :                                                       */
/* global variables : struct BoardInfo board                                */
/*                    fifo                                                  */
/* Note:                                                                    */
/* ************************************************************************ */

unsigned int CBISR(unsigned int irq, struct pt_regs *ptregs) {

    /* disable the irq of the device during the isr */
    rtl_hard_disable_global_irq(board.irq);

    /* Start of floating point operation */
    save_cr0_and_ctls(cr0);
    save_fpenv(linux_fpe);
    restore_fpenv(task_fpe);

    /* read the datas from register */
    for (countChannel=0;countChannel<CHANNELNUMBER;countChannel++) {
         dataRead[countChannel]=(unsigned int)(readw(board.badr2)*0.5);
    };

    /* put controller and out here */


    /* stop of floating point operation */
    save_fpenv(task_fpe);
    restore_fpenv(linux_fpe);
    restore_cr0(cr0);

    /* check the number of scan and ... */
    if (countIRQ<numberscan) {
          /* increase the number of scan */
             countIRQ++;
             /*clear the interrupt */
             writew(0x0085, board.badr1);
    } else {
         /* stop pacer */
         writew(0x0000,board.badr1+0x0002);

         /* clear ADC fifo */
         writew(0x0000,board.badr2+0x0002); /* write junk */
    };

    /* enable the irq of this device */
    rtl_hard_enable_global_irq(board.irq);

    return 0;

};

/* ************************************************************************ */
/* short CBFind(void);                                                      */
/* This function look for the board. If find, set all information in struct */
/* BoardInfo board.                                                         */
/* args in          :                                                       */
/* args out         : short status                                          */
/*                    status : status of the function                       */
/* global variables : struct BoardInfo board                                */
/* ************************************************************************ */

short CBInit(void) {

        int done; /* flag for the fing */
     extern struct pci_dev *pdev; /*for stock the board configuration on linux */
     pdev=NULL;

     /* Check if a pci bus is present */
     if (!pci_present()) {
          return NOPCIBUS;
     };

     /* init the flag for the find */
     done=0;

     /* look for a ComputerBoards PCI-DAS1602/16 */
     while((!done)&&(pdev=pci_find_device(VENDORID, BOARDID, pdev))) {

          /* Map the pci memory in the cpu memory */
          board.badr0=(unsigned int *) ioremap(pdev->base_address[0], 0x0004);
          if(board.badr0==NULL) return IOREMAPERR;
          board.badr1=(unsigned short *) ioremap(pdev->base_address[1], 0x000A);
          if(board.badr1==NULL) return IOREMAPERR;
          board.badr2=(unsigned short *) ioremap(pdev->base_address[2], 0x0004);
          if(board.badr2==NULL) return IOREMAPERR;
          board.badr3=(unsigned char *) ioremap(pdev->base_address[3],0x000D);
          if(board.badr3==NULL )return IOREMAPERR;
          board.badr4=(unsigned short *) ioremap(pdev->base_address[4],0x0004);
          if(board.badr4==NULL) return IOREMAPERR;

          /* Setup informations in the struct BoardInfo board */
          board.irq=(unsigned int)pdev->irq;
          board.vendorID=(unsigned int)VENDORID;
          board.boardID=(unsigned int)BOARDID;

          /* Setup the flag done */
          done=1;
    };

     return NOERROR;
};

/* ************************************************************************ */
/* short CBConfigure(double frequency);                                     */
/* This function configure the board and set the frequency                  */
/* args in          : double frequency                                      */
/*                    frequency : sampling frequency of the board           */
/* args out         : short status                                          */
/*                    status : status of the function                       */
/* global variables : struct BoardInfo board                                */
/* ************************************************************************ */

short CBConfigure(double frequency) {

     /*allocate to backup the irq lines status */
     rtl_irqstate_t irqStatus;

     /* disable interrupts on the CPU */
     rtl_no_interrupts(irqStatus);

     /* configure the isr handler and get the interrupt */
     if(!rtl_request_global_irq(board.irq, CBISR)) {

          /* setup variable to make the computation of the diviser frequency */
          unsigned int diviserFrequency;
          unsigned short *diviserFreq;
          diviserFreq=&diviserFrequency;

          /* disable everything first */
          writew(0x0000,board.badr1);

          /* stop pacer */
          writew(0x0000,board.badr1+0x0002);

          /* clear ADC fifo */
          writew(0x0000,board.badr2+0x0002); /* write junk */

          /* setup pacer for internal pacer clock */
          /* 8254 - counter 1 mode 2 least significant bit */
          writeb(0x0054,board.badr3+0x0003);
          rtl_delay(10);
          /* 8254 - counter 2 mode 2 least significant bit */
          writeb(0x0094,board.badr3+0x0003);
          rtl_delay(10);

          /* compute the diviser for 82C54 (Pacer source at 10Mhz and 8 channels)*/
          diviserFrequency=(long)(10000000/frequency);

          /* write the ADC pacer diviser for generate the frequency */
          writeb(*(diviserFreq+4),board.badr3+0x0001); /* 0-7 bits   */
          rtl_delay(100);
          writeb(*(diviserFreq+3),board.badr3+0x0001); /* 8-15 bits  */
          rtl_delay(100);
          writeb(*(diviserFreq+2),board.badr3+0x0002); /* 16-23 bits */
          rtl_delay(100);
          writeb(*(diviserFreq+1),board.badr3+0x0002); /* 24-32 bits */
          rtl_delay(100);

          /* configure the dio */
          /* port A out, port B in, port C up out, port C low in */
          writeb(0x0082,board.badr3+0x0007);

          /* setup trigger control */
          /* No trigger set, burst mode select 10Mhz source fro counter 0*/
          writew(0x0020,board.badr1+0x0004);

          /*enable the acquisition interrupt */
          writew(0x0005, board.badr1);

          /* setup the irq as real-time irq */
          rtl_hard_enable_irq(board.irq);

          /* restore the interrupts for the cpu */
          rtl_restore_interrupts(irqStatus);

      } else {
          /* restore the interrupts for the cpu */
          rtl_restore_interrupts(irqStatus);

          return IRQREQUESTERR;
      };

      return NOERROR;
};

/* ************************************************************************ */
/* short CBStart();                                                         */
/* This function start the acquisition and the control loop                 */
/* args in          :                                                       */
/* args out         : short status                                          */
/*                    status : status of the function                       */
/* global variables : struct BoardInfo board                                */
/* ************************************************************************ */

short CBStart(void) {

    /*reset the number of int loop */
    countIRQ=0;

    /* clear ADC fifo */
    writew(0x0000,board.badr2+0x0002); /* write junk */

    /* setup the MUX and the control register */
    /* diff +/- 5 Volts, internal 82C54 Counter/Timer (10 Mhz) */
    /* and 8 channels */
    writew(0x1170,board.badr1+0x0002);

    return NOERROR;
};

/* ************************************************************************ */
/* short CBStop();                                                          */
/* This function stop the acquisition and the control loop                  */
/* args in          :                                                       */
/* args out         : short status                                          */
/*                    status : status of the function                       */
/* global variables : struct BoardInfo board                                */
/* ************************************************************************ */

short CBStop() {

    /* stop pacer */
    writew(0x0000,board.badr1+0x0002);

    /* clear ADC fifo */
    writew(0x0000,board.badr2+0x0002); /* write junk */

    return NOERROR;
};

/* ************************************************************************ */
/* void CBClose();                                                          */
/* This function close the device, please use CBStop before                 */
/* args in          :                                                       */
/* args out         :                                                       */
/* global variables : struct BoardInfo board                                */
/* ************************************************************************ */

void CBClose(void) {

    /* disable the burst mode */
    writew(0x0000, board.badr1+0x0004);

    /* disable the acquisition interrupt */
    writew(0x0000, board.badr1);

    /* free irq */
    if(board.irq!=0) rtl_free_global_irq(board.irq);

    board.irq=0;

    /* unmap all allocate memory mapped by the precessor*/
    iounmap(board.badr0);
    iounmap(board.badr1);
    iounmap(board.badr2);
    iounmap(board.badr3);
    iounmap(board.badr4);
};

/* ************************************************************************ */
/* void *CBModuleRT();                                                      */
/* This function send order to the interrupt.                               */
/* args in          :                                                       */
/* args out         :                                                       */
/* ************************************************************************ */

void *CBRTModule(void* junk) {

     unsigned char command;     /* command to execute */
     double frequency;          /* frequency of the acquisition */
     unsigned int scan;         /* number of scans to acquire */
     unsigned short status;     /* status of the command */
     struct sched_param param;

     param.sched_priority=5;
     pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
     pthread_make_periodic_np(pthread_self(), gethrtime(), 5000);

     while(1) {
                pthread_wait_np();

                switch(rtf_get(FIFO_COMMAND,&command,sizeof(unsigned char))) {
               case CB_CONFIGURE:
                    rtf_get(FIFO_COMMAND,&frequency,sizeof(double));
                    rtf_get(FIFO_COMMAND,&scan,sizeof(unsigned int));

                    /* init the status for compute the number of scan */
                    countIRQ=0;
                    numberscan=scan;

                    /* find the PCI DAQ board */
                    status=CBInit();

                    /* configure the PCI DAQ board */
                    status=CBConfigure(frequency);

               break;

               case CB_START:
                    status=CBStart();

               break;

               case CB_STOP:
                    status=CBStop();

               break;

               case CB_CLOSE:
                    /* disable acquisition */
                    CBStop();

                    /* close the device */
                    CBClose();

               break;

               default:
                   rtl_printf("Real time task unknown");

               break;
          };
     };
};

/* ************************************************************************ */
/* void CBInitModule();                                                     */
/* This function init the module to communicate with display program.       */
/* args in          :                                                       */
/* args out         :                                                       */
/* ************************************************************************ */

int init_module(void) {

    pthread_attr_t attr;

    /* setup the fifo */
    rtf_destroy(FIFO_COMMAND);
    rtf_create(FIFO_COMMAND,FIFO_COMMAND_SIZE);
    rtf_destroy(FIFO_STATUS);
    rtf_create(FIFO_STATUS,FIFO_STATUS_SIZE);

    pthread_attr_init(&attr);
    return pthread_create(&thread, &attr, CBRTModule, NULL);
};

/* ************************************************************************ */
/* void cleanup_module(void);                                               */
/* This function clear the communication module.                            */
/* args in                                                                  */
/* args out         :                                                       */
/* ************************************************************************ */

void cleanup_module(void) {

    CBClose();

    rtf_destroy(FIFO_COMMAND);
    rtf_destroy(FIFO_STATUS);

    pthread_delete_np(thread);
};


#ifndef _CBCTRL_ 
#define _CBCTRL_ 

unsigned int CBISR(unsigned int irq, struct pt_regs *ptregs);
short CBInit(void);
short CBConfigure(double frequency);
short CBStart(void);
short CBStop(void);
void  CBClose(void);
void  *CBRTModule(void* junk);
int   init_module(void);
void  cleanup_module(void);
 
#endif
#* *********************************************************************** *
#*     ComputerBoard PCI-DAS1602/16 DAQ Board Driver / Controller          *
#* Stephane Bouchard                                                       *
#* [EMAIL PROTECTED] / [EMAIL PROTECTED]                               *
#* Laboratoire de Recherche en BioIngenierie                               *
#* Universite Laval, Quebec, Canada                                        *
#*                                                                         *
#* Tested and compiled with NMT-RT-Linux v2.0 with kernel 2.2.13           *
#* Special thanks to all people from RT-Linux mailing list                 *
#* only the need functionality for my project is implemented... you can    *
#* continue.                                                               *
#* *********************************************************************** *

#* ************************************************************************ *
#* Compilation commands for CBCtrl module                                   *
#* ************************************************************************ *

all: CBCtrl.o

include rtl.mk

CBCtrl.o: CBCtrl.c CBCommun.h
        $(CC) ${INCLUDE} ${CFLAGS} -c CBCtrl.c

#* ************************************************************************ *
#* Clean the real-time module CBCtrl directory                              *
#* ************************************************************************ *

clean_CBCtrl:
        rm -f *.o

#* ************************************************************************ *
#* Stop the real-time module CBCtr                                          *
#* ************************************************************************ *

stop_CBCtrl:
        @echo "***************************************"
        @echo "*   Stop the real-time module CBCtrl  *"
        @echo "***************************************"
        @echo " "
        @echo "Hit a key to continue"
        @read junk
        @echo " "
        @echo "Remove the module"
        -rmmod CBCtrl
        @echo " "

#* ************************************************************************ *
#* Start the real-time module CBCtr                                         *
#* ************************************************************************ *

start_CBCtrl: all
        @echo "***************************************"
        @echo "*  Start the real-time module CBCtrl  *"
        @echo "***************************************"
        @echo " "
        @echo "Hit a key to continue"
        @read junk
        @echo " "
        @echo "Remove the module if existing"
        -rmmod CBCtrl
        @echo "Remove RTL if existing"
        (cd ../../; ./rmrtl)
        @echo "Install the RTL fifo and scheduler"
        (cd ../../; ./insrtl)
        @echo "Now start the CBCtrl module"
        @insmod CBCtrl.o
        @echo "You can now start the GUI CBCrtlGUI"
        @echo " "

#ifndef _CBCOMMON_
#define _CBCOMMON_

/* error list */
#define NOERROR          00
#define NOPCIBUS         01
#define NOPCIDAS160216   02
#define IOREMAPERR       03
#define ERRASIGNISR      04
#define IRQREQUESTERR    05
#define FIFOERR          06
#define DATAREADERR      07

/* define the code number for the inter-process message */
#define CB_CONFIGURE     01
#define CB_START         02
#define CB_STOP          03
#define CB_CLOSE         04

/* ComputerBoards PCI-DAS1602/16 definition*/
#define VENDORID 0x1307
#define BOARDID  0x0001

/* define the fifo */
#define FIFO_OUT_DATA 3
#define FIFO_OUT_DATA_NAME "dev/rtf3"
#define FIFO_OUT_DATA_SIZE 0x1000
#define FIFO_COMMAND 4
#define FIFO_COMMAND_NAME "dev/rtf4"
#define FIFO_COMMAND_SIZE 0x0100
#define FIFO_STATUS 5
#define FIFO_STATUS_NAME "dev/rtf5"
#define FIFO_STATUS_SIZE 0x0100

/* define the number of channel */
#define CHANNELNUMBER 8

/* define a structure to stock the board informations */
typedef struct {
     unsigned int *badr0;
     unsigned short *badr1;
     unsigned short *badr2;
     unsigned char  *badr3;
     unsigned short *badr4;
     unsigned int    irq;
     unsigned int    vendorID;
     unsigned int    boardID;
} BoardInfo ;


#endif



Reply via email to