当前位置: 技术问答>嵌入式网络编程与非嵌入式网络编程有什么不同
iis7站长之家
嵌入式系统字符驱动程序(应用)问题(初学),请帮忙回答
来源: 互联网 发布时间:2015-07-13
本文导语: 我要做的是把一个字符设备的驱动程序加载到arm开发板上,我已经通过交叉编译,并且也已经把程序下载到开发板上了,自己写了一个很小的测试程序 main() { int buf[10]; int fd = open("/dev/s3c2410-ts",0); if(-1==fd) print...
我要做的是把一个字符设备的驱动程序加载到arm开发板上,我已经通过交叉编译,并且也已经把程序下载到开发板上了,自己写了一个很小的测试程序
main()
{
int buf[10];
int fd = open("/dev/s3c2410-ts",0);
if(-1==fd)
printf("Can't open TS!");
while(1)
{
read( fd,buf,10);
for( int i=0; ix = BUF_TAIL.x;
ts_ret->y = BUF_TAIL.y;
ts_ret->pressure = BUF_TAIL.pressure;
tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF);
spin_unlock_irq(&(tsdev.lock));
return sizeof(TS_RET);
}
static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
TS_RET ts_ret;
retry:
if (tsdev.head != tsdev.tail) {
int count;
count = tsRead(&ts_ret);
if (count) copy_to_user(buffer, (char *)&ts_ret, count);
return count;
} else {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
interruptible_sleep_on(&(tsdev.wq));
if (signal_pending(current))
return -ERESTARTSYS;
goto retry;
}
return sizeof(TS_RET);
}
#ifdef USE_ASYNC
static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)
{
return fasync_helper(fd, filp, mode, &(tsdev.aq));
}
#endif
static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait)
{
poll_wait(filp, &(tsdev.wq), wait);
return (tsdev.head == tsdev.tail) ? 0 : (POLLIN | POLLRDNORM);
}
static inline void start_ts_adc(void)
{
adc_state = 0;
mode_x_axis();
start_adc_x();
}
static inline void s3c2410_get_XY(void)
{
if (adc_state == 0) {
adc_state = 1;
disable_ts_adc();
y = (ADCDAT0 & 0x3ff);
mode_y_axis();
start_adc_y();
} else if (adc_state == 1) {
adc_state = 0;
disable_ts_adc();
x = (ADCDAT1 & 0x3ff);
tsdev.penStatus = PEN_DOWN;
DPRINTK("PEN DOWN: x: %08d, y: %08dn", x, y);
wait_up_int();
tsEvent();
}
}
static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)
{
#if 0
DPRINTK("Occured Touch Screen Interruptn");
DPRINTK("SUBSRCPND = 0x%08lxn", SUBSRCPND);
#endif
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP)
s3c2410_get_XY();
#ifdef HOOK_FOR_DRAG
else
s3c2410_get_XY();
#endif
spin_unlock_irq(&(tsdev.lock));
}
static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
{
#if 0
DPRINTK("Occured Touch Screen Interruptn");
DPRINTK("SUBSRCPND = 0x%08lxn", SUBSRCPND);
#endif
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP) {
start_ts_adc();
} else {
tsdev.penStatus = PEN_UP;
DPRINTK("PEN UP: x: %08d, y: %08dn", x, y);
wait_down_int();
tsEvent();
}
spin_unlock_irq(&(tsdev.lock));
}
#ifdef HOOK_FOR_DRAG
static void ts_timer_handler(unsigned long data)
{
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_DOWN) {
start_ts_adc();
}
spin_unlock_irq(&(tsdev.lock));
}
#endif
static int s3c2410_ts_open(struct inode *inode, struct file *filp)
{
tsdev.head = tsdev.tail = 0;
tsdev.penStatus = PEN_UP;
#ifdef HOOK_FOR_DRAG
init_timer(&ts_timer);
ts_timer.function = ts_timer_handler;
#endif
tsEvent = tsEvent_raw;
init_waitqueue_head(&(tsdev.wq));
MOD_INC_USE_COUNT;
return 0;
}
static int s3c2410_ts_release(struct inode *inode, struct file *filp)
{
#ifdef HOOK_FOR_DRAG
del_timer(&ts_timer);
#endif
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations s3c2410_fops = {
owner: THIS_MODULE,
open: s3c2410_ts_open,
read: s3c2410_ts_read,
release: s3c2410_ts_release,
#ifdef USE_ASYNC
fasync: s3c2410_ts_fasync,
#endif
poll: s3c2410_ts_poll,
};
void tsEvent_dummy(void) {}
#ifdef CONFIG_PM
static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
void *data)
{
switch (req) {
case PM_SUSPEND:
tsEvent = tsEvent_dummy;
break;
case PM_RESUME:
tsEvent = tsEvent_raw;
wait_down_int();
break;
}
return 0;
}
#endif
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_ts_dir, devfs_tsraw;
#endif
static int __init s3c2410_ts_init(void)
{
int ret;
tsEvent = tsEvent_dummy;
ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);
if (ret
main()
{
int buf[10];
int fd = open("/dev/s3c2410-ts",0);
if(-1==fd)
printf("Can't open TS!");
while(1)
{
read( fd,buf,10);
for( int i=0; ix = BUF_TAIL.x;
ts_ret->y = BUF_TAIL.y;
ts_ret->pressure = BUF_TAIL.pressure;
tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF);
spin_unlock_irq(&(tsdev.lock));
return sizeof(TS_RET);
}
static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
TS_RET ts_ret;
retry:
if (tsdev.head != tsdev.tail) {
int count;
count = tsRead(&ts_ret);
if (count) copy_to_user(buffer, (char *)&ts_ret, count);
return count;
} else {
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
interruptible_sleep_on(&(tsdev.wq));
if (signal_pending(current))
return -ERESTARTSYS;
goto retry;
}
return sizeof(TS_RET);
}
#ifdef USE_ASYNC
static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)
{
return fasync_helper(fd, filp, mode, &(tsdev.aq));
}
#endif
static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait)
{
poll_wait(filp, &(tsdev.wq), wait);
return (tsdev.head == tsdev.tail) ? 0 : (POLLIN | POLLRDNORM);
}
static inline void start_ts_adc(void)
{
adc_state = 0;
mode_x_axis();
start_adc_x();
}
static inline void s3c2410_get_XY(void)
{
if (adc_state == 0) {
adc_state = 1;
disable_ts_adc();
y = (ADCDAT0 & 0x3ff);
mode_y_axis();
start_adc_y();
} else if (adc_state == 1) {
adc_state = 0;
disable_ts_adc();
x = (ADCDAT1 & 0x3ff);
tsdev.penStatus = PEN_DOWN;
DPRINTK("PEN DOWN: x: %08d, y: %08dn", x, y);
wait_up_int();
tsEvent();
}
}
static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)
{
#if 0
DPRINTK("Occured Touch Screen Interruptn");
DPRINTK("SUBSRCPND = 0x%08lxn", SUBSRCPND);
#endif
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP)
s3c2410_get_XY();
#ifdef HOOK_FOR_DRAG
else
s3c2410_get_XY();
#endif
spin_unlock_irq(&(tsdev.lock));
}
static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
{
#if 0
DPRINTK("Occured Touch Screen Interruptn");
DPRINTK("SUBSRCPND = 0x%08lxn", SUBSRCPND);
#endif
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP) {
start_ts_adc();
} else {
tsdev.penStatus = PEN_UP;
DPRINTK("PEN UP: x: %08d, y: %08dn", x, y);
wait_down_int();
tsEvent();
}
spin_unlock_irq(&(tsdev.lock));
}
#ifdef HOOK_FOR_DRAG
static void ts_timer_handler(unsigned long data)
{
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_DOWN) {
start_ts_adc();
}
spin_unlock_irq(&(tsdev.lock));
}
#endif
static int s3c2410_ts_open(struct inode *inode, struct file *filp)
{
tsdev.head = tsdev.tail = 0;
tsdev.penStatus = PEN_UP;
#ifdef HOOK_FOR_DRAG
init_timer(&ts_timer);
ts_timer.function = ts_timer_handler;
#endif
tsEvent = tsEvent_raw;
init_waitqueue_head(&(tsdev.wq));
MOD_INC_USE_COUNT;
return 0;
}
static int s3c2410_ts_release(struct inode *inode, struct file *filp)
{
#ifdef HOOK_FOR_DRAG
del_timer(&ts_timer);
#endif
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations s3c2410_fops = {
owner: THIS_MODULE,
open: s3c2410_ts_open,
read: s3c2410_ts_read,
release: s3c2410_ts_release,
#ifdef USE_ASYNC
fasync: s3c2410_ts_fasync,
#endif
poll: s3c2410_ts_poll,
};
void tsEvent_dummy(void) {}
#ifdef CONFIG_PM
static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
void *data)
{
switch (req) {
case PM_SUSPEND:
tsEvent = tsEvent_dummy;
break;
case PM_RESUME:
tsEvent = tsEvent_raw;
wait_down_int();
break;
}
return 0;
}
#endif
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_ts_dir, devfs_tsraw;
#endif
static int __init s3c2410_ts_init(void)
{
int ret;
tsEvent = tsEvent_dummy;
ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);
if (ret