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, ¶m); 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