0

I am new to RTEMS and I want to write a very simple character device for it but when I search in internet I can't find anything.

I can write character device for linux but doesn't have any experience in RTEMS.

I want to write a character device having 3 function: init(), exit() , read().

and when i call read just return a string.

Is there any reference to give me a hint to write this simple device driver?

milad
  • 1,854
  • 2
  • 11
  • 27

1 Answers1

1

This maybe depends a bit what you mean by "simple character device". I assume that you want something that is accessible via a device interface (similar to the Linux character devices).

In RTEMS there are some frameworks for I2C, SPI, serial ports, and some more simple interfaces. Quite a bit of drivers is pulled in from FreeBSD via libbsd and therefore uses the FreeBSD interface. Hardware that doesn't fit one of the frameworks uses a self defined interface most of the time. That can also be a file like interface.

If you want to use a file like interface you want to take a look at IMFS_make_generic_node. You can take a look at the I2C driver for a fully working example: https://git.rtems.org/rtems/tree/cpukit/dev/i2c/i2c-dev.c?id=94481cedc4165f6a49ef5287098251740922fee1#n147

A bit of a more minimal example could look like follows: Note that I write the following more or less from my head so there can be quite some typos and there are quite sure missing headers:

#include <rtems/imfs.h>

static ssize_t my_read(
  rtems_libio_t *iop,
  void *buffer,
  size_t count
)
{
  memset(buffer, 42, count);
  return count;
}

static const rtems_filesystem_file_handlers_r my_handler = {
    .open_h = rtems_filesystem_default_open,
    .close_h = rtems_filesystem_default_close,
    .read_h = my_read,
    .write_h = rtems_filesystem_default_write,
    .ioctl_h = rtems_filesystem_default_ioctl,
    .lseek_h = rtems_filesystem_default_lseek_file,
    .fstat_h = rtems_filesystem_default_fstat,
    .ftruncate_h = rtems_filesystem_default_ftruncate,
    .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
    .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
    .fcntl_h = rtems_filesystem_default_fcntl,
    .kqfilter_h = rtems_filesystem_default_kqfilter,
    .mmap_h = rtems_filesystem_default_mmap,
    .poll_h = rtems_filesystem_default_poll,
    .readv_h = rtems_filesystem_default_readv,
    .writev_h = rtems_filesystem_default_writev
};

static const IMFS_node_control my_node_control = IMFS_GENERIC_INITIALIZER(
  &my_handler,
  IMFS_node_initialize_generic,
  IMFS_node_destroy_default,
);

void my_Initialize( void )
{
  IMFS_make_generic_node(
    "/dev/my_dev",
    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
    &my_node_control,
    NULL
  );
}

Calling my_Initialize should give you a "/dev/my_dev" where you can read any amount of 42 that you want.

  • Your example and explanation was great. Thank you very much Christian. Dear Christian, I have some more question, can you give me your email address to ask. I will be thankful to you if you do that because I am really new to RTEMS and I think you can be a good leader for me. – milad Oct 29 '19 at 06:45
  • @milad: I would suggest the RTEMS users mailing list for that type of questions. Most of the developers (including myself) and a lot of users read that list. Normally the list is quite friendly and open to all new users. So you have the best chance to get fast and good answers there: https://lists.rtems.org/mailman/listinfo/users – Christian Mauderer Oct 29 '19 at 10:06
  • OK, Next time i will try that. thank you very much. – milad Oct 31 '19 at 17:13