ts-7000
[Top] [All Lists]

Re: [ts-7000] Disabling interrupts and kernel driver ioctls.

To:
Subject: Re: [ts-7000] Disabling interrupts and kernel driver ioctls.
From: Triffid Hunter <>
Date: Sat, 14 Jul 2007 14:16:26 +1000 (EST)
On Fri, 13 Jul 2007, Kevin Cozens wrote:

> Greetings, all.
>
> I have a kernel device driver for a TS-7250 which is generating timer-based
> interrupts every 500uS. The interrupt handler just flips some bits on port B
> resulting in the generation of 1kHz signals on port B. The problem I have is
> that my user space application also needs to control some of the bits of port
> B (but not the ones the kernel driver is changing).
>
> The simple solution would be to have my application disable all interrupts
> during the read/modify/write of port B. The application doesn't need to modify
> the bits of port B that often and the read/modify/write would only take a few
> instructions so they would only be off for a very short time.

This solution only has the illusion of being simple - at the very least, 
it would cause jitter in your output from where interrupts are disabled 
when the timer fires, and at worst you could mess up a whole host of 
kernel timing and other services.

If you want to do atomic operations, do them in kernel space which is 
designed to support them.

> Can I issue disable/enable interrupts instruction in user space (via asm
> directives?) or will I be forced to implement ioctl support in my device
> driver to control the other bits of port B?

I'd add a character device to /dev or /proc which accepts bytes, stores 
them in your kernel module somewhere and mask+ors them to the output every 
interrupt. Avoids anything complex in userspace, allows all the bit 
masking and whatnot to happen in one place, but also puts a <=500uS delay 
on output from userspace apps.

If the delay is unacceptable, you could add another port write to the 
dev_read function that accepts bytes written to the device node, again 
keeping masking and whatnot in the one file as well as allowing high speed 
streams of data from userspace to be accurately represented without 
disturbing the timer.

Here's some c-like pseudocode in case I'm not clear:-

(note that I've never actually written a kernel module before, so this may 
not be how it actually works)

--kernel module--
// bitmask for timer, userspace can have all the 0 bits
#define timer_mask 0b00000100

// current port state
static byte portdata

module_init()
     portdata = 0;
     create(/dev/portB, DEV_CHAR, &userspace_wrote_to_dev_node,
     &userspace_read_dev_node);
     setup_timer_intr();

userspace_wrote_to_dev_node(char *data, int len)
     for (i=0;i<len;i++)
// (timer bits) | (new userspace bits)
         out(portB, portdata = (portdata & timer_mask) | (data[i] &
         ~timer_mask));

// return the port's current output state
userspace_read_dev_node(char *buf, int buflen)
#if CONFIG_INCLUDE_TIMER_BITS
     buf[0] = portdata;
#else
     buf[0] = portdata & ~timer_mask;
#endif
     return 1; // number of bytes written to buffer

timer_intr()
// (userspace bits) | (new timer bits)
     out(portB, portdata = (portdata & ~timer_mask) | ((~portdata) &
     timer_mask));
--end--

--userspace--
int port;
main()
     if ((port = open(/dev/portB)) < 0)
         perror("can't open /dev/portB");
     write(port, "someData");
     while(do_some_calculations(&more_data))
         write(port, more_data);
--end--

If it's possible for the kernel to preempt the dev_write call, or you want 
to use this on a multi-processor system, protect portdata with a mutex or 
spinlock or something.

By chance, I currently have a very relevant article open (watch out for 
long line splitting mail clients & servers) - 
http://www.linuxdevcenter.com/pub/a/linux/2007/07/05/devhelloworld-a-simple-introduction-to-device-drivers-under-linux.html

In theory, you could grow such a system into a generic port driver which 
can allocate different bits to different drivers/processes in either 
kernel or userspace and a generic timer driver which would be incredibly 
useful to many people on this mailing list. Simply posting the code you 
have now could easily allow someone else to do it for us :)



 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 

<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU