嵌入式系统字符驱动程序(应用)问题(初学),请帮忙回答
我要做的是把一个字符设备的驱动程序加载到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; i<10;i++)
printf('buf[%d]= %d\n",i,buf[i]);
}
}
程序运行后,屏幕上提示 Can't open TS!不知道错在哪里?dev/s3c2410-ts 是不是驱动程序里面的#define DEVICE_NAME "s3c2410-ts"?如果不是在哪里可以找到?
驱动程序:(部分,帖子太长了)
/* debug macros */
#undef DEBUG
#ifdef DEBUG
#define DPRINTK( x... ) printk("s3c2410-ts: " ##x)
#else
#define DPRINTK( x... )
#endif
#define PEN_UP 0
#define PEN_DOWN 1
#define PEN_FLEETING 2
#define MAX_TS_BUF 16 /* how many do we want to buffer */
#undef USE_ASYNC 1
#define DEVICE_NAME "s3c2410-ts"
#define TSRAW_MINOR 1
typedef struct {
unsigned int penStatus; /* PEN_UP, PEN_DOWN, PEN_SAMPLE */
TS_RET buf[MAX_TS_BUF]; /* protect against overrun */
unsigned int head, tail; /* head and tail for queued events */
wait_queue_head_t wq;
spinlock_t lock;
#ifdef USE_ASYNC
struct fasync_struct *aq;
#endif
#ifdef CONFIG_PM
struct pm_dev *pm_dev;
#endif
} TS_DEV;
static TS_DEV tsdev;
#define BUF_HEAD (tsdev.buf[tsdev.head])
#define BUF_TAIL (tsdev.buf[tsdev.tail])
#define INCBUF(x,mod) ((++(x)) & ((mod) - 1))
static int tsMajor = 0;
static void (*tsEvent)(void);
#define HOOK_FOR_DRAG
#ifdef HOOK_FOR_DRAG
#define TS_TIMER_DELAY (HZ/100) /* 10 ms */
static struct timer_list ts_timer;
#endif
static int adc_state = 0;
static int x, y; /* touch screen coorinates */
static void tsEvent_raw(void)
{
if (tsdev.penStatus == PEN_DOWN) {
BUF_HEAD.x = x;
BUF_HEAD.y = y;
BUF_HEAD.pressure = PEN_DOWN;
#ifdef HOOK_FOR_DRAG
ts_timer.expires = jiffies + TS_TIMER_DELAY;
add_timer(&ts_timer);
#endif
} else {
#ifdef HOOK_FOR_DRAG
del_timer(&ts_timer);
#endif
BUF_HEAD.x = 0;
BUF_HEAD.y = 0;
BUF_HEAD.pressure = PEN_UP;
}
tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF);
wake_up_interruptible(&(tsdev.wq));
#ifdef USE_ASYNC
if (tsdev.aq)
kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);
#endif
#ifdef CONFIG_PM
pm_access(tsdev.pm_dev);
#endif
}
static int tsRead(TS_RET * ts_ret)
{
spin_lock_irq(&(tsdev.lock));
ts_ret->x = 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: %08d\n", 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 Interrupt\n");
DPRINTK("SUBSRCPND = 0x%08lx\n", 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 Interrupt\n");
DPRINTK("SUBSRCPND = 0x%08lx\n", 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: %08d\n", 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 < 0) {
printk(DEVICE_NAME " can't get major number\n");
return ret;
}
tsMajor = ret;
/* set gpio to XP, YM, YP and YM */
set_gpio_ctrl(GPIO_YPON);
set_gpio_ctrl(GPIO_YMON);
set_gpio_ctrl(GPIO_XPON);
set_gpio_ctrl(GPIO_XMON);
ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT,
DEVICE_NAME, s3c2410_isr_adc);
if (ret) goto adc_failed;
ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT,
DEVICE_NAME, s3c2410_isr_tc);
if (ret) goto tc_failed;
/* Wait for touch screen interrupts */
wait_down_int();
tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT,
s3c2410_ts_pm_callback);
#endif
printk(DEVICE_NAME " initialized\n");
return 0;
tc_failed:
free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);
adc_failed:
return ret;
}
static void __exit s3c2410_ts_exit(void)
{
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_tsraw);
devfs_unregister(devfs_ts_dir);
#endif
unregister_chrdev(tsMajor, DEVICE_NAME);
#ifdef CONFIG_PM
pm_unregister(tsdev.pm_dev);
#endif
free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);
free_irq(IRQ_TC, s3c2410_isr_tc);
}
module_init(s3c2410_ts_init);
module_exit(s3c2410_ts_exit);
问题点数:20、回复次数:9Top
1 楼LinHanLao(凌寒)回复于 2004-08-05 09:47:54 得分 5
你必须在你的驱动程序里用devfs_register()注册一个/dev/s3c2410-ts,
或者用mknod直接建立一个,<ldd2>上有详细的说明,去看看。Top
2 楼syncrow(天天)回复于 2004-08-05 11:08:02 得分 0
谢谢,我已经找到了在dev的文件夹下找到的!谢谢你的关注Top
3 楼syncrow(天天)回复于 2004-08-05 11:33:57 得分 0
我把应用程序的
main()
{
int buf[10];
int fd = open("/dev/touchscreen",0);
if(-1==fd)
printf("Can't open TS!");
while(1)
{
read( fd,buf,10);
for( int i=0; i<10;i++)
printf('buf[%d]= %d\n",i,buf[i]);
}
}
这样就可以访问触摸屏了,但是在运行的时候输出的总是那一段数据(10个),不断的重复,我都没有接触触摸屏.
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;
}
程序里面可以看出,如果没有接触触摸屏的话,应该是要等待循环(goto retry);不应该不停的输出的呀!
(在没有接上硬件的时候也可以输出数据而且和接了硬件后输出的数据是一样的,请帮我看看
!!Top
4 楼syncrow(天天)回复于 2004-08-05 11:35:18 得分 0
我把应用程序的
main()
{
int buf[10];
int fd = open("/dev/touchscreen",0);
if(-1==fd)
printf("Can't open TS!");
while(1)
{
read( fd,buf,10);
for( int i=0; i<10;i++)
printf('buf[%d]= %d\n",i,buf[i]);
}
}
这样就可以访问触摸屏了,但是在运行的时候输出的总是那一段数据(10个),不断的重复,我都没有接触触摸屏.
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;
}
程序里面可以看出,如果没有接触触摸屏的话,应该是要等待循环(goto retry);不应该不停的输出的呀!
(在没有接上硬件的时候也可以输出数据而且和接了硬件后输出的数据是一样的,请帮我看看
!!Top
5 楼freasy(崔沙)回复于 2004-08-05 12:11:45 得分 5
你看看read的返回值呢?Top
6 楼freasy(崔沙)回复于 2004-08-05 12:12:45 得分 0
看看这个值是不是由你的驱动程序返回的,也许你的操作错误,使得你的请求没到达你的驱动程序就由操作系统检查出非法,就直接返回了Top
7 楼syncrow(天天)回复于 2004-08-05 14:47:56 得分 0
是的,我试过read的返回值是-1,看一个数据是否是驱动程序返回的方法是什么?请相告!谢谢!Top
8 楼zhjie374(zhjie374)回复于 2004-08-10 15:05:05 得分 5
看看read的返回值!!!Top
9 楼wfwater(淡水)回复于 2004-08-11 13:19:19 得分 5
assize_t read(int fields,void *buff,size_t nbytes);
返回:读到的字节数,若已经到达文件尾为0,若出错为-1Top




