0

I am trying to write a simple read/write character driver for a beaglebone. One of the tasks is to be able to use the cat command to read from the device, but I am unable to do so.

Here is the code for my read function for my character device driver located inside char_drvr.c:

ssize_t lkm_read (struct file *pfile,
                  char __user *buffer,
                  size_t length,
                  loff_t *offset)
{
    int device_buffer = (int)gpio_get_value(gpioIn); //gets value from gpio pin (HI or LO)
    return simple_read_from_buffer(buffer,length, offset, &device_buffer, sizeof(int));     
}

Read executes successfully (the correct value is returned) when I run my test application, so I know that device is able to communicate with the device driver, but nothing is returned (right away) when I run

$cat /dev/simple_char_driver

My full code: https://github.com/gteeger/character_driver1

Attempted solutions:

cat function calling read() infinite times

C - infinite read from cat in Device file

and a few others.

Any help is greatly appreciated

gabson
  • 66
  • 7
  • What do you mean by `$cat`? Are you referring to the `cat` command? If so, the `$` isn't part of its name. – Keith Thompson Jul 23 '18 at 07:26
  • I changed my question based on your input. – gabson Jul 23 '18 at 07:29
  • `cat` displays its output to the terminal. The terminal displays ASCII characters. Your read routine does not return bytes containing displayable ASCII characters. And as your comment indicates, the GPIO pin only has values of either one or zero, i.e. a single bit. Have you tried `cat /dev/simple_char_driver | hexdump` ? BTW you almost got the kernel coding style right, but not 100% – sawdust Jul 23 '18 at 08:19
  • you can do as sawdust suggested or in your read function you add '0' to your integer before going for `simple_read_from_buffer`. – yashC Jul 23 '18 at 10:33

1 Answers1

0

Answer: they are called character device drivers, not boolean device drivers.

Fixed code, now cat works:

ssize_t lkm_read (struct file *pfile,
                  char __user *buffer,
                  size_t length,
                  loff_t *offset) 
{
char out = '0';
bool gpioPin = gpio_get_value(gpioIn);
if (gpioPin == 0) out = '0';
if (gpioPin == 1) out = '1';
printk(KERN_ALERT "Inside the %s function\n", __FUNCTION__);
return simple_read_from_buffer(buffer, length, offset, &out, sizeof(char));
}
gabson
  • 66
  • 7