Compile kvaser linuxCAN driver in TX1 fail

I try to compile kvaser linuxcan in TX1. But there are some error.

--------------------------------------------------------------------
building kvcommon
Kernel src: /lib/modules/3.10.96-tegra/build
make -C /lib/modules/`uname -r`/build SUBDIRS=/home/ubuntu/linuxcan/common modules
make[2]: Entering directory `/usr/src/linux-headers-3.10.96-tegra'
  CC [M]  /home/ubuntu/linuxcan/common/VCanOsIf.o
/home/ubuntu/linuxcan/common/VCanOsIf.c: In function ‘vCanDispatchEvent’:
/home/ubuntu/linuxcan/common/VCanOsIf.c:382:9: error: implicit declaration of function ‘atomic_set_mask’ [-Werror=implicit-function-declaration]
         atomic_set_mask(objbuf_mask, &fileNodePtr->objbufActive);
         ^
/home/ubuntu/linuxcan/common/VCanOsIf.c: At top level:
cc1: error: unrecognized command line option "-Wno-date-time" [-Werror]
cc1: all warnings being treated as errors
make[3]: *** [/home/ubuntu/linuxcan/common/VCanOsIf.o] Error 1
make[2]: *** [_module_/home/ubuntu/linuxcan/common] Error 2
make[2]: Leaving directory `/usr/src/linux-headers-3.10.96-tegra'
make[1]: *** [kv_module] Error 2
make[1]: Leaving directory `/home/ubuntu/linuxcan/common'
make: *** [common] Error 2

The code in driver file is like

#ifdef __arm__
        unsigned int rd;
        unsigned int new_rd;
        do {
          rd = atomic_read(&fileNodePtr->objbufActive);
          new_rd = rd | objbuf_mask;
        } while (atomic_cmpxchg(&fileNodePtr->objbufActive, rd, new_rd) != rd);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
        atomic_set_mask(objbuf_mask, &fileNodePtr->objbufActive);
#else
        atomic_or(objbuf_mask, &fileNodePtr->objbufActive);
#endif
        queue_work(fileNodePtr->objbufTaskQ,
                   &fileNodePtr->objbufWork);
      }
    }

Then I check the <asm/atomic.h> in TX1 system. But there is not atomic_set_mask. It only have atomic_or.
So I change the code like

#ifdef __arm__
        unsigned int rd;
        unsigned int new_rd;
        do {
          rd = atomic_read(&fileNodePtr->objbufActive);
          new_rd = rd | objbuf_mask;
        } while (atomic_cmpxchg(&fileNodePtr->objbufActive, rd, new_rd) != rd);
#else
        atomic_or(objbuf_mask, &fileNodePtr->objbufActive);
#endif
        queue_work(fileNodePtr->objbufTaskQ,
                   &fileNodePtr->objbufWork);
      }
    }

or

unsigned int rd;
        unsigned int new_rd;
        do {
          rd = atomic_read(&fileNodePtr->objbufActive);
          new_rd = rd | objbuf_mask;
        } while (atomic_cmpxchg(&fileNodePtr->objbufActive, rd, new_rd) != rd);

But there is a new error like

--------------------------------------------------------------------
building kvcommon
Kernel src: /lib/modules/3.10.96-tegra/build
make -C /lib/modules/`uname -r`/build SUBDIRS=/home/ubuntu/linuxcan/common modul                                                                                                                                                             es
make[2]: Entering directory `/usr/src/linux-headers-3.10.96-tegra'
  CC [M]  /home/ubuntu/linuxcan/common/VCanOsIf.o
scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: "(" unexpected
make[3]: *** [/home/ubuntu/linuxcan/common/VCanOsIf.o] Error 2
make[2]: *** [_module_/home/ubuntu/linuxcan/common] Error 2
make[2]: Leaving directory `/usr/src/linux-headers-3.10.96-tegra'
make[1]: *** [kv_module] Error 2
make[1]: Leaving directory `/home/ubuntu/linuxcan/common'
make: *** [common] Error 2

Any help is really appreciated!

Where is this driver from, and is it designed to work with a 3.x version kernel? Was it designed to work with 64-bit (arm64)?

A second part I notice is related to this error:

cc1: error: unrecognized command line option "-Wno-date-time" [-Werror]

…this might be a compiler error due to using a compiler of a completely incorrect architecture, or might be from using a compiler support a different standard than expected (think of mixing old and new standards from software from different years mixing with code expecting the compiler to support a certain way of doing things from some standard which has changed).

A comment on this error:

scripts/basic/fixdep: 1: scripts/basic/fixdep: Syntax error: "(" unexpected

…this could be just bad code, but one very significant change between different compiler versions over time (Linaro does this a lot) is to change the semantics of what is or isn’t legal for parenthesis to be considered non-ambiguous…it could be that a newer compiler is used which tightened requirements and now marks the current use of parenthesis an error. If this latter is the case, then adding more parenthesis to make them less ambiguous would solve the one problem.

Which compiler are you using? I assume you are cross compiling, so you’d need both a 64-bit and 32-bit compiler.

At first thank you for help.
I want to compile the driver in TX1.

At first the error is

gcc: error: unrecognized command line option ‘-mgeneral-regs-only’

So I follow

https://devtalk.nvidia.com/default/topic/906942/failed-to-compile-kernel-module-gcc-cannot-recognize-aarch64-option-mgeneral-regs-only-/#4768594

to install a compiler for arm64.
And then, it’s shown the same error.

The driver is

"Tested under x86_64 SMP Ubuntu 14.04 x32/x64 (3.13.0-32-generic/3.13.0-32-generic)."
"Compiled with gcc version 6.1.1, 4.8.4, 4.6.3, 4.7.3, 4.8.2 and 6.1.1."

and

"System requirements: Linux 2.6.26 or later."

That driver is already worked in my desktop-PC with 64bit ubuntu 14.04.4.

But in TX1, I install a 32-bit OS because some other software reauire 32-bit OS.

BTW the driver can use in raspberry pi.

The kernel with this release requires some bug fixes before it compiles (including general regs), these are a summary (the double quote mark listed below may be fixed in the most recent kernel):

NOTE: May need to edit "Makefile" KBUILD_CFLAGS_KERNEL to have "-fomit-frame-pointer"
KBUILD_CFLAGS_KERNEL := -fomit-frame-pointer

NOTE: May need to edit "drivers/platform/tegra/tegra21_clocks.c:1065"
     c->state = ((!is_lp_cluster()) == (c->u.cpu.mode == MODE_G)) ? ON : OFF;

NOTE: drivers/base/Kconfig, line 234, missing double quote to close string.
NOTE: May need to edit "drivers/platform/tegra/tegra21_clocks.c:1065"
NOTE: toplevel Makefile, KBUILD_CFLAGS_KERNEL := -fomit-frame-pointer
            c->state = ((!is_lp_cluster()) == (c->u.cpu.mode == MODE_G)) ? ON : OFF;

It sounds like kernels after 2.6.26 are worded as working, but usually there are significant modifications before a 2.6 kernel driver works in 3.x+. Make those above adjustments and give it a shot.

FYI, the kernel is always 64-bit, the 32-bit earlier releases were user space only for 32-bit support (the kernel puts the CPU in compatibility mode…there’s a big performance hit for that if it matters).

Hi, I’m also trying to build kvaser canlib driver on TX1 and I’m encountering the same issues.
Any update on this? I have kernel version 3.10.96.

EDIT: does the driver compile ok on TX2? if yes, I’ll switch to TX2. Can somebody try? :) The driver can be found here: https://www.kvaser.com/linux-drivers-and-sdk/

NOTE: I had thought this was TX2 originally. You’ll have to adjust for this if you use TX1, but it does work in TX2.

Looks like the full kernel source has “arm/include/asm/opcodes.h”, but the header package in “/usr/src/linux-headers-4.4.15-tegra” does not match the kernel source (headers present in full source are missing in “/usr/src/linux-headers-4.4.15-tegra”).

This isn’t really the right way to do it, the headers package should probably be updated, but here is a very hackish way to make it work…

I unpacked the full kernel source in “/usr/local/src/”, which results in “/usr/local/src/kernel/kernel-4.4” existing. I copied “/proc/config.gz” there, unzipped, renamed to “.config”, loaded that in “make menuconfig” (add package “ncurses-dev”), set CONFIG_LOCALVERSION to “-tegra”, saved, and exiting menuconfig. Then “make modules_prepare”. This sets the kernel source here to match your running system.

I then moved “/usr/src/linux-headers-4.4.15-tegra/” to a backup name, and created a symbolic link in “/usr/src/” named “linux-headers-4.4.15-tegra”, which points to “/usr/local/src/kernel/kernel-4.4”. Then I could build kvaser. I did not check if it was valid or not, but compile completed.

Hi Linuxdev,

The driver was succesfully compiled. Thanks!

Thanks Linuxdev, here is my solution for TX1, kernel 3.10.96:

def __arm__

or

define(__arm__)

with

(defined(__arm__) || defined(__aarch64__))

there are 5 or 6 spots…I’ll ask Kvaser to include this patch to their next canlib release.

  • now you should be able to “make” from linuxcan/

  • when tried to sudo make install, I had a soft link issue, so I had to delete lib/module/3.10.96/kernel and have lib/module/3.10.96/kernel pointing to usr/src/kernel instead

  • now you should be able to “sudo make install” from linuxcan/

  • you can get ~2GB of flash drive space back by deleting *.o files in usr/src/kernel

Hi linuxdev,

I downloaded the kernel 4.4.63 (I’m using 4.4.14) from https://www.kernel.org/. After I installed the driver I got the following when I checked the log so I guess the driver was not loaded. Might be a kernel version issue?

nvidia@tegra-ubuntu:/usr/src/GobiNet$ dmesg | grep Gobi
[ 25.799039] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 25.799041] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 25.799629] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 25.801316] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 26.851498] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 218.232772] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 218.236629] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 218.238252] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 218.244302] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’
[ 219.256384] GobiNet: version magic ‘4.4.63-tegra SMP preempt mod_unload aarch64’ should be ‘4.4.15-tegra SMP preempt mod_unload aarch64’

Thanks!

A module won’t insert correctly if either the base kernel software version is mismatched, or if config does not match. Never use mismatched versions.