{"id":7984,"date":"2022-03-01T08:15:08","date_gmt":"2022-03-01T08:15:08","guid":{"rendered":"http:\/\/fastbitlab.com\/?p=7984"},"modified":"2023-09-14T16:32:15","modified_gmt":"2023-09-14T11:02:15","slug":"linux-device-driver-programming-lecture-39-understanding-read-method","status":"publish","type":"post","link":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/","title":{"rendered":"Linux Device Driver Programming Lecture 39- Understanding read method"},"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: 50px;\"><span style=\"font-weight: 400; color: #000080;\"><b>Understanding read method<\/b><\/span><\/h1>\n<div class=\"row bg-editor-hr-wrap\" style=\"border-width: 0px; margin-top: -25px;\">\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\n<div>\n<p>&nbsp;<\/p>\n<div class=\"bg-hr bg-hr-10 color2-color\" style=\"border-style: solid; border-width: 0px 0px 3px;\"><\/div>\n<p>&nbsp;<\/p>\n<\/div>\n<\/div>\n<\/div>\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;\">In this article, let&#8217;s understand our driver&#8217;s read method implementation.<\/span><\/p>\n<figure id=\"attachment_7987\" aria-describedby=\"caption-attachment-7987\" style=\"width: 668px\" class=\"wp-caption aligncenter\"><img fetchpriority=\"high\" decoding=\"async\" class=\" wp-image-7987\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-1-1.png\" alt=\"Figure 1. Read method implementation\" width=\"668\" height=\"339\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.png 701w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-300x152.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-600x305.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-120x61.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-500x254.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-700x356.png 700w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-200x102.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1-400x203.png 400w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><figcaption id=\"caption-attachment-7987\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 1. Read method implementation<\/span><\/figcaption><\/figure>\n<p data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\">&nbsp;<\/p>\n<p style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 20px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\"><span style=\"color: #ff0000;\"><strong>What is read? <\/strong><\/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-level process executes a read system call to read from a file. In our case, the file is not a regular file but a device file, which handles our pseudo character 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;\">In our project, the pseudo character device is nothing but a memory array. A contiguous memory location an array. So, I will call it as a device memory buffer. Whenever a user program issues read system call on our device file, we should transfer data from our device memory buffer to the user buffer. So, the data copy happens from kernel side to user side. That is read.&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;\">The write is in reverse direction, write means user program wants to write some data into the device memory buffer of our device.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Purpose of the Read Method:<\/strong><\/span><\/p>\n<ul class=\"\" style=\"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=\"\">\n<li><span style=\"color: #000000;\">The read method is used to read data from a file or device.<\/span><\/li>\n<li><span style=\"color: #000000;\">In the context of a character device driver, it is responsible for reading data from a pseudo-character device, which could represent various devices like sensors, input devices, or other peripherals.<\/span><\/li>\n<\/ul>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Parameters of the Read Method:<\/strong><\/span><\/p>\n<ul class=\"\" style=\"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=\"\">\n<li><span style=\"color: #000000;\">The read method typically takes the following parameters:<\/span>\n<ul>\n<li><span style=\"color: #000000;\">File Descriptor: A reference to the file or device being read.<\/span><\/li>\n<li><span style=\"color: #000000;\">Buffer: A pointer to a memory buffer in which the read data will be stored.<\/span><\/li>\n<li><span style=\"color: #000000;\">Count: The number of bytes requested to be read<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #ff0000;\"><strong>How the Read Method Works?<\/strong><\/span><\/p>\n<p class=\"\" style=\"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=\"\">When a user program (or any process) invokes the read system call on a file descriptor associated with a character device, the read method in the corresponding device driver is triggered.<\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Steps to Implement the Read Method<\/strong><\/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;\">Let&#8217;s understand how to implement the read method, what are the steps we are going to take in our driver. <\/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=\"color: #000000;\"><span style=\"font-weight: 400;\">These are the steps below you should be taking to implement read method, as shown in Figure 2.<\/span><\/span><\/p>\n<figure id=\"attachment_7988\" aria-describedby=\"caption-attachment-7988\" style=\"width: 707px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"size-full wp-image-7988\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-2-1.png\" alt=\"Figure 2. Steps to implement the read method\" width=\"707\" height=\"349\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1.png 707w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1-300x148.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1-600x296.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1-120x59.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1-500x247.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1-200x99.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-2-1-400x197.png 400w\" sizes=\"(max-width: 707px) 100vw, 707px\" \/><figcaption id=\"caption-attachment-7988\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 2. Steps to implement the read method<\/span><\/figcaption><\/figure>\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;\">First, you have to check the user requested count value, because the user cannot request some random amount of data. Because, so our device memory buffer is limited. It is only 512 bytes. That means, the user cannot request more than 512&nbsp;&nbsp;<\/span><span style=\"font-weight: 400;\">bytes.&nbsp;<\/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 why in your driver&#8217;s read method, you should check the user requested a count value against the max size, that is DEV_MEM_SIZE. This macro we have in our driver&#8217;s source code, which points to 512 bytes.<\/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;\">You have to check this count value against the DEV_MEM_SIZE of the device.&nbsp;<\/span><span style=\"font-weight: 400;\">If the current file position that is tracked by this field f_pos,&nbsp; that&#8217;s a current file&nbsp;<\/span><span style=\"font-weight: 400;\">position. If the current file position + count if it is greater than DEV_MEM_SIZE, then you have to adjust the &#8216;count&#8217;. This &#8216;count&#8217; needs to be adjusted.<\/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;\">This is how we adjust. count = DEV_MEM_SIZE &#8211;&nbsp; the current file position.<\/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;\">For example, let&#8217;s say &#8216;count&#8217; requested is a 513 bytes. The initial value of the&nbsp;<\/span><span style=\"font-weight: 400;\">file position when the device is initially opened is 0 actually.<\/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 why you have to check like this. Current file position let&#8217;s assume 0,&nbsp; 0+count. Count is, let&#8217;s say 513. Whether it is greater than 512 or not? (0+513 &gt; 512) Yes. In this case, it is greater than 512. That&#8217;s why you have to adjust count. Count = max_size 512 minus the current file position. Let&#8217;s say, if&nbsp; it is 0, then you actually truncate the count value to&nbsp; 512 bytes, like 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;\">I hope you get the idea why this check is required. Because user cannot ask a random amount of data. It should be a within a 512 bytes. The &#8216;count&#8217; value should be less than 512 bytes.<\/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;\">After that, once you adjust the correct value of count, you can copy &#8216;count&#8217; number of bytes from device memory to user buffer. So, user buffer pointer you can get from this(char __user *buff) field. After that, you have to update the current file position, that is f_pos. And return the number of bytes successfully read, or you can also return error code if there is any error during copying of data from device memory to the user buffer.<\/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;\">If the file position at the end of file(EOF), then there is nothing to read. In that case, you can return 0.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Understanding Current File Position<\/strong><\/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\u2019s explain the concept of current file position, which is denoted by f_pos.<\/span><\/p>\n<figure id=\"attachment_7989\" aria-describedby=\"caption-attachment-7989\" style=\"width: 718px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"size-full wp-image-7989\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-3-1.png\" alt=\"Figure 3. Pseudo character device memory access and file structure\" width=\"718\" height=\"507\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1.png 718w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1-300x212.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1-600x424.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1-120x85.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1-500x353.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1-200x141.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-3-1-400x282.png 400w\" sizes=\"(max-width: 718px) 100vw, 718px\" \/><figcaption id=\"caption-attachment-7989\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 3. Pseudo character device memory access and file 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;\">First of all, f_pos is a member element of the struct file. Remember this structure. This structure gets created whenever you open a file. For every open, one file object will be created. f_pos is nothing but one of the member element of this struct file. So, the pointer to this field is actually passed loff_t *f_pos by the VFS, whenever VFS calls the read or write method of the driver.<\/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 pointer what you&#8217;re seeing *f_pos, this is nothing but a pointer to file objects f_pos member element.&nbsp;<\/span><\/p>\n<p class=\"\" style=\"border-width: 0px; font-family: 'Roboto Slab'; font-weight: 400; font-size: 18px; line-height: 30px;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"color: #ff0000;\"><strong>What is the use of this current file position variable? <\/strong><\/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;\">This actually tracks the file access. Since we are dealing with a device file, we can use this current file position to track our pseudo character device memory access. When you open a device file, this file object will be created, and VFS sets loff_t f_pos field to 0.&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;\">Initially, this field will be 0 whenever a file is opened. That&#8217;s why in our driver, we can use this a current file position variable to track our pseudo character device memory area.<\/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 say there is a read of 6 bytes. Let&#8217;s say user wants to read 6 bytes from our pseudo character device(shown in Figure 4).<\/span><\/p>\n<figure id=\"attachment_7990\" aria-describedby=\"caption-attachment-7990\" style=\"width: 699px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-7990\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-4-1.png\" alt=\"Figure 4. Pseudo character device memory access\" width=\"699\" height=\"238\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1.png 699w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1-300x102.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1-600x204.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1-120x41.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1-500x170.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1-200x68.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-4-1-400x136.png 400w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><figcaption id=\"caption-attachment-7990\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 4. Pseudo character device memory access<\/span><\/figcaption><\/figure>\n<p class=\"\">&nbsp;<\/p>\n<figure id=\"attachment_7991\" aria-describedby=\"caption-attachment-7991\" style=\"width: 707px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-7991\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-5-1.png\" alt=\"Figure 5. Initial file position\" width=\"707\" height=\"270\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1.png 707w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1-300x115.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1-600x229.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1-120x46.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1-500x191.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1-200x76.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-5-1-400x153.png 400w\" sizes=\"(max-width: 707px) 100vw, 707px\" \/><figcaption id=\"caption-attachment-7991\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 5. Initial file position<\/span><\/figcaption><\/figure>\n<p class=\"\" 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;\">So, this was the initial position of a f_pos variable, and after that, it will be incremented by 6. So, now this will be the current position in the file for file access.&nbsp; The next read or write will takes place from this location onwards, as shown in Figure 5.<\/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 say there is a request for 2 bytes write Figure 6.<\/span><\/p>\n<figure id=\"attachment_7992\" aria-describedby=\"caption-attachment-7992\" style=\"width: 699px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-7992\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-6-1.png\" alt=\"Figure 6. After write of 2 bytes\" width=\"699\" height=\"274\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1.png 699w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1-300x118.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1-600x235.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1-120x47.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1-500x196.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1-200x78.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-6-1-400x157.png 400w\" sizes=\"(max-width: 699px) 100vw, 699px\" \/><figcaption id=\"caption-attachment-7992\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 6. After write of 2 bytes<\/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;\">The user program wants to write 2 bytes. This was the previous file location. So, the first write happens here, the second write happens here, and now the file position will point to the next free location. This is a current file position from which the next read or write can happen, as shown in Figure 6.&nbsp; <\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<figure id=\"attachment_7993\" aria-describedby=\"caption-attachment-7993\" style=\"width: 511px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-7993\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-7-1.png\" alt=\"Figure 7. After lseek of -2 from current position\" width=\"511\" height=\"221\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-1.png 511w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-1-300x130.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-1-120x52.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-1-500x216.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-1-200x86.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-7-1-400x173.png 400w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><figcaption id=\"caption-attachment-7993\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 7. After lseek of -2 from current position<\/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;\">Let&#8217;s say there is a&nbsp; request for lseek of -2&nbsp; from the current file position. This was the previous file position, that is this one. And from there -2. -1 and&nbsp; -1,&nbsp; so -2.&nbsp; That&#8217;s&nbsp; lseek. The lseek changes the position of the&nbsp; f_pos variable. It moves the file position pointer forward or backward. I hope you get the idea of&nbsp; lseek.<\/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;\">Now, let&#8217;s discuss the end of file(EOF) scenarios. In our case, what is the end of file scenario? We have got&nbsp; 512 bytes of device memory, that is from here to here. <\/span><span style=\"font-weight: 400;\">This was the last byte of our device memory. If the file position is pointing beyond that, then that&#8217;s a EOF scenario. It is pointing to the next memory location, which is free, but that is not a valid memory because our device memory is of only 512 bytes.<\/span><\/span><\/p>\n<figure id=\"attachment_7994\" aria-describedby=\"caption-attachment-7994\" style=\"width: 657px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7994 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-8-1.png\" alt=\"Understanding read method\" width=\"657\" height=\"214\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1.png 657w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1-300x98.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1-600x195.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1-120x39.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1-500x163.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1-200x65.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-8-1-400x130.png 400w\" sizes=\"(max-width: 657px) 100vw, 657px\" \/><figcaption id=\"caption-attachment-7994\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 8. EOF Scenario<\/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=\"color: #000000;\"><span style=\"font-weight: 400;\">Let&#8217;s say the current file position is f_pos, and there is a request for 2 bytes read.&nbsp;<\/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=\"color: #000000;\"><span style=\"font-weight: 400;\">What happens? <\/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=\"color: #000000;\"><span style=\"font-weight: 400;\">Current file position is 512 + the requester is 2, it is greater&nbsp;<\/span><span style=\"font-weight: 400;\">than 512(512+2 &gt; 512) that maximum device size. 514 is. This is 514 greater than&nbsp; 512. In that case, what you should do is, you should truncate the count.<\/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;\">Count = the maximum size is 512 &#8211; the current file position, that is 512. Count will be 0.&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;\">In this case, you can&#8217;t read anything. That&#8217;s why count is 0 in this case. You should return 0. When you return 0 to the user program, the user program understands that there is nothing to read. That&#8217;s why this is how you should manage your device access.<\/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 end of scenario is when the current file position is pointing one byte beyond the maximum size. That&#8217;s&nbsp; a end of file(EOF) scenario.&nbsp;<\/span><span style=\"font-weight: 400; color: #000000;\">I hope you get the idea of a write, after that, we should discuss about copying data from kernel space to the userspace.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<figure id=\"attachment_7995\" aria-describedby=\"caption-attachment-7995\" style=\"width: 645px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7995 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-9-1.png\" alt=\"Understanding read method\" width=\"645\" height=\"380\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1.png 645w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1-300x177.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1-600x353.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1-120x71.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1-500x295.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1-200x118.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-9-1-400x236.png 400w\" sizes=\"(max-width: 645px) 100vw, 645px\" \/><figcaption id=\"caption-attachment-7995\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 9. Kernel space to user space<\/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;\">Userspace pointers you cannot trust just like that. Because sometimes the user address space may not be valid, sometimes the virtual memory space of the user process may not be valid because the virtual memory manager can swap out those memory locations, and the user-level memory pointers can&#8217;t be directly dereferenced by the kernel-level code. For that purpose, you should use the kernel data copying utility, such as copy_to_user and copy_from_user.<\/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 case of&nbsp; read, you should use the copy_to_user&nbsp; function, which is given by the kernel.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 20px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><span style=\"text-decoration: underline; color: #000080;\"><strong>Data Copying from Kernel to User Space<\/strong><\/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 discuss about data copying between kernel space and user space, you have got two functions&nbsp;<\/span><\/p>\n<ol 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=\"\">\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #000000;\">copy_to_user and&nbsp;<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #000000;\">copy_from_user.<\/span><\/li>\n<\/ol>\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 role of these two functions.<\/span><\/p>\n<ul 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=\"\">\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #000000;\">These functions are used for copying data between user space and kernel space.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #000000;\">So, these functions check whether the userspace pointer is valid or not.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #000000;\">If the pointer is invalid, no copy is performed.&nbsp;<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #000000;\">If an invalid address is encountered during the copy, only part of the data is copied. In both cases, the return value is the amount of memory still to be copied.<\/span><\/li>\n<\/ul>\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;\">These functions check whether the user-level memory pointer is valid or not and if these functions detect any invalid memory during data copy. So, the data copy will be stopped, and the amount of data which is still to be copied will be returned by this functions.<\/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;\">So, now let&#8217;s understand the syntax of using copy_to_user and copy_from_user.&nbsp;<\/span><span style=\"font-weight: 400;\">Let&#8217;s understand copy_to_user(shown in Figure 10).<\/span><\/span><\/p>\n<figure id=\"attachment_7996\" aria-describedby=\"caption-attachment-7996\" style=\"width: 663px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7996 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-10-1.png\" alt=\"Understanding read method\" width=\"663\" height=\"327\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1.png 663w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1-300x148.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1-600x296.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1-120x59.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1-500x247.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1-200x99.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-10-1-400x197.png 400w\" sizes=\"(max-width: 663px) 100vw, 663px\" \/><figcaption id=\"caption-attachment-7996\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 10. copy_to_user<\/span><\/figcaption><\/figure>\n<p class=\"\" 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=\"color: #000000;\"><span style=\"font-weight: 400;\">Because we will be using this in our read method. It takes 3 arguments here. The first argument is a destination address in userspace, and here const void *from you should mention the source address. That is the kernel space address. The data will be copied from here to here(<\/span><b>const void *from to void __user *to<\/b><span style=\"font-weight: 400;\">). And this <\/span><b>unsigned long n<\/b><span style=\"font-weight: 400;\"> is a number of bytes to copy. The return value is very important. Returns zero on success or number of bytes that could not be copied.<\/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;\">If this function returns the non-zero value, you should assume that there was a problem during data copy. So, you have to return the appropriate error code. In this case, error code will be EFAULT.&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;\">But, if this copy_to_user doesn&#8217;t return&nbsp; 0, then you should return EFAULT.<\/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 explore copy_from_user(shown in Figure 11).<\/span><\/p>\n<figure id=\"attachment_7997\" aria-describedby=\"caption-attachment-7997\" style=\"width: 611px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-7997 size-full\" src=\"http:\/\/fastbitlab.com\/wp-content\/uploads\/2022\/03\/Figure-11-1.png\" alt=\"Understanding read method\" width=\"611\" height=\"263\" srcset=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1.png 611w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1-300x129.png 300w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1-600x258.png 600w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1-120x52.png 120w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1-500x215.png 500w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1-200x86.png 200w, https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-11-1-400x172.png 400w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><figcaption id=\"caption-attachment-7997\" class=\"wp-caption-text\"><span style=\"color: #000000;\">Figure 11. copy_from_user<\/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=\"color: #000000;\"><span style=\"font-weight: 400;\">Copy_from_user means copy from a user-level program to the kernel, that is, we use this during write. So, the parameters this <\/span><b>void *to<\/b><span style=\"font-weight: 400;\"> is a destination address in kernel space, and this <\/span><b>const void __user *from<\/b><span style=\"font-weight: 400;\"> is source address in userspace. Data copy happens from here to here(<\/span><b>const void __user *from to void *to<\/b><span style=\"font-weight: 400;\">). In both the functions, the first argument is destination remember that. The first argument is always destination. The same thing returns 0 on success or a number of bytes that could not be copied.<\/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;\">In the following article, let&#8217;s get back to coding and let&#8217;s code our read method of the driver. I will see you in the following article.<\/span><\/p>\n<p class=\"\">&nbsp;<\/p>\n<p class=\"\" style=\"font-size: 18px; line-height: 30px; font-family: 'Roboto Slab'; font-weight: 400;\" data-font-family=\"Roboto Slab\" data-font-weight=\"400\" data-font-style=\"\"><strong><span style=\"color: #993366;\">Get the Full Course on Linux Device Driver<span style=\"color: #0000ff;\"> <a style=\"color: #0000ff;\" href=\"https:\/\/www.udemy.com\/course\/linux-device-driver-programming-using-beaglebone-black\/\">Here<\/a><\/span><\/span><\/strong><\/p>\n<p class=\"\" style=\"border-width: 0px; font-size: 18px; line-height: 20px;\"><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;\"><span style=\"color: #000000;\">lick here:<\/span>&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; Understanding read method &nbsp; &nbsp; In this article, let&#8217;s understand our driver&#8217;s read method implementation. &nbsp; What is read? The user-level process executes a read system call to read from a file. In our case, the file is not a regular file but a device file, which handles our pseudo character device. In our [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7987,"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-7984","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>read method - Linux device Driver Programming<\/title>\n<meta name=\"description\" content=\"Linux device Driver Programming - Implementation of the read method in driver programming. Learn about steps, file positions, EOF scenarios,\" \/>\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\/linux-device-driver-programming-lecture-39-understanding-read-method\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"read method - Linux device Driver Programming\" \/>\n<meta property=\"og:description\" content=\"Linux device Driver Programming - Implementation of the read method in driver programming. Learn about steps, file positions, EOF scenarios,\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/\" \/>\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-01T08:15:08+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-14T11:02:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"701\" \/>\n\t<meta property=\"og:image:height\" content=\"356\" \/>\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=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/\"},\"author\":{\"name\":\"FastBitLab\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#\\\/schema\\\/person\\\/e32b38e733a0d76ffa7e6bc998652e5d\"},\"headline\":\"Linux Device Driver Programming Lecture 39- Understanding read method\",\"datePublished\":\"2022-03-01T08:15:08+00:00\",\"dateModified\":\"2023-09-14T11:02:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/\"},\"wordCount\":2137,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-1-1.png\",\"keywords\":[\"Linux Device Driver Programming Tutorial\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/\",\"name\":\"read method - Linux device Driver Programming\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-1-1.png\",\"datePublished\":\"2022-03-01T08:15:08+00:00\",\"dateModified\":\"2023-09-14T11:02:15+00:00\",\"description\":\"Linux device Driver Programming - Implementation of the read method in driver programming. Learn about steps, file positions, EOF scenarios,\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#primaryimage\",\"url\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-1-1.png\",\"contentUrl\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/03\\\/Figure-1-1.png\",\"width\":701,\"height\":356,\"caption\":\"Figure 1. Read method implementation\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/linux-device-driver-programming-lecture-39-understanding-read-method\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/fastbitlab.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Linux Device Driver Programming Lecture 39- Understanding read method\"}]},{\"@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":"read method - Linux device Driver Programming","description":"Linux device Driver Programming - Implementation of the read method in driver programming. Learn about steps, file positions, EOF scenarios,","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\/linux-device-driver-programming-lecture-39-understanding-read-method\/","og_locale":"en_US","og_type":"article","og_title":"read method - Linux device Driver Programming","og_description":"Linux device Driver Programming - Implementation of the read method in driver programming. Learn about steps, file positions, EOF scenarios,","og_url":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/","og_site_name":"FastBit EBA","article_publisher":"https:\/\/www.facebook.com\/fastbiteba\/","article_published_time":"2022-03-01T08:15:08+00:00","article_modified_time":"2023-09-14T11:02:15+00:00","og_image":[{"width":701,"height":356,"url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.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":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#article","isPartOf":{"@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/"},"author":{"name":"FastBitLab","@id":"https:\/\/fastbitlab.com\/blog\/#\/schema\/person\/e32b38e733a0d76ffa7e6bc998652e5d"},"headline":"Linux Device Driver Programming Lecture 39- Understanding read method","datePublished":"2022-03-01T08:15:08+00:00","dateModified":"2023-09-14T11:02:15+00:00","mainEntityOfPage":{"@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/"},"wordCount":2137,"commentCount":0,"publisher":{"@id":"https:\/\/fastbitlab.com\/blog\/#organization"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#primaryimage"},"thumbnailUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.png","keywords":["Linux Device Driver Programming Tutorial"],"articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/","url":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/","name":"read method - Linux device Driver Programming","isPartOf":{"@id":"https:\/\/fastbitlab.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#primaryimage"},"image":{"@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#primaryimage"},"thumbnailUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.png","datePublished":"2022-03-01T08:15:08+00:00","dateModified":"2023-09-14T11:02:15+00:00","description":"Linux device Driver Programming - Implementation of the read method in driver programming. Learn about steps, file positions, EOF scenarios,","breadcrumb":{"@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#primaryimage","url":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.png","contentUrl":"https:\/\/fastbitlab.com\/blog\/wp-content\/uploads\/2022\/03\/Figure-1-1.png","width":701,"height":356,"caption":"Figure 1. Read method implementation"},{"@type":"BreadcrumbList","@id":"https:\/\/fastbitlab.com\/blog\/linux-device-driver-programming-lecture-39-understanding-read-method\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fastbitlab.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Linux Device Driver Programming Lecture 39- Understanding read method"}]},{"@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\/7984","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=7984"}],"version-history":[{"count":5,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/7984\/revisions"}],"predecessor-version":[{"id":15938,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/posts\/7984\/revisions\/15938"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/media\/7987"}],"wp:attachment":[{"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/media?parent=7984"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/categories?post=7984"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fastbitlab.com\/blog\/wp-json\/wp\/v2\/tags?post=7984"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}