Hi I am new to kernel driver developement. I am using the raspberry pi as my hostI am trying to create an I2C driver for a custom board we have. The custom board will act as the slave. I am confused about how do I go about entering the devices slave address. From what I understand
You need to either have a board setup file which I dont since its a custom board.
You can edit the device tree
Or you can do it in the user space application.
I am not sure where exactly to edit the device tree if I go with the second option. More over I would like to somehow register the slave address in the I2C driver itself. That way I donot need to rebuild the kernel. One method i was looking at was to set the i2c client from the driver code but that was advised by commentators I am not sure why. Any help would be appreciated.
Instantiating Drivers
So I have finally a working way in which I can bind the I2C device without needing a kernel rebuild. I create two driver files(.ko files). One for registering and one for the actual driver.
The way I did it is I got the bus number to which the device was connected.
(You can look into i2c user space code. i2cdetect -y (busnumber) will help you detect which bus number it is)
Once I knew that I created a driver file which would register my device by getting access to the adapter and then registering it. My bus number was 1 and slave address 0x10
static struct i2c_board_info board_info[] __initdata =
{
{
I2C_BOARD_INFO("my_device", 0x10),
},
};
And in the init function of the driver I register the device by
i2c_new_device(i2c_get_adapter(1), board_info[0])
Thats it. Now once you build this insmod the ko file before insmoding the actual driver file and everything should work.
Related
I am a newbie to linux kernel. While interfacing with the external device, I made the required changes in bsp file. The bsp file device name and platform_driver name should match in order to invoke probe(). I have heard that probe will check whether h/w exists and probe() will create device file (/dev/rtc1) for a new external device. I am not sure about the functionality of the probe(). Can someone explain me how device file is created in this context?Thank you in advance!
probe() is a callback function that gets called, irrespective of h/w presence, when the bus_match_driver() routine returns success. The probe function is called when a device is installed that the driver-core thinks it should handle; the probe function should perform checks on the information passed to it about the device and decide whether the driver is really appropriate for that device. A device file is created either manually by mknod or automatically by udev and is not directly related to probe function. The book https://lwn.net/Kernel/LDD3/ (highly recommended) has all the details regarding creating a device node.
I am writing a serial driver for UART in windows just for learning purpose. More specifically in WDM.
I will write both the bus driver and function driver.
Currently i am writing the bus driver. So my question is from where i can come to know in my driver that how many serial ports i have in my system, so that i can expose that number of PDO's from my bus driver?? And resources allocated to each port. Do i have to check some kind of registry or windows will provide some kind of structure.
Please help me!! Thanks in advance
Assuming your UARTs are part of the PC, there's already a bus driver which will enumerate them. ACPI.SYS gets information from the platform BIOS, which includes the number and resource assignments for built-in components like UARTs.
If you're writing your driver for an add-in multi-port serial board, then you would need to look at the documentation for the board to determine how you find the number of UARTs. It might be as simple as looking at the PCI Product ID and having a hard-coded count for the type of board you have.
When ACPI enumerates the device, your driver's AddDevice routine will be called to load on it, and you'll receive the assigned resources when handling the PNP START message.
I am studying windows device drivers on my own and I find it's very difficult to differentiate between PDO and FDO. Let me tell you the flow that I have in my head correct me if I am wrong !!
when system boots it loads the root bus driver that will create a FDO. Now it will enumerates its child devices and i guess some hot plug method of the bus driver will be called, when a new child will be found and that method will notify the PNP manager. PNP manager will call the AddDevice() routine of the root bus driver and that will intern create PDOs for new buses like one for PCI and etc. Please explain the whole flow in detail, this is just my imagination. And then it is documented that system will load the functional driver for the PCI bus that will create the FDO ??
what is this FDO?? and why would i need that?? According to me PCI bus driver should also follow the same as done by the root bus, enumerate its child and create PDOs for them, or by this FDO they mean PDO only ?? I am so much confused :( !!
What are you actually doing, or are you just trying to learn? I am just wondering how you ended up this low down in the stack.
PDO = Physical Device Object
FDO = Functional Device Object
A PDO acts as a physical device, but it does not necessarily have to be physical. It is essentially the interface between a device on a bus, and the bus itself. This is pretty well covered on MSDN.
Here is an example that uses USB sticks and this illustrates the difference quite well.
Here is a more in depth explanation and the important quote
If your point of reference is the PCI bus, then Pci.sys is the function driver. But if your point of reference is the Proseware Gizmo device, then Pci.sys is the bus driver. This dual role is typical in the PnP device tree. A driver that serves as function driver for a bus also serves as bus driver for a child device of the bus.
You also have filter drivers which allow you to sit between PDO's and FDO's and start doing naughty stuff like hiding files, POC rootkits etc. At this stage you can add extra functionality, or completely prevent access to the PDO.
And here is all the MSDN links.
http://msdn.microsoft.com/en-us/library/windows/hardware/hh439632(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff554721(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/hh439643(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff554731(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff564859(v=vs.85).aspx
http://technet.microsoft.com/en-us/library/cc776371(v=ws.10).aspx
If that doesn't clear it up for you, feel free to post back.
Here is the excerpt form "Programming the Microsoft Windows Driver Model", 2nd edition, Walter One:
- PDO stands for physical device object. The bus driver uses this
object to represent the connection between the device and the bus.
- FDO stands for function device object. The function driver uses
this object to manage the functionality of the device.
- FiDO stands
for filter device object. A filter driver uses this object as a place
to store the information it needs to keep about the hardware and its
filtering activities. (The early beta releases of the Windows 2000
DDK used the term FiDO, and I adopted it then. The DDK no longer
uses this term because, I guess, it was considered too frivolous.)
Hope this helps you out.
According to me PCI bus driver should also follow the same as done by the root bus, enumerate its child and create PDOs for them --WRONG!.
If you are talking about WDM, PnP Manager creates PDOs. Earlier to that, YOU had to create it(after detection of device) in DriverEntry().
If a USB device driver is loaded, and at some time the device plugs in, then which part of the kernel will create struct device and register it?
When the driver is loaded, the system calls the function, which you assigned in module_init. You will want to call there usb_register(struct usb_driver skel_driver), where skel_driver is a struct with pointers to methods servicing the device, like the probe method.
The probe method is the one which is called, when a new usb device is introduced in to the system. In this place you can fill your struct (usb_skel) with what you will need in the future, initiate a char device or whatever you do, when the device is introduced.
The system mostly won't create anything by itself, it has to have most of the structs prepared and filled with device specific data.
Please see usb-skeleton in lxr for reference and learn to use it, besides read writing usb drivers from LDD.
Cheers
I'm trying to learn about device drivers on Linux Kernel, for that I've created three modules with:
A bus type
A device driver
A fake device that does nothing now, only is registered
Everything works fine, I can load the bus, the driver and the module that creates the device. Everything appears on sysfs, including the link between the device and the device driver that indicates that they are binded.
And when the driver and device are loaded, I can see using udevadm monitor that also some events are provoked:
KERNEL[1275564332.144997] add /module/bustest_driver (module)
KERNEL[1275564332.145289] add /bus/bustest/drivers/bustest_example (drivers)
UDEV [1275564332.157428] add /module/bustest_driver (module)
UDEV [1275564332.157483] add /bus/bustest/drivers/bustest_example (drivers)
KERNEL[1275564337.656650] add /module/bustest_device (module)
KERNEL[1275564337.656817] add /devices/bustest_device (bustest)
UDEV [1275564337.658294] add /module/bustest_device (module)
UDEV [1275564337.664707] add /devices/bustest_device (bustest)
But after everything, the device doesn't appear on hal. What else need a device to be seen by hal?
Everything seems to be ok with the device, the problem is that Hal needs a handler for each subsystem (the list of handlers can be found in hald/linux/device.c), and obviously, hal doesn't support bustest, the subsystem invented for this case.
If the bus is registered with the name "pseudo" instead of "bustest", hal uses a set of handlers defined for fake devices to initialize the database entry, registers it and send a DeviceAdded event.