{"id":8203,"date":"2022-03-08T08:34:18","date_gmt":"2022-03-08T08:34:18","guid":{"rendered":"http:\/\/fastbitlab.com\/?p=8203"},"modified":"2023-08-12T14:34:04","modified_gmt":"2023-08-12T09:04:04","slug":"pcd-driver-with-multiple-devices","status":"publish","type":"post","link":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/","title":{"rendered":"Linux Device Driver Programming Lecture 48- Pcd driver with multiple devices"},"content":{"rendered":"<div class=\"boldgrid-section\" style=\"background-image: linear-gradient(to left, #eeeeee, #eeeeee);\" data-bg-color-1=\"#EEEEEE\" data-bg-color-2=\"#EEEEEE\" data-bg-direction=\"to left\">\n<div class=\"container\">\n<div class=\"row\" style=\"padding-top: 35px; padding-bottom: 0px; background-image: linear-gradient(to left, #eeeeee, #eeeeee);\" data-bg-color-1=\"#EEEEEE\" data-bg-color-2=\"#EEEEEE\" data-bg-direction=\"to left\">\n<div class=\"col-md-1 col-sm-12 col-xs-12 col-lg-1\">\n<p>&nbsp;<\/p>\n<\/div>\n<div class=\"col-md-10 col-sm-12 col-xs-12 col-lg-10\">\n<h1 class=\"\" style=\"text-align: center; font-size: 30px; border-width: 0px; line-height: 35px;\"><span style=\"color: #000080;\"><strong><b>Pcd driver with multiple devices<\/b><\/strong><\/span><\/h1>\n<div class=\"row bg-editor-hr-wrap\">\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\n<p>&nbsp;<\/p>\n<div class=\"bg-hr bg-hr-10\" style=\"border-style: solid; border-width: 0px 0px 3px;\"><\/div>\n<p>&nbsp;<\/p>\n<\/div>\n<\/div>\n<p class=\"\" style=\"border-width: 0px; line-height: 34px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In the previous article, we actually wrote a pseudo character driver to handle a single device. In this article, let&#8217;s do one more exercise in which we are going to write a pseudo character driver with multiple devices.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: Merriweather; font-weight: 400;\" data-font-family=\"Merriweather\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">This is an exercise as in Figure 1.<\/span><\/p>\n<figure id=\"attachment_8206\" aria-describedby=\"caption-attachment-8206\" style=\"width: 507px\" class=\"wp-caption aligncenter\"><img fetchpriority=\"high\" decoding=\"async\" class=\"size-full wp-image-8206\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-1-16.png\" alt=\"Figure 1. Exercise 1\" width=\"507\" height=\"106\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-16.png 507w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-16-300x63.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-16-120x25.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-16-500x105.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-16-200x42.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-16-400x84.png 400w\" sizes=\"(max-width: 507px) 100vw, 507px\" \/><figcaption id=\"caption-attachment-8206\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 1. Exercise 1<\/span><\/figcaption><\/figure>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">You have to modify the previous pseudo character device driver to support four pseudo character devices. So, you have to implement open, release, read, write, lseek driver methods, same as before, to handle user request. The pseudo character device, in our case, as you know, it is just a static memory area. You can use arrays here as well.<\/span><\/p>\n<figure id=\"attachment_8207\" aria-describedby=\"caption-attachment-8207\" style=\"width: 652px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"size-full wp-image-8207\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-2-12.png\" alt=\"Figure 2. Detail of exercise\" width=\"652\" height=\"372\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png 652w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12-300x171.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12-600x342.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12-120x68.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12-500x285.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12-200x114.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12-400x228.png 400w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><figcaption id=\"caption-attachment-8207\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 2. Detail of exercise<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">That means there will be one single driver or kernel module, I call&nbsp; it as pcdrv pseudo character driver. And that driver is going to take care of four devices. Let&#8217;s call it as&nbsp; Pcdev-1, Pcdev-2, Pcdev-3, and Pcdev-4. So, the driver, which we are about to write, should manage 4 devices&nbsp; or it could be more. You can consider it as manage N devices.&nbsp;<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">There will be a single driver managing all N devices, remember that.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\"> You are not going to write 4 different kernel modules, there will be only one driver or one kernel module, which is going to manage N devices. There will be only one implementation of open, read, write, release, and lseek driver methods. That also means, the drivers should first determine which device is being accessed from the user&#8217;s space to fulfill the request. That logic you have to build. So, we will see that while we code for this exercise.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px; line-height: 40px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">These are the device filename we are going to use for 4 different pseudo character devices, as shown in Figure 3.<\/span><\/p>\n<figure id=\"attachment_8208\" aria-describedby=\"caption-attachment-8208\" style=\"width: 679px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"size-full wp-image-8208\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-3-12.png\" alt=\"Figure 3. Creating all these device\" width=\"679\" height=\"385\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12.png 679w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12-300x170.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12-600x340.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12-120x68.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12-500x284.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12-200x113.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-12-400x227.png 400w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><figcaption id=\"caption-attachment-8208\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 3. Creating all these device<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; line-height: 30px; font-size: 17px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">So, in the \/dev directory, you have to create all these device files, as shown in Figure 3.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Before implementing the driver, now let&#8217;s discuss some of the design aspect of the device driver. How we are going to manage the information? Remember that every device has its own private data, as shown in Figure 4.<\/span><\/p>\n<figure id=\"attachment_8212\" aria-describedby=\"caption-attachment-8212\" style=\"width: 504px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8212 size-full\" src=\"https:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-4-11.png\" alt=\"Pcd driver with multiple devices, pseudo character driver\" width=\"504\" height=\"205\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-11.png 504w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-11-300x122.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-11-120x49.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-11-500x203.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-11-200x81.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-11-400x163.png 400w\" sizes=\"(max-width: 504px) 100vw, 504px\" \/><figcaption id=\"caption-attachment-8212\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 4. Private data of a device(Device-specific information)<\/span><\/figcaption><\/figure>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In our case, a device is nothing but a memory area. We call it as a pseudo-device.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">What are the attributes or device-specific information of our device? <\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">The first thing could be a serial number.&nbsp;<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Every device may have its own serial number. A serial number could be a collection of characters or a string data. Since, our device is a memory area, so the starting address of the memory area is very important. That could be another device-specific information.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">What is the size of that memory area, and the permission of that memory area also become device-specific information. That means, in our case, there are 4 device-specific information. The permission could be read-only, write-only, and read-write.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">This is how your driver is going to manage a four different devices.<\/span><\/p>\n<figure id=\"attachment_8213\" aria-describedby=\"caption-attachment-8213\" style=\"width: 781px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8213 size-full\" src=\"https:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-5-10.png\" alt=\"Pcd driver with multiple devices, pseudo character driver\" width=\"781\" height=\"363\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10.png 781w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-300x139.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-768x357.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-600x279.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-120x56.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-500x232.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-200x93.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-10-400x186.png 400w\" sizes=\"(max-width: 781px) 100vw, 781px\" \/><figcaption id=\"caption-attachment-8213\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 5. Driver\u2019s device management for 4 different devices<\/span><\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In this exercise, every device represents a unique memory area. You can create a the memory area either statically or by using dynamic memory allocation. But, let&#8217;s stick to static allocation that is array-based, because we have not yet discussed the dynamic memory allocation in the kernel space.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s push that discussion to a later point in the article. So, we will discuss how to use dynamic memory allocation API later. For this exercise, let&#8217;s just tick to array-based memory.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">The user space will see your device files Pcdev_1, Pcdev-2, Pcdev-3, and&nbsp; four. And the driver is going to manage 4 memory areas. The Pcdev-1 will be read-only in our case, and Pcdev-2&nbsp; will be write-only. Pcdev-3 and Pcdev-4 will be read-write memory. This is the configuration we are going to use for this exercise.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s say there is a userspace application echo, which tries to write some data to pcdev-1. In that case, the driver should detect that, and it should return the error code EPERM. That means the operation is not permitted. Because this is read-only.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In the same way, if an application tries to read from this \/dev\/pcdev-2 device, then only the driver should detect that, and it should return the appropriate error code. And for these two devices, the userspace application can read and write.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s say there is a userspace application echo tries to write some data to the pcdev-3, then the driver should appropriately it should copy that data to the write device. Drivers should not put that data in the memory areas of other devices.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\"><span style=\"font-weight: 400;\">That means the driver should detect to which device the request is coming in. That means the driver should detect, or it should understand which device is being accessed from the user space, and it should process that request appropriately.&nbsp;<\/span><span style=\"font-weight: 400;\">So, the driver should not corrupt the memory areas of other devices.<\/span><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Before implementing this exercise, let me also discuss about the data structure we are going to use for this exercise.<\/span><\/p>\n<figure id=\"attachment_8214\" aria-describedby=\"caption-attachment-8214\" style=\"width: 599px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8214 size-full\" src=\"https:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-6-10.png\" alt=\"Pcd driver with multiple devices, pseudo character driver\" width=\"599\" height=\"151\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-10.png 599w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-10-300x76.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-10-120x30.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-10-500x126.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-10-200x50.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-10-400x101.png 400w\" sizes=\"(max-width: 599px) 100vw, 599px\" \/><figcaption id=\"caption-attachment-8214\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 6. Device driver data structure<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">What will do for this driver is. In the driver, we will maintain 2 structures.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">What are those structures?<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\"> The first structure is going to hold driver&#8217;s private data, and another structure is going to hold a device&#8217;s private data.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Let&#8217;s understand a structure to represent private device data. As I explained in the previous Figure 4, every device has its own private data.<\/span><\/p>\n<figure id=\"attachment_8215\" aria-describedby=\"caption-attachment-8215\" style=\"width: 1933px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-8215 size-full\" src=\"https:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-7-8.png\" alt=\"Pcd driver with multiple devices, pseudo character driver\" width=\"1933\" height=\"577\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8.png 1933w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-300x90.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-768x229.png 768w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-1024x306.png 1024w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-600x179.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-120x36.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-500x149.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-200x60.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-400x119.png 400w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-800x239.png 800w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-8-1200x358.png 1200w\" sizes=\"(max-width: 1933px) 100vw, 1933px\" \/><figcaption id=\"caption-attachment-8215\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 7. Structure to represent device\u2019s private data<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In our case, the pcdev device has couple of private data such as start&nbsp; address, size, permission, serial number. We will put all these data in a structure format. That&#8217;s why I&#8217;m going to include, or I&#8217;m going to create, this structure. <\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Struct pcdev_private_data, which has a couple of member elements to capture the device&#8217;s private data.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px; font-family: 'Roboto Slab'; font-weight: 400; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">The first member element will be a pointer to capture the start address, the next one is to capture the size, and this is a pointer to capture the serial number, which is nothing but a string of information, and this is to capture the permission.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\"><span style=\"font-weight: 400;\">This structure also embeds our cdev structure, that is, character device structure. Because, in this case, we are going to handle multiple character devices.&nbsp;<\/span><span style=\"font-weight: 400;\">Every device has to get registered with a virtual file system of the kernel.<\/span><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Since we are using, let&#8217;s say, four devices, then we should be creating four cdev structure. So, that also means that the cdev structure is device-specific. That&#8217;s why it makes sense to keep that device-specific information in the device private data structure. That&#8217;s a reason why I embed the cdev variable in the device&#8217;s private data structure. I hope that makes sense. So, any private data if you think it is specific to device, then you are free to keep that in this structure.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">We will later see when we use synchronization related a kernel object such as pin logs and other things. That also, if it is a device-specific, then it goes into this structure.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">Now let&#8217;s explore the structure to represent the driver&#8217;s private data, as shown below.<\/span><\/p>\n<pre class=\"color-neutral-text-contrast color-neutral-background-color\" style=\"font-size: 12px; box-shadow: #cecece 0px 0px 0px 0px inset;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\"><span style=\"color: #008000;\">\/*This structure represents driver private data *\/<\/span>\r\n<span style=\"color: #800080;\">struct<\/span> <span style=\"color: #008080;\">pcdrv_private_data<\/span>\r\n{\r\n    <span style=\"color: #993366;\"> int<\/span> <span style=\"color: #3366ff;\">total_devices<\/span>;\r\n    <span style=\"color: #993366;\"> struct<\/span> <span style=\"color: #008080;\">pcdev_private_data<\/span><span style=\"color: #3366ff;\"> pcdev_data<\/span><span style=\"color: #000000;\">[NO_OF_DEVICES];<\/span>\r\n};<\/pre>\n<p class=\"\" style=\"text-align: center;\"><span style=\"color: #000000;\">Structure to represent driver\u2019s private data<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">In our case, the driver is the one who is going to handle four or N&nbsp; number of devices. Character devices. That&#8217;s why I include only two member elements in the driver&#8217;s private data structure.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">The first one will be total devices. Because since the driver is handling&nbsp; N number of devices, so this is it is just to track how many devices being handled in the driver. That&#8217;s a reason why I use a int total_devices variable. That becomes a driver&#8217;s info. The total devices will never become device information.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000000;\"><span style=\"font-weight: 400;\">It is not a device-specific, it should be a driver-specific. Now, the next member element is nothing but device private data instances. So, this driver is handling N number of devices. That means, each device should have its own pcdev_private&nbsp;<\/span><span style=\"font-weight: 400;\">data struct variable.<\/span><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">That&#8217;s the reason I just created an array of private device data. Here,&nbsp; number of devices macro represents a number of devices. The reason for embedding pcdev_ private_data instances. Inside the driver, structure is because driver is the one who is going to operate on the device-specific data.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">For example,&nbsp; driver is the one who is going to alter the memory address of a device to read or write data. That&#8217;s a reason why we can create this array of struct pcdev_private_data inside this driver structure.<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"font-weight: 400; color: #000000;\">I hope you understood about the structures a what we are going to use for this exercise. From the<span style=\"color: #ff6600;\"><a style=\"color: #ff6600;\" href=\"http:\/\/fastbitlab.com\/pcd-driver-with-multiple-devices-code-implementation-part-1\/\" target=\"_blank\" rel=\"noopener\"> next article<\/a> <\/span>onwards, let&#8217;s start coding for this exercise.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 17px; line-height: 28px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #000080;\"><b>FastBit Embedded Brain Academy Courses<\/b><\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 17px;\"><span style=\"color: #000000;\">C<span style=\"font-weight: 400;\">lick here:&nbsp;<\/span><\/span><span style=\"color: #0000ff;\"><a style=\"color: #0000ff; text-decoration: underline;\" href=\"http:\/\/fastbitlab.com\/course1\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">https:\/\/fastbitlab.com\/course1<\/span><\/a><\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Pcd driver with multiple devices &nbsp; &nbsp; In the previous article, we actually wrote a pseudo character driver to handle a single device. In this article, let&#8217;s do one more exercise in which we are going to write a pseudo character driver with multiple devices. This is an exercise as in Figure 1. &nbsp; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":8207,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"0","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"off","ocean_gallery_id":[],"footnotes":""},"categories":[8],"tags":[18],"class_list":["post-8203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-linux-device-driver-programming","entry","has-media"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Pcd driver with multiple devices | Linux Device Driver Programming<\/title>\n<meta name=\"description\" content=\"Pcd driver with multiple devices. In the previous article, we actually wrote a pseudo character driver to handle a single device.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Pcd driver with multiple devices | Linux Device Driver Programming\" \/>\n<meta property=\"og:description\" content=\"Pcd driver with multiple devices. In the previous article, we actually wrote a pseudo character driver to handle a single device.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/\" \/>\n<meta property=\"og:site_name\" content=\"FastBit EBA\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/fastbiteba\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-08T08:34:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-12T09:04:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png\" \/>\n\t<meta property=\"og:image:width\" content=\"652\" \/>\n\t<meta property=\"og:image:height\" content=\"372\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"FastBitLab\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@fastbiteba\" \/>\n<meta name=\"twitter:site\" content=\"@fastbiteba\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"FastBitLab\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/\"},\"author\":{\"name\":\"FastBitLab\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/person\\\/e32b38e733a0d76ffa7e6bc998652e5d\"},\"headline\":\"Linux Device Driver Programming Lecture 48- Pcd driver with multiple devices\",\"datePublished\":\"2022-03-08T08:34:18+00:00\",\"dateModified\":\"2023-08-12T09:04:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/\"},\"wordCount\":1568,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-2-12.png\",\"keywords\":[\"Linux Device Driver Programming Tutorial\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/\",\"name\":\"Pcd driver with multiple devices | Linux Device Driver Programming\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-2-12.png\",\"datePublished\":\"2022-03-08T08:34:18+00:00\",\"dateModified\":\"2023-08-12T09:04:04+00:00\",\"description\":\"Pcd driver with multiple devices. In the previous article, we actually wrote a pseudo character driver to handle a single device.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#primaryimage\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-2-12.png\",\"contentUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-2-12.png\",\"width\":652,\"height\":372,\"caption\":\"Figure 2. Detail of exercise\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/pcd-driver-with-multiple-devices\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Linux Device Driver Programming Lecture 48- Pcd driver with multiple devices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\",\"name\":\"FastBit EBA\",\"description\":\"Your Online Academy of Embedded Systems\",\"publisher\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\",\"name\":\"FastBit EBA\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/logo-EzNrEnyr.png\",\"contentUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/04\\\/logo-EzNrEnyr.png\",\"width\":640,\"height\":640,\"caption\":\"FastBit EBA\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/fastbiteba\\\/\",\"https:\\\/\\\/x.com\\\/fastbiteba\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/fastbit-embedded-brain-academy-b3167b124\\\/\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCa1REBV9hyrzGp2mjJCagBg\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/person\\\/e32b38e733a0d76ffa7e6bc998652e5d\",\"name\":\"FastBitLab\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g\",\"caption\":\"FastBitLab\"},\"description\":\"The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Pcd driver with multiple devices | Linux Device Driver Programming","description":"Pcd driver with multiple devices. In the previous article, we actually wrote a pseudo character driver to handle a single device.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/","og_locale":"en_US","og_type":"article","og_title":"Pcd driver with multiple devices | Linux Device Driver Programming","og_description":"Pcd driver with multiple devices. In the previous article, we actually wrote a pseudo character driver to handle a single device.","og_url":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/","og_site_name":"FastBit EBA","article_publisher":"https:\/\/www.facebook.com\/fastbiteba\/","article_published_time":"2022-03-08T08:34:18+00:00","article_modified_time":"2023-08-12T09:04:04+00:00","og_image":[{"width":652,"height":372,"url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png","type":"image\/png"}],"author":"FastBitLab","twitter_card":"summary_large_image","twitter_creator":"@fastbiteba","twitter_site":"@fastbiteba","twitter_misc":{"Written by":"FastBitLab","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#article","isPartOf":{"@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/"},"author":{"name":"FastBitLab","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/person\/e32b38e733a0d76ffa7e6bc998652e5d"},"headline":"Linux Device Driver Programming Lecture 48- Pcd driver with multiple devices","datePublished":"2022-03-08T08:34:18+00:00","dateModified":"2023-08-12T09:04:04+00:00","mainEntityOfPage":{"@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/"},"wordCount":1568,"commentCount":0,"publisher":{"@id":"https:\/\/fastbitlab.com\/blog\/#organization"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#primaryimage"},"thumbnailUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png","keywords":["Linux Device Driver Programming Tutorial"],"articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/","url":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/","name":"Pcd driver with multiple devices | Linux Device Driver Programming","isPartOf":{"@id":"https:\/\/fastbitlab.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#primaryimage"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#primaryimage"},"thumbnailUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png","datePublished":"2022-03-08T08:34:18+00:00","dateModified":"2023-08-12T09:04:04+00:00","description":"Pcd driver with multiple devices. In the previous article, we actually wrote a pseudo character driver to handle a single device.","breadcrumb":{"@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#primaryimage","url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png","contentUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-12.png","width":652,"height":372,"caption":"Figure 2. Detail of exercise"},{"@type":"BreadcrumbList","@id":"https:\/\/fastbitlab.com\/blog\/pcd-driver-with-multiple-devices\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fastbitlab.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Linux Device Driver Programming Lecture 48- Pcd driver with multiple devices"}]},{"@type":"WebSite","@id":"https:\/\/fastbitlab.com\/blog\/#website","url":"https:\/\/fastbitlab.com\/blog\/","name":"FastBit EBA","description":"Your Online Academy of Embedded Systems","publisher":{"@id":"https:\/\/fastbitlab.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fastbitlab.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fastbitlab.com\/blog\/#organization","name":"FastBit EBA","url":"https:\/\/fastbitlab.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2026\/04\/logo-EzNrEnyr.png","contentUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2026\/04\/logo-EzNrEnyr.png","width":640,"height":640,"caption":"FastBit EBA"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/fastbiteba\/","https:\/\/x.com\/fastbiteba","https:\/\/www.linkedin.com\/in\/fastbit-embedded-brain-academy-b3167b124\/","https:\/\/www.youtube.com\/channel\/UCa1REBV9hyrzGp2mjJCagBg"]},{"@type":"Person","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/person\/e32b38e733a0d76ffa7e6bc998652e5d","name":"FastBitLab","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9230d0f9bdef28b63a01e7ca274ee7b2e8ed9abe932ee564af8809caaf52a0c8?s=96&d=mm&r=g","caption":"FastBitLab"},"description":"The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries."}]}},"_links":{"self":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/8203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/comments?post=8203"}],"version-history":[{"count":5,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/8203\/revisions"}],"predecessor-version":[{"id":15435,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/8203\/revisions\/15435"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/media\/8207"}],"wp:attachment":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/media?parent=8203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/categories?post=8203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/tags?post=8203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}