2. pdiso16 kernel module
2.1 Loading (init_module)
Mechanism
Linux kernel modules are specially made to be pieces of kernel that can be loaded and unloaded dynamically, while the kernel is running. These appear as object files (modname.o) and are loaded with the command insmod modname.o [arguments]. This operation runs the initialization of the device(s) and gives a major number to the device driver. This one can be found in the /proc/devices file. The command can receive many arguments specific to the module.
After being loaded, the device driver module must be associated with devices files which will be used by user programs. This is made with the command : mknod devname c major minor. This action can be avoided, if this file is already created with its proper major and minor numbers.
Parameters
An optional parameters can be specified when you load the pdiso16 device driver with the insmod command. The loading command will looks like (run being root):
insmod pdiso16.o [PDISO16_base_adr=adr | PDISO16_major=major]
- PDISO16_base_adr:
As The cio-pdiso16 board can be installed at several address location, the base address switch sets the starting I/O location where the CPU can access the registers of the board. The factory default is 300 hex (768 decimal). If you already have a board installed at address 300 hex, choose a new address from those available on your computer and set the switches. User can specify board address by adding PDISO16_base_adr=adr at the end of the loading command. It must be presented in a hex format (e.g. : PDISO16_base_adr=0x300. In case of no PDISO16_base_adr parameter, a board with the default address IO_BOARD_ADR (specified in the pdiso16.h header file) will try to be loaded. To see which I/O space is already use by devices you can look at the /proc/ioports file.
- PDISO16_major:
The major number for the pdiso16 device driver can be set to another value. In case of no PDISO16_major parameter, PDISO16_MAJOR is taken from the pdiso16.h header file.
Initialization
The device driver has to register itself with Linux and RTLinux. The loading process begins with a call to pdiso16_init() function dedicated to general purpose initialization (Linux I/O region checking, register device...). Then, it has to deal with RTLinux stuff: register using posixio API, set up fifo's and initialize its base address and communication state (PORT1 byte-wise behavior)
Errors
Error can appear during the module loading. This error may be caused by invalid loading parameters or by the fact that module is already running on system.
In case of error, you should check if the module is not already running and if all the required resources are free (see the Special files section). You can also use the dmesg command to see debug or error messages (see the Debug options section).
2.2 Unloading (cleanup_module)
Mechanism
As you can dynamically load your kernel module, you can also unload it when you want using the command rmmod modname. You can check its name calling the useful lsmod command.
Errors
Nevertheless, the module will be unloaded only if all the processes/threads have been closed before. This is done with the driver's release() function call which is called by the generic close() function. Finally, the call may look like close(FD). If some processes/threads are still using the device driver when you try to unload it, the kernel will display a 'busy device or resource' message on console.