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