Documentation to use / test the driver in RTAI?

This forum covers PCAN-Linux and Linux development issues concerning our products
niklas.b
Posts: 9
Joined: Fri 23. Sep 2016, 13:43

Documentation to use / test the driver in RTAI?

Post by niklas.b » Tue 4. Oct 2016, 16:08

Hi,

I installed the pcan driver on a RTAI patched Linux according to the manual. Commands like

Code: Select all

cat /proc/pcan
or

Code: Select all

for f in /sys/class/pcan/pcanpci0/*; do [ -f $f ] && echo -n "'basename $f' = " && cat $f; done
shows me, that the driver seems to be installed correctly and ready for use.

But how to actually test and drive the ports now in the RTAI environment? The manual shows how to test in non-RT installations (where device nodes are created), but there are no extra char devices for PCAN using the RTAI installation (RTAI have these /dev/rtf* files, which have the major number 150 and * being the minor, if I understood correctly. These files can be used to communicate with the driver in user-space using FIFOs somehow (?)).

I found the "minimal_xenomai" test and tried to compile it for RTAI (the make file offers an RT=RTAI option), but the "native/task.h" file is missing (it only exists on xeno installations afaik).

So...does anyone knows where to find documentation and preferable examples about how to access the driver using RTAI?

User avatar
S.Grosjean
Software Development
Software Development
Posts: 357
Joined: Wed 4. Jul 2012, 17:02

Re: Documentation to use / test the driver in RTAI?

Post by S.Grosjean » Thu 6. Oct 2016, 10:18

Hello!

The system is not notified when a RT device is created by a RT driver, thus there won't be any related "/dev/" inode created in userspace, when a RT-pcan driver is loaded, nor any "aliases" like "pcanpcifdY" or "pcanusbZ".

Anyway, the device IS created and his RT-Kernel name is "pcanX" with X = the number the driver has given during the enum time, when it has been loaded. These numbers are shown by the "cat /proc/pcan" command.

When the examples say "/dev/pcanBLAHBLAH" then simply use "pcanX" instead.

Regards,

Stéphane
— Stéphane

niklas.b
Posts: 9
Joined: Fri 23. Sep 2016, 13:43

Re: Documentation to use / test the driver in RTAI?

Post by niklas.b » Fri 7. Oct 2016, 10:39

Hi,

so I tried to use the "receivetest" and "transmittest" in the "test" directory, by having multiple terminals open:

in terminal 1:

Code: Select all

./receivetest -f=/dev/pcan0 -b=0x14
(With -f=pcan0 it doesn NOT work: "cannot open ...". Also, the "-n" option in the manual is deprecated.)

in terminal 2:

Code: Select all

./transmitest transmit.txt -f=/dev/pcan0 -b=0x14
I was under the impression, that one could connect the ports 0 and 1 (for example) physically via a CAN-cable and now transmit on pcan1, but the transmittest only allowed me to open the same port as I opened in receivetest.

in terminal 3:

Code: Select all

lspcan -T -t -s -f
dev name port bus %bus rx %fifo tx %fifo err
[PCAN-PCI Express 0]
|_ pcanpci0 CAN1 PASSIVE - 1 0.00 52 100.00 2
|_ pcanpci1 CAN2 CLOSED - 0 0.00 0 0.00 0
|_ pcanpci2 CAN3 CLOSED - 0 0.00 0 0.00 0
|_ pcanpci3 CAN4 CLOSED - 0 0.00 0 0.00 0
Nothing happened in terminal 1 and 2, so I canceled both tests. I get:
in terminal 1:
receivetest: device node="/dev/pcan0"
Only standard frames are accepted, init with BTR0BTR1=0x0014
receivetest: driver version = Release_20160608_n
receivetest: reading data from CAN ... (press Ctrl-C to exit)
^Ctransmitest: finishing
receivetest: type = pci
io = 0xf7c00000
irq = 18
count of reads = 1
count of writes = 52
count of errors = 2
count of irqs = 2
last CAN status = 0x00a0
last error = 0
open paths = 1
driver version = Release_20160608_n
in terminal 2:
transmitest: device node="/dev/pcan0"
Only standard frames are sent, init with BTR0BTR1=0x0014
Data will be read from "transmit.txt".
transmitest: driver version = Release_20160608_n
transmitest: writing data to CAN ... (press Ctrl-C to exit)
^Ctransmitest: finishing
transmitest: type = pci
io = 0xf7c00000
irq = 18
count of reads = 1
count of writes = 52
count of errors = 2
count of irqs = 2
last CAN status = 0x00a0
last error = 0
open paths = 2
driver version = Release_20160608_n

Log gives me

Code: Select all

dmesg | tail
...
[ 1773.585588] pcan: failed requesting PCI IRQ 18 (err -16)
[ 1773.585596] pcan: can't request irq from device (err -16)

Proc interface:

Code: Select all

cat /proc/pcan
*------------- PEAK-System CAN interfaces (http://www.peak-system.com) -------------
*------------- Release_20160608_n (8.1.0) Oct 4 2016 13:44:51 --------------
*---------------------- [mod] [isa] [pci] [dng] [rt] ------------------------
*--------------------- 4 interfaces @ major 000 found -----------------------
*n -type- -ndev- --base-- irq --btr- --read-- --write- --irqs-- -errors- status
0 pci -NA- f7c00000 018 0x0014 00000001 00000034 00000002 00000002 0x0000
1 pci -NA- f7c00400 018 0x0014 00000000 00000000 00000000 00000000 0x0000
2 pci -NA- f7c00800 018 0x001c 00000000 00000000 00000000 00000000 0x0000
3 pci -NA- f7c00c00 018 0x001c 00000000 00000000 00000000 00000000 0x0000
(I tried the test with pcan1 too, that's why the baudrate is the same as pcan0)



Is there a special rtai module needed in order to run the rest properly? Currently, these rtai modules are loaded:

Code: Select all

lsmod | grep rtai
rtai_comedi 18864 0
kcomedilib 14229 1 rtai_comedi
rtai_netrpc 30000 0
rtai_msg 35063 0
rtai_mbx 17571 1 rtai_netrpc
rtai_fifos 38218 0
rtai_rtdm 345719 1 pcan
rtai_sem 35038 4 pcan,rtai_rtdm,rtai_mbx,rtai_netrpc
rtai_sched 101948 10 pcan,rtai_rtdm,rtai_mbx,rtai_msg,rtai_sem,kcomedilib,rtai_fifos,rtai_comedi,ni_pcimio,rtai_netrpc
rtai_hal 522893 16 mite,pcan,comedi_fc,rtai_rtdm,rtai_mbx,rtai_msg,rtai_sem,kcomedilib,comedi,ni_tio,rtai_fifos,rtai_sched,rtai_comedi,ni_pcimio,ni_tiocmd,rtai_netrpc


I also tried to run the examples in the pcanlib-basic, but during the compilation there were a few bugs, I had to fix:
- in the "PCAN_Basic_Linux-4.1.0/pcanbasic/src/pcbcore.c", line 949, I had to move the "int i" decleration out of the for-loop.
- some files could not be found, because in one of the source files in "PCAN_Basic_Linux-4.1.0/pcanbasic/src/libpcanfd/src" the path for the private lib was not set correctly
- in the "PCAN_Basic_Linux-4.1.0/pcanbasic/Makefile_latest.mk", there was somewhere a lib name wrong (libpcan instead of libpcanbasic), so it could not link correctly.

And I think that there are still other things not correct, because after finally compiling it (with RT=RTAI), the binaries still don't work:

Code: Select all

/home/rtai/PCAN_Basic_Linux-4.1.0/pcanbasic/examples/c++/pcanread
1475829127.956085: ERROR: failed to read line in file 'uevent'.
1475829127.956323: ERROR: failed to read line in file 'uevent'.
1475829127.956548: ERROR: failed to read line in file 'uevent'.
1475829127.956774: ERROR: failed to read line in file 'uevent'.
Initialize CAN: 512
Error 0x4000000

Edit:
it seem that writing works just fine. With both

Code: Select all

pcanfdtst tx --fd-non-iso -n 10 -ie 0x123 -l 2 -b 250k -d 2M -p 1s -c 60M pcan0
and the aforementioned transmittest, the tx counter of the device goes up and I can see the signal via a oszilloscope.

So my guess is, that I just cannot read on the same port while transmit. Just curious why i cannot open different ports at the same time.

User avatar
S.Grosjean
Software Development
Software Development
Posts: 357
Joined: Wed 4. Jul 2012, 17:02

Re: Documentation to use / test the driver in RTAI?

Post by S.Grosjean » Mon 10. Oct 2016, 10:03

Hi,

Our test programs do remove the "/dev/" prefix from the device node name characters string, to unify their use among the different worlds. But the real name of the device is "pcanX" only.

Did you put any terminator on the cable you have plugged on CAN1 (pcan0) ?

The fact that you're ablt to open only one port among 4 is abnormal. Could you please give us the complete output of:

Code: Select all

$ dmesg |grep pcan 
when you try to use "pcan1"? We'd like to know more about the "err -16" issue. Could you also give us the output of:

Code: Select all

$ cat /proc/interrupts
err -16 says that IRQ 18 is already in use.

Thx and regards,

Stéphane
— Stéphane

niklas.b
Posts: 9
Joined: Fri 23. Sep 2016, 13:43

Wrote some minimal tests

Post by niklas.b » Mon 17. Oct 2016, 10:31

Hi,

I wrote own, minimal tests (< 100 lines) for RTAI and PCAN now to tackle down the problem, please have a look at the attachement. To make it short, I posted one of the tests below.

What I found out was that I cannot open multiple ports at the same time using can_handle = LINUX_Can_Open("/dev/pcan<n>", 1). btw, what is this second parameter? The lib call it "nFlag", what does this mean? Anyway, when opening the second port/device, the handle goes NULL.

I can however open ports 0 and 1 (but not 2 or 3! ) at the same time using can_handle = CAN_Open(HW_PCI, <n>). Both handles are returned and I get no error when initializing both using errno = CAN_Init(can_handle<n>, CAN_BAUD CAN_BAUD_250K, CAN_INIT_TYPE_ST). The problem is, the baudrate does actually NOT set (in this case, not to 250k, it keeps standard 500k looking at cat /proc/pcan).

So, when I run the script below for the first time, I get the following:

Code: Select all

./multiport
pcan0 status = Broken pipe
pcan1 status = Broken pipe
Sending ... frame: m s 0x00000000 4 01 02 03 04
Receiving ... frame: m s 0x00000002 4 00 00 00 04

Code: Select all

cat /proc/pcan
*------------- PEAK-System CAN interfaces (http://www.peak-system.com) -------------
*------------- Release_20160608_n (8.1.0) Oct 4 2016 13:44:51 --------------
*---------------------- [mod] [isa] [pci] [dng] [rt] ------------------------
*--------------------- 4 interfaces @ major 000 found -----------------------
*n -type- -ndev- --base-- irq --btr- --read-- --write- --irqs-- -errors- status
0 pci -NA- f7c00000 018 0x011c 00000001 00000001 00000002 00000002 0x0000
1 pci -NA- f7c00400 018 0x001c 00000000 00000000 00000000 00000000 0x0000
2 pci -NA- f7c00800 018 0x001c 00000000 00000000 00000000 00000000 0x0000
3 pci -NA- f7c00c00 018 0x001c 00000000 00000000 00000000 00000000 0x0000

Code: Select all

dmesg | grep pcan
[ 3.482416] pcan: Release_20160608_n (le)
[ 3.482419] pcan: driver config [mod] [isa] [pci] [dng] [rt]
[ 3.487520] pcan: pci device minor 0 found
[ 3.487545] pcan: pci device minor 1 found
[ 3.487568] pcan: pci device minor 2 found
[ 3.487590] pcan: pci device minor 3 found
[ 3.487724] pcan: major 0.
[ 932.953945] Modules linked in: pcan(O) ni_pcimio(O) rtai_comedi(O) kcomedilib(O) rtai_netrpc(O) rtai_msg(O) rtai_mbx(O) rtai_fifos(O) rtai_rtdm(O) rtai_sem(O) rtai_sched(O) crc32c_intel ghash_clmulni_intel aesni_intel aes_x86_64 ablk_helper cryptd lrw gf128mul glue_helper joydev hid_generic hid_cherry eeepc_wmi asus_wmi evdev sparse_keymap mxm_wmi ni_tiocmd(O) mite(O) ni_tio(O) e1000e(O) 8255(O) comedi_fc(O) comedi(O) usbhid rtai_hal(O) ehci_pci ehci_hcd hid microcode shpchp serio_raw ptp video processor pps_core button acpi_pad wmi fuse parport_pc ppdev lp parport ext4 crc16 mbcache jbd2 sd_mod crc_t10dif ahci libahci libata xhci_hcd scsi_mod psmouse usbcore usb_common fan thermal thermal_sys
[ 932.954053] [<ffffffffa045f929>] ? pcan_pci_req_irq+0x39/0x90 [pcan]
[ 932.954057] [<ffffffffa0459bab>] ? pcan_open_path+0xcb/0x1a0 [pcan]

The cable connects physical ports 1 and 2 (I think they refer logical to 0 and 1?) and have a 120Ohm resistor between H and L. As you can see, I actually can receive the 4 bytes, I wrote out, but the baudrate is not set correctly and the ID and data is wrong.

Now, when I run the script a second and third time, I get:
root@tux1035:/usr/src/own_driver/minimal_pcan# ./multiport
pcan0 status = Broken pipe
pcan1 status = Broken pipe
Sending ... frame: m s 0x00000000 4 01 02 03 04
Receiving ... frame: m s 0x00000003 4 00 00 00 08
root@tux1035:/usr/src/own_driver/minimal_pcan# ./multiport
pcan0 status = Broken pipe
pcan1 status = Broken pipe
Sending ... frame: m s 0x00000000 4 01 02 03 04
^C
I have to abort the third time. dmesg is still the same after both runs. For the interrupts, I get:
rtai@tux1035:~$ cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 128 0 0 0 IO-APIC-edge timer
1: 3 0 0 0 IO-APIC-edge i8042
8: 1 0 0 0 IO-APIC-edge rtc0
9: 0 0 0 0 IO-APIC-fasteoi acpi
12: 4 0 0 0 IO-APIC-edge i8042
16: 10 18 1 1 IO-APIC-fasteoi ehci_hcd:usb3, ni_pcimio
17: 0 0 0 0 IO-APIC-fasteoi ni_pcimio
23: 29 4 1 0 IO-APIC-fasteoi ehci_hcd:usb4
41: 30 50691 0 3 PCI-MSI-edge xhci_hcd
42: 8509 1621 15927 6812 PCI-MSI-edge ahci
43: 15 123 15913 1 PCI-MSI-edge eth0
NMI: 112 140 112 110 Non-maskable interrupts
LOC: 165390 172083 158190 163842 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 112 140 112 110 Performance monitoring interrupts
IWI: 7445 7144 7591 7761 IRQ work interrupts
RTR: 2 0 0 0 APIC ICR read retries
RES: 543627 519393 550581 541863 Rescheduling interrupts
CAL: 351 439 390 523 Function call interrupts
TLB: 47346 51572 55613 49717 TLB shootdowns
ERR: 0
MIS: 0

I found some old posts regarding the problem: http://permalink.gmane.org/gmane.linux. ... rtai/24037. The interesting part:
But thanks to Mr. Tisserant from PEAK Systems I found my bug.
I just didn't compile RTDM/RTAI with Interrupt sharing support. After
recompiling RTAI and the PEAK driver the second channel of the card is
supported.
I have not found anything regarding how to compile with "Interrupt sharing support" on the internet or in the RTAI manual though.


My test-source-code:

Code: Select all

////////////////////////////////////////////////////////////////////////////////
//
// try to open multiple ports at once
// try to send from the first and receive on the other
//
////////////////////////////////////////////////////////////////////////////////


#include <stdlib.h> // for standard type definitions
#include <libpcan.h> // for PCAN stuff
#include <rtai_lxrt.h> // for RTAI stuff
#include <errno.h> // for tracking errors
#include <sys/mman.h> // for locking memory

#define CAN_PORT_1 0 // logical port number for physical port 1
#define CAN_PORT_2 1 // logical port number for physical port 2
#define CAN_BAUD CAN_BAUD_250K // baudrate for both ports

void print_frame(TPCANMsg *m) {
	/* prints content of a CAN frame*/

	// print message type, device ID, data length
	int i;
	printf("frame: %c %c 0x%08x %1d ",
			((m->MSGTYPE & MSGTYPE_RTR) ? 'r' : 'm') -
				((m->MSGTYPE & MSGTYPE_SELFRECEIVE) ? 0x20 : 0),
			(m->MSGTYPE & MSGTYPE_EXTENDED) ? 'e' : 's',
			 m->ID,
			 m->LEN);

	// print data bytes
	if (!(m->MSGTYPE & MSGTYPE_RTR))
		for (i = 0; i < m->LEN; i++)
			printf("%02x ", m->DATA[i]);

	printf("\n");
}

int main(int argc, char *argv[]) {

	// open port 1
	HANDLE h1 = CAN_Open(HW_PCI, CAN_PORT_1);
	if (!h1) printf("can't open pcan%d\n", CAN_PORT_1);
	printf("pcan%d status = %s\n", CAN_PORT_1, strerror(CAN_Status(h1)));
	// open port 2
	HANDLE h2 = CAN_Open(HW_PCI, CAN_PORT_2);
	if (!h2) printf("can't open pcan%d\n", CAN_PORT_2);
	printf("pcan%d status = %s\n", CAN_PORT_2, strerror(CAN_Status(h2)));

	// init port 1 with baudrate
	errno = CAN_Init(h1, CAN_BAUD, CAN_INIT_TYPE_ST);
	if (errno) {
		printf("can't initialize pcan%d. error %s\n", CAN_PORT_1, strerror(errno));
		goto error;
	}
	// init port 2 with baudrate
	errno = CAN_Init(h2, CAN_BAUD, CAN_INIT_TYPE_ST);
	if (errno) {
		printf("can't initialize pcan%d. error %s\n", CAN_PORT_2, strerror(errno));
		goto error;
	}

	// prepare a simple message to send
	TPCANMsg msg;
	msg.MSGTYPE = MSGTYPE_STANDARD;
	msg.LEN = 4;
	msg.ID = 0;
	msg.DATA[0] = 1;
	msg.DATA[1] = 2;
	msg.DATA[2] = 3;
	msg.DATA[3] = 4;

	// lock process's virtual address space into RAM
	mlockall(MCL_CURRENT | MCL_FUTURE);

	// make a task with name-ID 102 (can be any number) and priority 2 (0 is highest)
	RT_TASK *trx_task = rt_task_init_schmod(102, 2, 0, 0, SCHED_FIFO, 0xF);
	rt_make_hard_real_time();

	// send via port 1
	printf("Sending ... ");
	errno = CAN_Write(h1, &msg);
	if (errno) {
		printf("error while writing: %s\n", strerror(errno));
		goto error;
	}
	print_frame(&msg);

	// receive via port 2
	printf("Receiving ... ");
	errno = CAN_Read(h2, &msg); // this will block/wait until either an error occurs or data is coming
	if (errno) {
		printf("error while reading: %s\n", strerror(errno));
		goto error;
	}
	print_frame(&msg);

	// back to user mode
	rt_make_soft_real_time();
	rt_task_delete(trx_task);

error:
	// close ports
	CAN_Close(h1);
	CAN_Close(h2);
	return 0;
}
Attachments
minimal_pcan.tar.gz
(13.78 KiB) Downloaded 547 times

User avatar
S.Grosjean
Software Development
Software Development
Posts: 357
Joined: Wed 4. Jul 2012, 17:02

Re: Documentation to use / test the driver in RTAI?

Post by S.Grosjean » Tue 18. Oct 2016, 10:49

Hi!

1/ "nFlag" is used as 2nd arg of open()/rt_dev_open(). This should define O_RDWR bits.

2/ your multiport program does not create any RT task. You're using "CAN_Open()" libpcan RT library from some non-RT Linux thread! You MUST first create an RT task if you want using an RT driver!, as shown by (for example) test/src/pcanfdtst.c. Otheriwse, DON'T build pcan with "RT=" option and you'll be able to run it from any Linux program.

Regards,

Stéphane
— Stéphane

niklas.b
Posts: 9
Joined: Fri 23. Sep 2016, 13:43

Re: Documentation to use / test the driver in RTAI?

Post by niklas.b » Wed 19. Oct 2016, 09:30

Hi,

thanks for the hints. However, I actually create a RT task in all of my examples using

Code: Select all

RT_TASK *trx_task = rt_task_init_schmod(102, 2, 0, 0, SCHED_FIFO, 0xF);
rt_make_hard_real_time();
...
// the realtime stuff
...
rt_make_soft_real_time();
rt_task_delete(trx_task);
I now moved the creation of the task at the top of main, so it includes the opening of the ports, but the result is the same. Or do I have to run all the opening, initialization etc. in a rt THREAD?

However, I really think the problem is the interrupt sharing thing, so the baudrate is correctly set, but I have no clue how to solve this.

BR,
niklas

User avatar
S.Grosjean
Software Development
Software Development
Posts: 357
Joined: Wed 4. Jul 2012, 17:02

Re: Documentation to use / test the driver in RTAI?

Post by S.Grosjean » Thu 20. Oct 2016, 10:09

Hello,

By using the RT entry points of an RT driver, you MUST access it from an RT task. So you MUST open, ioctl, read/write and close it from an RT task only. The libpcan and libpcanfd enclose these RT entry points. So, you have to manage calling the CAN_xxx() entry points from an RT task exclusively.

RT kernels don't allow to share IRQ among RT and non-RT drivers. When the driver is loaded, could you please do:

Code: Select all

$ cat /proc/interrupts
as well as:

Code: Select all

$ cat /proc/pcan
Moreover, please do as before and post your modified program.

Meanwhile, could you please run the "pcanfdtst" program? Do as follow:

- connect CAN1 and CAN2 (for example) of your card to some CAN busses (500 kbps)
- open 2 shell sessions and run in the 1st one:

Code: Select all

$ test/pcanfdtst tx -i 0x123 -I 4 pcanX

- If everything is ok, run in the 2nd window:

Code: Select all

$ test/pcanfdtst tx -i 0x123 -I 4 pcanY


with Y=X+1 (that is, probably, pcan0 and pcan1).

Both windows should display plenty lines of 0x123 CAN frames with 4 bytes of data which increment, written every 1 ms. on each bus.

Thanks and regards,

Stéphane
— Stéphane

niklas.b
Posts: 9
Joined: Fri 23. Sep 2016, 13:43

Re: Documentation to use / test the driver in RTAI?

Post by niklas.b » Thu 20. Oct 2016, 15:17

Hi,

this is after driver is loaded and before any tests run.

Code: Select all

cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 128 0 0 0 IO-APIC-edge timer
1: 3 0 0 0 IO-APIC-edge i8042
8: 0 0 0 1 IO-APIC-edge rtc0
9: 0 0 0 0 IO-APIC-fasteoi acpi
12: 4 0 0 0 IO-APIC-edge i8042
16: 17 2 8 3 IO-APIC-fasteoi ehci_hcd:usb3, ni_pcimio
17: 0 0 0 0 IO-APIC-fasteoi ni_pcimio
23: 34 0 0 0 IO-APIC-fasteoi ehci_hcd:usb4
41: 6729 1009 1575 18686 PCI-MSI-edge ahci
42: 33 4147 2 1 PCI-MSI-edge xhci_hcd
43: 14 95 4153 0 PCI-MSI-edge eth0
NMI: 10 13 8 8 Non-maskable interrupts
LOC: 11131 11974 9164 10819 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 10 13 8 8 Performance monitoring interrupts
IWI: 682 366 364 949 IRQ work interrupts
RTR: 2 0 0 0 APIC ICR read retries
RES: 26061 22934 24606 23712 Rescheduling interrupts
CAL: 234 513 451 507 Function call interrupts
TLB: 3136 3852 2739 3135 TLB shootdowns
ERR: 0
MIS: 0

Code: Select all

cat /proc/pcan
*------------- PEAK-System CAN interfaces (www.peak-system.com) -------------
*------------- Release_20160608_n (8.1.0) Oct 4 2016 13:44:51 --------------
*---------------------- [mod] [isa] [pci] [dng] [rt] ------------------------
*--------------------- 4 interfaces @ major 000 found -----------------------
*n -type- -ndev- --base-- irq --btr- --read-- --write- --irqs-- -errors- status
0 pci -NA- f7c00000 018 0x001c 00000000 00000000 00000000 00000000 0x0000
1 pci -NA- f7c00400 018 0x001c 00000000 00000000 00000000 00000000 0x0000
2 pci -NA- f7c00800 018 0x001c 00000000 00000000 00000000 00000000 0x0000
3 pci -NA- f7c00c00 018 0x001c 00000000 00000000 00000000 00000000 0x0000
I connect port 1 and 2 via a BUS cable with 120Ohms.
First shell:

Code: Select all

/usr/src/can_driver/peak-linux-driver-8.1/test# ./pcanfdtst tx -i 0x123 -I 4 pcan0
I got (instantly) this and is hangs at the last line:
644.111809 pcan0 < 123 ..... [00 00 00 00]
644.112847 pcan0 < 123 ..... [01 00 00 00]
644.113859 pcan0 < 123 ..... [02 00 00 00]
644.113990 pcan0 > BUS STATE=WARNING
644.114877 pcan0 < 123 ..... [03 00 00 00]
644.115886 pcan0 < 123 ..... [04 00 00 00]
644.116895 pcan0 < 123 ..... [05 00 00 00]
644.117904 pcan0 < 123 ..... [06 00 00 00]
644.118916 pcan0 < 123 ..... [07 00 00 00]
644.119927 pcan0 < 123 ..... [08 00 00 00]
644.120936 pcan0 < 123 ..... [09 00 00 00]
644.121945 pcan0 < 123 ..... [0a 00 00 00]
644.122954 pcan0 < 123 ..... [0b 00 00 00]
644.123963 pcan0 < 123 ..... [0c 00 00 00]
644.124971 pcan0 < 123 ..... [0d 00 00 00]
644.125980 pcan0 < 123 ..... [0e 00 00 00]
644.126989 pcan0 < 123 ..... [0f 00 00 00]
644.127998 pcan0 < 123 ..... [10 00 00 00]
644.129007 pcan0 < 123 ..... [11 00 00 00]
644.130016 pcan0 < 123 ..... [12 00 00 00]
644.131024 pcan0 < 123 ..... [13 00 00 00]
644.132033 pcan0 < 123 ..... [14 00 00 00]
644.133042 pcan0 < 123 ..... [15 00 00 00]
644.134051 pcan0 < 123 ..... [16 00 00 00]
644.135064 pcan0 < 123 ..... [17 00 00 00]
644.136085 pcan0 < 123 ..... [18 00 00 00]
644.137103 pcan0 < 123 ..... [19 00 00 00]
644.138125 pcan0 < 123 ..... [1a 00 00 00]
644.139144 pcan0 < 123 ..... [1b 00 00 00]
644.140154 pcan0 < 123 ..... [1c 00 00 00]
644.141163 pcan0 < 123 ..... [1d 00 00 00]
644.142172 pcan0 < 123 ..... [1e 00 00 00]
644.143181 pcan0 < 123 ..... [1f 00 00 00]
644.144190 pcan0 < 123 ..... [20 00 00 00]
644.145199 pcan0 < 123 ..... [21 00 00 00]
644.146208 pcan0 < 123 ..... [22 00 00 00]
644.147217 pcan0 < 123 ..... [23 00 00 00]
644.148225 pcan0 < 123 ..... [24 00 00 00]
644.149234 pcan0 < 123 ..... [25 00 00 00]
644.150243 pcan0 < 123 ..... [26 00 00 00]
644.151252 pcan0 < 123 ..... [27 00 00 00]
644.152261 pcan0 < 123 ..... [28 00 00 00]
644.153270 pcan0 < 123 ..... [29 00 00 00]
644.154279 pcan0 < 123 ..... [2a 00 00 00]
644.155288 pcan0 < 123 ..... [2b 00 00 00]
644.156297 pcan0 < 123 ..... [2c 00 00 00]
644.157306 pcan0 < 123 ..... [2d 00 00 00]
644.158315 pcan0 < 123 ..... [2e 00 00 00]
644.159323 pcan0 < 123 ..... [2f 00 00 00]
644.160332 pcan0 < 123 ..... [30 00 00 00]
644.161341 pcan0 < 123 ..... [31 00 00 00]
644.162350 pcan0 < 123 ..... [32 00 00 00]
644.163363 pcan0 < 123 ..... [33 00 00 00]
644.164376 pcan0 < 123 ..... [34 00 00 00]
On the second shell:

Code: Select all

/usr/src/can_driver/peak-linux-driver-8.1/test# ./pcanfdtst tx -i 0x123 -I 4 pcan1
failed to open "pcan1" (err -16)

No pcan device is opened. Exiting application

Setup CAN[FD] tests between CAN channels over the pcan driver (>= v8.x)

WARNING
This application comes with ABSOLUTELY NO WARRANTY. This is free
software and you are welcome to redistribute it under certain
conditions. For details, see attached COPYING file.

USAGE
$ pcanfdtst MODE [OPTIONS] CAN [CAN...]

MODE
tx generate CAN traffic on the specified CAN interfaces
rx check CAN traffic received on the specified CAN interfaces

CAN
/dev/pcanx indicate which CAN interface is used in the test.
Several CAN interfaces can be specified. In that case,
each one is opened in non-blocking mode.

OPTIONS
-a | --accept f-t add message filter [f...t]
-b | --bitrate v set [nominal] bitrate to "v" bps
--btr0btr1 bitrates with BTR0BTR1 format
-B | --brs data bitrate used for sending CANFD msgs
-c | --clock v select clock frequency "v" Hz
-D | --debug (maybe too) lot of display
-d | --dbitrate v set data bitrate to "v" bps
-f | --fd select CAN-FD ISO mode
-F | --fd-non-iso select CAN-FD non-ISO mode
-h | --help display this help
-i | --id v|r set fixed CAN Id. "v" or randomly
-is v|r set fixed standard CAN Id. "v" or randomly
-ie v|r set fixed extented CAN Id. "v" or randomly
-I | --incr v "v"=nb of data bytes to use for increment counter
-l | --len v set fixed CAN dlc "v" for tests
-m | --mul v tx/rx "v" msgs at once
-n v do "v" test loops and stop
-o | --listen-only set pcan device in listen-only mode
-p | --pause-us v "v" us. pause between sys calls (rx/tx def=0/1000)
-q | --quiet nothing is displayed
-r | --rtr set the RTR flag to msgs sent
--no-rtr clear the RTR flag from msgs sent
-s | --stdmsg-only don't handle extended msgs
-t | --timeout-ms v wait "v" ms. for events
-u | --bus-load get bus load notifications from the driver
-v | --verbose things are (very much) explained
-w | --with-ts logs are prefixed with time of day (s.us)
When I ctrl-c the hanging program in shell 1, I got:
^Cpcan0 < [packets=53 calls=53 bytes=212 eagain=0]
sent frames: 53





cats after that:
root@tux1035:/usr/src/can_driver/peak-linux-driver-8.1/test# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 128 0 0 0 IO-APIC-edge timer
1: 3 0 0 0 IO-APIC-edge i8042
8: 0 0 0 1 IO-APIC-edge rtc0
9: 0 0 0 0 IO-APIC-fasteoi acpi
12: 4 0 0 0 IO-APIC-edge i8042
16: 17 2 8 3 IO-APIC-fasteoi ehci_hcd:usb3, ni_pcimio
17: 0 0 0 0 IO-APIC-fasteoi ni_pcimio
23: 34 0 0 0 IO-APIC-fasteoi ehci_hcd:usb4
41: 6729 1009 3498 18686 PCI-MSI-edge ahci
42: 33 16014 2 10777 PCI-MSI-edge xhci_hcd
43: 14 95 10306 0 PCI-MSI-edge eth0
NMI: 34 40 31 36 Non-maskable interrupts
LOC: 49587 53135 44807 50532 Local timer interrupts
SPU: 0 0 0 0 Spurious interrupts
PMI: 34 40 31 36 Performance monitoring interrupts
IWI: 895 634 682 1298 IRQ work interrupts
RTR: 2 0 0 0 APIC ICR read retries
RES: 126081 116442 128389 117193 Rescheduling interrupts
CAL: 234 513 451 507 Function call interrupts
TLB: 4083 4778 3703 4172 TLB shootdowns
ERR: 0
MIS: 0
root@tux1035:/usr/src/can_driver/peak-linux-driver-8.1/test# cat /proc/pcan

*------------- PEAK-System CAN interfaces (www.peak-system.com) -------------
*------------- Release_20160608_n (8.1.0) Oct 4 2016 13:44:51 --------------
*---------------------- [mod] [isa] [pci] [dng] [rt] ------------------------
*--------------------- 4 interfaces @ major 000 found -----------------------
*n -type- -ndev- --base-- irq --btr- --read-- --write- --irqs-- -errors- status
0 pci -NA- f7c00000 018 0x001c 00000001 00000035 00000003 00000003 0x0001
1 pci -NA- f7c00400 018 0x001c 00000000 00000000 00000000 00000000 0x0000
2 pci -NA- f7c00800 018 0x001c 00000000 00000000 00000000 00000000 0x0000
3 pci -NA- f7c00c00 018 0x001c 00000000 00000000 00000000 00000000 0x0000



The modified code of my own program (again: same symptoms as described in the last post):

Code: Select all

////////////////////////////////////////////////////////////////////////////////
//
// try to open multiple ports at once
// try to send from the first and receive on the other
//
////////////////////////////////////////////////////////////////////////////////


#include <stdlib.h> // for standard type definitions
#include <libpcan.h> // for PCAN stuff
#include <rtai_lxrt.h> // for RTAI stuff
#include <errno.h> // for tracking errors
#include <sys/mman.h> // for locking memory

#define CAN_PORT_1 0 // logical port number for physical port 1
#define CAN_PORT_2 1 // logical port number for physical port 2
#define CAN_BAUD CAN_BAUD_250K // baudrate for both ports

HANDLE h1; // CAN handle for port 1
HANDLE h2; // CAN handle for port 2
TPCANMsg msg; // CAN message struct
RT_TASK *trx_task; // realtime task

void print_frame(TPCANMsg *m) {
	/* prints content of a CAN frame*/

	// print message type, device ID, data length
	int i;
	printf("frame: %c %c 0x%08x %1d ",
			((m->MSGTYPE & MSGTYPE_RTR) ? 'r' : 'm') -
				((m->MSGTYPE & MSGTYPE_SELFRECEIVE) ? 0x20 : 0),
			(m->MSGTYPE & MSGTYPE_EXTENDED) ? 'e' : 's',
			 m->ID,
			 m->LEN);

	// print data bytes
	if (!(m->MSGTYPE & MSGTYPE_RTR))
		for (i = 0; i < m->LEN; i++)
			printf("%02x ", m->DATA[i]);

	printf("\n");
}

int main(int argc, char *argv[]) {
	// lock process's virtual address space into RAM
	mlockall(MCL_CURRENT | MCL_FUTURE);

	// make a task with name-ID 102 (can be any number) and priority 2 (0 is highest)
	trx_task = rt_task_init_schmod(102, 2, 0, 0, SCHED_FIFO, 0xF);
	rt_make_hard_real_time();

	// open port 1
	h1 = CAN_Open(HW_PCI, CAN_PORT_1);
	if (!h1) printf("can't open pcan%d\n", CAN_PORT_1);
	printf("pcan%d status = %s\n", CAN_PORT_1, strerror(CAN_Status(h1)));
	// open port 2
	h2 = CAN_Open(HW_PCI, CAN_PORT_2);
	if (!h2) printf("can't open pcan%d\n", CAN_PORT_2);
	printf("pcan%d status = %s\n", CAN_PORT_2, strerror(CAN_Status(h2)));

	// init port 1 with baudrate
	errno = CAN_Init(h1, CAN_BAUD, CAN_INIT_TYPE_ST);
	if (errno) {
		printf("can't initialize pcan%d. error %s\n", CAN_PORT_1, strerror(errno));
		goto error;
	}
	// init port 2 with baudrate
	errno = CAN_Init(h2, CAN_BAUD, CAN_INIT_TYPE_ST);
	if (errno) {
		printf("can't initialize pcan%d. error %s\n", CAN_PORT_2, strerror(errno));
		goto error;
	}

	// prepare a simple message to send
	msg.MSGTYPE = MSGTYPE_STANDARD;
	msg.LEN = 4;
	msg.ID = 0;
	msg.DATA[0] = 1;
	msg.DATA[1] = 2;
	msg.DATA[2] = 3;
	msg.DATA[3] = 4;

	// send via port 1
	printf("Sending ... ");
	errno = CAN_Write(h1, &msg);
	if (errno) {
		printf("error while writing: %s\n", strerror(errno));
		goto error;
	}
	print_frame(&msg);

	// receive via port 2
	printf("Receiving ... ");
	errno = CAN_Read(h2, &msg); // this will block/wait until either an error occurs or data is coming
	if (errno) {
		printf("error while reading: %s\n", strerror(errno));
		goto error;
	}
	print_frame(&msg);

	// back to user mode
	rt_make_soft_real_time();
	rt_task_delete(trx_task);

error:
	// close ports
	CAN_Close(h1);
	CAN_Close(h2);
	return 0;
}

Thanks and best regards,
niklas

User avatar
S.Grosjean
Software Development
Software Development
Posts: 357
Joined: Wed 4. Jul 2012, 17:02

Re: Documentation to use / test the driver in RTAI?

Post by S.Grosjean » Thu 20. Oct 2016, 19:42

Hi,

Did you connect the cable between both pcan0 and pcan1? If yes, you should not use two instances of "pcanfdtst" in "tx" mode. Use "pcanfdtst rx pcan1" (for example) instead, before launching "pcanfdtst tx pcan0"

Another test, please: connect pcan0 (which seems ok) with pcan2 or pcan3 and re-run "pcanfdtst rx" on each while you run "pcanfdtst tx pcan0".

Regarding the -EBUSY error on pcanY: did you check:

Code: Select all

 Add-ons  --->
[*] Real-Time Driver Model over RTAI
[*]   Shared interrupts
when you have configured your RTAI system?

If yes, I'd like to know what causes the -EBUSY: could you rebuild the pcan driver but in DEBUG mode, please? Here are the commands:

Code: Select all

$ cd driver
$ make clean
$ make RT=RTAI DBG=DEBUG
Then:

Code: Select all

$ rmmod pcan
$ insmod pcan.ko
Next:

Code: Select all

$ cd ..
$ test/pcanfdtst rx pcan0
and from another shell:

Code: Select all

$ test/pcanfdtst tx -n 1000 pcan1
Finally:

Code: Select all

$ dmesg | grep pcan
Thanks to give me the output of this last command.

Regards,

Stéphane
— Stéphane

Post Reply