All of lore.kernel.org
 help / color / mirror / Atom feed
* Is anybody can show me a simple rtdm driver to read/write virtual memory device?
@ 2020-04-06  7:22 孙世龙
  2020-04-06  7:45 ` Jan Kiszka
  0 siblings, 1 reply; 5+ messages in thread
From: 孙世龙 @ 2020-04-06  7:22 UTC (permalink / raw)
  To: xenomai

Is anybody could show me a simple xenomai3 rtdm driver to read/write
virtual memory device?
A virtual memory device to:
    write "hello world" to memory device in real real time(It's appricate
if the write operation could wake up the read task which allready waited to
read)
read  the memory device in real time(It's appricate if the read operation
could wake up the write task which allready waited to write)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is anybody can show me a simple rtdm driver to read/write virtual memory device?
  2020-04-06  7:22 Is anybody can show me a simple rtdm driver to read/write virtual memory device? 孙世龙
@ 2020-04-06  7:45 ` Jan Kiszka
       [not found]   ` <CAAvDm6aatWP2G6h3YavWE2KYk6++omNgkJ2ntjQaXk-jYtEbbQ@mail.gmail.com>
  2020-04-07 10:33   ` Pierre FICHEUX
  0 siblings, 2 replies; 5+ messages in thread
From: Jan Kiszka @ 2020-04-06  7:45 UTC (permalink / raw)
  To: 孙世龙, xenomai

On 06.04.20 09:22, 孙世龙 via Xenomai wrote:
> Is anybody could show me a simple xenomai3 rtdm driver to read/write
> virtual memory device?
> A virtual memory device to:
>      write "hello world" to memory device in real real time(It's appricate
> if the write operation could wake up the read task which allready waited to
> read)
> read  the memory device in real time(It's appricate if the read operation
> could wake up the write task which allready waited to write)
> 

What do you mean with "virtual memory"?

If you are looking for a pattern how a driver implements read/write 
callbacks, maybe study the serial drivers. They come closest to "simple".

Jan

-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is anybody can show me a simple rtdm driver to read/write virtual memory device?
       [not found]   ` <CAAvDm6aatWP2G6h3YavWE2KYk6++omNgkJ2ntjQaXk-jYtEbbQ@mail.gmail.com>
@ 2020-04-06  8:53     ` Jan Kiszka
  0 siblings, 0 replies; 5+ messages in thread
From: Jan Kiszka @ 2020-04-06  8:53 UTC (permalink / raw)
  To: 孙世龙, Xenomai

[re-adding the mailing list]

On 06.04.20 10:20, 孙世龙 wrote:
> Thanks a lot for your replay.
> 
> My english is poor.I am sorry to confuse you.
> 

No problem! We are both not native speakers.

> I wrote in last letter  " a simple rtdm driver to read/write virtual 
> memory device ".
> I mean a simple device driver to read\write some bytes from memory 
> ,which is not a driver  for a practical hardware .The simple device 
> driver works like the /dev/null or /dev/zero in linux.
> To make it more clearly, i hope to port this simple linux driver listed 
> below to rtdm driver.

Did you study the RTDM API already [1]? As a rule of thumb, if there are 
corresponding functions, use them in favor of the Linux API. If you have 
any question on a particular one, drop it here on the list.

Jan

[1] 
https://xenomai.org/documentation/xenomai-3/html/xeno3prm/group__rtdm.html

> 
> #include<linux/init.h >
> #include<linux/module.h >
> #include<linux/kernel.h >	/* printk() */
> #include<linux/slab.h >		/* kmalloc() */
> #include<linux/fs.h >		/* everything... */
> #include<linux/errno.h >	/* error codes */
> #include<linux/types.h >	/* size_t */
> #include<linux/fcntl.h >	/* O_ACCMODE */
> #include<linux/cdev.h >
> #include<asm/uaccess.h >	/* copy_*_user */
> 
> 
> MODULE_LICENSE("Dual BSD/GPL");
> MODULE_AUTHOR("Hcamael");
> 
> int scull_major=    0;
> int scull_minor=    0;
> int scull_nr_devs=  4;
> int scull_quantum=  4000;
> int scull_qset=  1000;
> 
> struct scull_qset{
> 	void  **data;
> 	struct scull_qset*next;
> };
> 
> struct scull_dev{
> 	struct scull_qset*data;   /* Pointer to first quantum set. */
> 	int quantum;               /* The current quantum size. */
> 	int qset;                  /* The current array size. */
> 	unsigned long size;        /* Amount of data stored here. */
> 	unsigned int access_key;   /* Used by sculluid and scullpriv. */
> 	struct mutex mutex;        /* Mutual exclusion semaphore. */
> 	struct cdev cdev;	/* Char device structure. */
> };
> 
> struct scull_dev*scull_devices;	/* allocated in scull_init_module */
> 
> /* * Follow the list. */
> struct scull_qset*scull_follow(struct scull_dev*dev,  int n)
> {
> 	struct scull_qset*qs=  dev->data;
> 
>          /* Allocate the first qset explicitly if need be. */
> 	if  (!  qs)  {
> 		qs=  dev->data=  kmalloc(sizeof(struct scull_qset),  GFP_KERNEL);
> 		if  (qs==  NULL)
> 			return  NULL;
> 		memset(qs,  0,  sizeof(struct scull_qset));
> 	}
> 
> 	/* Then follow the list. */
> 	while  (n--)  {
> 		if  (!qs->next)  {
> 			qs->next=  kmalloc(sizeof(struct scull_qset),  GFP_KERNEL);
> 			if  (qs->next==  NULL)
> 				return  NULL;
> 			memset(qs->next,  0,  sizeof(struct scull_qset));
> 		}
> 		qs=  qs->next;
> 		continue;
> 	}
> 	return  qs;
> }
> 
> /* * Data management: read and write. */
> 
> ssize_tscull_read(struct file*filp,  char __user*buf,  size_t count,
>                  loff_t*f_pos)
> {
> 	struct scull_dev*dev=  filp->private_data;
> 	struct scull_qset*dptr;  /* the first listitem */
> 	int quantum=  dev->quantum,  qset=  dev->qset;
> 	int itemsize=  quantum*  qset;  /* how many bytes in the listitem */
> 	int item,  s_pos,  q_pos,  rest;
> 	ssize_t retval=  0;
> 
> 	if  (mutex_lock_interruptible(&dev->mutex))
> 		return  -ERESTARTSYS;
> 	if  (*f_pos >=  dev->size)
> 		goto out;
> 	if  (*f_pos+  count >  dev->size)
> 		count=  dev->size-  *f_pos;
> 
> 	/* Find listitem, qset index, and offset in the quantum */
> 	item=  (long)*f_pos/  itemsize;
> 	rest=  (long)*f_pos%  itemsize;
> 	s_pos=  rest/  quantum;  q_pos=  rest%  quantum;
> 
> 	/* follow the list up to the right position (defined elsewhere) */
> 	dptr=  scull_follow(dev,  item);
> 
> 	if  (dptr==  NULL||  !dptr->data||  !  dptr->data[s_pos])
> 		goto out;  /* don't fill holes */
> 
> 	/* read only up to the end of this quantum */
> 	if  (count >  quantum-  q_pos)
> 		count=  quantum-  q_pos;
> 
> 	if  (raw_copy_to_user(buf,  dptr->data[s_pos]  +  q_pos,  count))  {
> 		retval=  -EFAULT;
> 		goto out;
> 	}
> 	*f_pos+=  count;
> 	retval=  count;
> 
>    out:
> 	mutex_unlock(&dev->mutex);
> 	return  retval;
> }
> 
> ssize_tscull_write(struct file*filp,  const  char __user*buf,  size_t count,
>                  loff_t*f_pos)
> {
> 	struct scull_dev*dev=  filp->private_data;
> 	struct scull_qset*dptr;
> 	int quantum=  dev->quantum,  qset=  dev->qset;
> 	int itemsize=  quantum*  qset;
> 	int item,  s_pos,  q_pos,  rest;
> 	ssize_t retval=  -ENOMEM;  /* Value used in "goto out" statements. */
> 
> 	if  (mutex_lock_interruptible(&dev->mutex))
> 		return  -ERESTARTSYS;
> 
> 	/* Find the list item, qset index, and offset in the quantum. */
> 	item=  (long)*f_pos/  itemsize;
> 	rest=  (long)*f_pos%  itemsize;
> 	s_pos=  rest/  quantum;
> 	q_pos=  rest%  quantum;
> 
> 	/* Follow the list up to the right position. */
> 	dptr=  scull_follow(dev,  item);
> 	if  (dptr==  NULL)
> 		goto out;
> 	if  (!dptr->data)  {
> 		dptr->data=  kmalloc(qset*  sizeof(char*),  GFP_KERNEL);
> 		if  (!dptr->data)
> 			goto out;
> 		memset(dptr->data,  0,  qset*  sizeof(char*));
> 	}
> 	if  (!dptr->data[s_pos])  {
> 		dptr->data[s_pos]  =  kmalloc(quantum,  GFP_KERNEL);
> 		if  (!dptr->data[s_pos])
> 			goto out;
> 	}
> 	/* Write only up to the end of this quantum. */
> 	if  (count >  quantum-  q_pos)
> 		count=  quantum-  q_pos;
> 
> 	if  (raw_copy_from_user(dptr->data[s_pos]+q_pos,  buf,  count))  {
> 		retval=  -EFAULT;
> 		goto out;
> 	}
> 	*f_pos+=  count;
> 	retval=  count;
> 
>          /* Update the size. */
> 	if  (dev->size<  *f_pos)
> 		dev->size=  *f_pos;
> 
>    out:
> 	mutex_unlock(&dev->mutex);
> 	return  retval;
> }
> 
> /* Beginning of the scull device implementation. */
> 
> /* * Empty out the scull device; must be called with the device * mutex 
> held. */
> intscull_trim(struct scull_dev*dev)
> {
> 	struct scull_qset*next,  *dptr;
> 	int qset=  dev->qset;    /* "dev" is not-null */
> 	int i;
> 
> 	for  (dptr=  dev->data;  dptr;  dptr=  next)  {  /* all the list items */
> 		if  (dptr->data)  {
> 			for  (i=  0;  i<  qset;  i++)
> 				kfree(dptr->data[i]);
> 			kfree(dptr->data);
> 			dptr->data=  NULL;
> 		}
> 		next=  dptr->next;
> 		kfree(dptr);
> 	}
> 	dev->size=  0;
> 	dev->quantum=  scull_quantum;
> 	dev->qset=  scull_qset;
> 	dev->data=  NULL;
> 	return  0;
> }
> 
> intscull_release(struct inode*inode,  struct file*filp)
> {
>      printk(KERN_DEBUG"process %i (%s) success release minor(%u) file\n",  current->pid,  current->comm,  iminor(inode));
> 	return  0;
> }
> 
> /* * Open and close */
> 
> intscull_open(struct inode*inode,  struct file*filp)
> {
> 	struct scull_dev*dev;  /* device information */
> 
> 	dev=  container_of(inode->i_cdev,  struct scull_dev,  cdev);
> 	filp->private_data=  dev;  /* for other methods */
> 
> 	/* If the device was opened write-only, trim it to a length of 0. */
> 	if  (  (filp->f_flags&  O_ACCMODE)  ==  O_WRONLY)  {
> 		if  (mutex_lock_interruptible(&dev->mutex))
> 			return  -ERESTARTSYS;
> 		scull_trim(dev);  /* Ignore errors. */
> 		mutex_unlock(&dev->mutex);
> 	}
>      printk(KERN_DEBUG"process %i (%s) success open minor(%u) file\n",  current->pid,  current->comm,  iminor(inode));
> 	return  0;
> }
> 
> /* * The "extended" operations -- only seek. */
> 
> loff_tscull_llseek(struct file*filp,  loff_t off,  int whence)
> {
> 	struct scull_dev*dev=  filp->private_data;
> 	loff_t newpos;
> 
> 	switch(whence)  {
> 	case  0:  /* SEEK_SET */
> 		newpos=  off;
> 		break;
> 
> 	case  1:  /* SEEK_CUR */
> 		newpos=  filp->f_pos+  off;
> 		break;
> 
> 	case  2:  /* SEEK_END */
> 		newpos=  dev->size+  off;
> 		break;
> 
> 	default:  /* can't happen */
> 		return  -EINVAL;
> 	}
> 	if  (newpos<  0)
> 		return  -EINVAL;
> 	filp->f_pos=  newpos;
> 	return  newpos;
> }
> 
> struct file_operations scull_fops=  {
> 	.owner=     THIS_MODULE,
> 	.llseek=    scull_llseek,
> 	.read=      scull_read,
> 	.write=     scull_write,
> 	// .unlocked_ioctl = scull_ioctl,
> 	.open=      scull_open,
> 	.release=   scull_release,
> };
> 
> /* * Set up the char_dev structure for this device. */
> static  void  scull_setup_cdev(struct scull_dev*dev,  int index)
> {
> 	int err,  devno=  MKDEV(scull_major,  scull_minor+  index);
> 
> 	cdev_init(&dev->cdev,  &scull_fops);
> 	dev->cdev.owner=  THIS_MODULE;
> 	dev->cdev.ops=  &scull_fops;
> 	err=  cdev_add  (&dev->cdev,  devno,  1);
> 	/* Fail gracefully if need be. */
> 	if  (err)
> 		printk(KERN_NOTICE"Error %d adding scull%d",  err,  index);
>      else
>          printk(KERN_INFO"scull: %d add success\n",  index);
> }
> 
> 
> void  scull_cleanup_module(void)
> {
> 	int i;
> 	dev_t devno=  MKDEV(scull_major,  scull_minor);
> 
> 	/* Get rid of our char dev entries. */
> 	if  (scull_devices)  {
> 		for  (i=  0;  i<  scull_nr_devs;  i++)  {
> 			scull_trim(scull_devices+  i);
> 			cdev_del(&scull_devices[i].cdev);
> 		}
> 		kfree(scull_devices);
> 	}
> 
> 	/* cleanup_module is never called if registering failed. */
> 	unregister_chrdev_region(devno,  scull_nr_devs);
>      printk(KERN_INFO"scull: cleanup success\n");
> }
> 
> 
> intscull_init_module(void)
> {
> 	int result,  i;
> 	dev_t dev=  0;
> 
> 	/* * Get a range of minor numbers to work with, asking for a dynamic 
> major * unless directed otherwise at load time. */
> 	if  (scull_major)  {
> 		dev=  MKDEV(scull_major,  scull_minor);
> 		result=  register_chrdev_region(dev,  scull_nr_devs,  "scull");
> 	}  else  {
> 		result=  alloc_chrdev_region(&dev,  scull_minor,  scull_nr_devs,  "scull");
> 		scull_major=  MAJOR(dev);
> 	}
> 	if  (result<  0)  {
> 		printk(KERN_WARNING"scull: can't get major %d\n",  scull_major);
> 		return  result;
> 	}  else  {
>          printk(KERN_INFO"scull: get major %d success\n",  scull_major);
>      }
> 
>          /* * Allocate the devices. This must be dynamic as the device number can 
> * be specified at load time. */
> 	scull_devices=  kmalloc(scull_nr_devs*  sizeof(struct scull_dev),  GFP_KERNEL);
> 	if  (!scull_devices)  {
> 		result=  -ENOMEM;
> 		goto fail;
> 	}
> 	memset(scull_devices,  0,  scull_nr_devs*  sizeof(struct scull_dev));
> 
>          /* Initialize each device. */
> 	for  (i=  0;  i<  scull_nr_devs;  i++)  {
> 		scull_devices[i].quantum=  scull_quantum;
> 		scull_devices[i].qset=  scull_qset;
> 		mutex_init(&scull_devices[i].mutex);
> 		scull_setup_cdev(&scull_devices[i],  i);
> 	}
> 
> 	return  0;  /* succeed */
> 
>    fail:
> 	scull_cleanup_module();
> 	return  result;
> }
> 
> module_init(scull_init_module);
> module_exit(scull_cleanup_module);
> 
> 
> 
> 
> 
> 
> Jan Kiszka <jan.kiszka@siemens.com <mailto:jan.kiszka@siemens.com>> 于 
> 2020年4月6日周一 下午3:45写道:
> 
>     On 06.04.20 09:22, 孙世龙 via Xenomai wrote:
>      > Is anybody could show me a simple xenomai3 rtdm driver to read/write
>      > virtual memory device?
>      > A virtual memory device to:
>      >      write "hello world" to memory device in real real time(It's
>     appricate
>      > if the write operation could wake up the read task which allready
>     waited to
>      > read)
>      > read  the memory device in real time(It's appricate if the read
>     operation
>      > could wake up the write task which allready waited to write)
>      >
> 
>     What do you mean with "virtual memory"?
> 
>     If you are looking for a pattern how a driver implements read/write
>     callbacks, maybe study the serial drivers. They come closest to
>     "simple".
> 
>     Jan
> 
>     -- 
>     Siemens AG, Corporate Technology, CT RDA IOT SES-DE
>     Corporate Competence Center Embedded Linux
> 


-- 
Siemens AG, Corporate Technology, CT RDA IOT SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is anybody can show me a simple rtdm driver to read/write virtual memory device?
  2020-04-06  7:45 ` Jan Kiszka
       [not found]   ` <CAAvDm6aatWP2G6h3YavWE2KYk6++omNgkJ2ntjQaXk-jYtEbbQ@mail.gmail.com>
@ 2020-04-07 10:33   ` Pierre FICHEUX
  2020-04-07 11:16     ` 孙世龙
  1 sibling, 1 reply; 5+ messages in thread
From: Pierre FICHEUX @ 2020-04-07 10:33 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: 孙世龙, xenomai

Hi,

I wrote some RTDM examples for Pi 3 GPIO (based on BCM register access, not
GPIO kernel API).

May be it could help...

regards

Le lun. 6 avr. 2020 à 09:45, Jan Kiszka via Xenomai <xenomai@xenomai.org> a
écrit :

> On 06.04.20 09:22, 孙世龙 via Xenomai wrote:
> > Is anybody could show me a simple xenomai3 rtdm driver to read/write
> > virtual memory device?
> > A virtual memory device to:
> >      write "hello world" to memory device in real real time(It's
> appricate
> > if the write operation could wake up the read task which allready waited
> to
> > read)
> > read  the memory device in real time(It's appricate if the read operation
> > could wake up the write task which allready waited to write)
> >
>
> What do you mean with "virtual memory"?
>
> If you are looking for a pattern how a driver implements read/write
> callbacks, maybe study the serial drivers. They come closest to "simple".
>
> Jan
>
> --
> Siemens AG, Corporate Technology, CT RDA IOT SES-DE
> Corporate Competence Center Embedded Linux
>
>

-- 

Pierre FICHEUX -/- CTO Smile ECS, France -\- pierre.ficheux@smile.fr
                             http://www.smile.fr
                             https://smile.eu/fr/offres/embarque-iot
I would love to change the world, but they won't give me the source code

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Is anybody can show me a simple rtdm driver to read/write virtual memory device?
  2020-04-07 10:33   ` Pierre FICHEUX
@ 2020-04-07 11:16     ` 孙世龙
  0 siblings, 0 replies; 5+ messages in thread
From: 孙世龙 @ 2020-04-07 11:16 UTC (permalink / raw)
  To: Pierre FICHEUX; +Cc: Jan Kiszka, xenomai

Thanks, I'll check it out.

Pierre FICHEUX <pierre.ficheux@smile.fr> 于2020年4月7日周二 下午6:34写道:

> Hi,
>
> I wrote some RTDM examples for Pi 3 GPIO (based on BCM register access,
> not GPIO kernel API).
>
> May be it could help...
>
> regards
>
> Le lun. 6 avr. 2020 à 09:45, Jan Kiszka via Xenomai <xenomai@xenomai.org>
> a écrit :
>
>> On 06.04.20 09:22, 孙世龙 via Xenomai wrote:
>> > Is anybody could show me a simple xenomai3 rtdm driver to read/write
>> > virtual memory device?
>> > A virtual memory device to:
>> >      write "hello world" to memory device in real real time(It's
>> appricate
>> > if the write operation could wake up the read task which allready
>> waited to
>> > read)
>> > read  the memory device in real time(It's appricate if the read
>> operation
>> > could wake up the write task which allready waited to write)
>> >
>>
>> What do you mean with "virtual memory"?
>>
>> If you are looking for a pattern how a driver implements read/write
>> callbacks, maybe study the serial drivers. They come closest to "simple".
>>
>> Jan
>>
>> --
>> Siemens AG, Corporate Technology, CT RDA IOT SES-DE
>> Corporate Competence Center Embedded Linux
>>
>>
>
> --
>
> Pierre FICHEUX -/- CTO Smile ECS, France -\- pierre.ficheux@smile.fr
>                              http://www.smile.fr
>                              https://smile.eu/fr/offres/embarque-iot
> I would love to change the world, but they won't give me the source code
>
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-07 11:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-06  7:22 Is anybody can show me a simple rtdm driver to read/write virtual memory device? 孙世龙
2020-04-06  7:45 ` Jan Kiszka
     [not found]   ` <CAAvDm6aatWP2G6h3YavWE2KYk6++omNgkJ2ntjQaXk-jYtEbbQ@mail.gmail.com>
2020-04-06  8:53     ` Jan Kiszka
2020-04-07 10:33   ` Pierre FICHEUX
2020-04-07 11:16     ` 孙世龙

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.