我用的Tiny6410的核心板,2.6.36的内核,仿照友善的led驱动程序,把GPI2、GPI3,GPI4、GPI5,GPI6、GPI7,GPI10、GPI11,GPI12、GPI13分别作为红绿双色LED的控制端,改写的驱动程序中的ioctl函数如下:
static long status_led_ioctl( struct file *file, unsigned int ledstatus, unsigned long ledno)
{
unsigned tmp;
if (ledno >= 5)
{
return -EINVAL;
}
if (ledno >= 3)
{
ledno += 1;
}
printk("ioctl executed~~~~~~~~~~~~");
if (ledstatus == LED_FAULT)
{
printk("LED_FAULT ledstatus: %d", ledstatus);
tmp = readl(S3C64XX_GPIDAT);
tmp &= ~(1 << (2+ledno*2));
tmp |= (1 << (2+ledno*2+1));
writel(tmp, S3C64XX_GPIDAT);
return 0;
}
if (ledstatus == LED_RUN)
{
printk("LED_RUN ledstatus: %d", ledstatus);
tmp = readl(S3C64XX_GPIDAT);
tmp |= (1 << (2+ledno*2));
tmp &= ~(1 << (2+ledno*2+1));
writel(tmp, S3C64XX_GPIDAT);
return 0;
}
if (ledstatus == LED_OFF)
{
printk("LED_OFF ledstatus: %d", ledstatus);
tmp = readl(S3C64XX_GPIDAT);
tmp |= (1 << (2+ledno*2));
tmp |= (1 << (2+ledno*2+1));
writel(tmp, S3C64XX_GPIDAT);
return 0;
}
return -EINVAL;
}
测试程序主要部分如下:
#define LED_RUN 1
#define LED_FAULT 2
#define LED_OFF 3
static int ledctrlfd;
static void Error(const char *Msg)
{
fprintf (stderr, "%s\n", Msg);
fprintf (stderr, "strerror() is %s\n", strerror(errno));
//exit(1);
}
int main(int argc, char **argv)
{
int iter;
unsigned ledstatus;
ledctrlfd = open(DEVICE_NAME, 0);
if (ledctrlfd < 0)
{
Error(strerror(errno));
return 0;
}
ledstatus = LED_RUN;
for (iter = 0; iter < 5; iter++)
{
printf("ledstatus: %d\n", ledstatus);
if (ioctl(ledctrlfd, ledstatus, iter) != 0)
{
Error(strerror(errno));
}
sleep(1);
}
sleep(1);
ledstatus = LED_OFF;
for (iter = 0; iter < 5; iter++)
{
printf("ledstatus: %d\n", ledstatus);
if (ioctl(ledctrlfd, ledstatus, iter) != 0)
{
Error(strerror(errno));
}
sleep(1);
}
sleep(1);
ledstatus = LED_FAULT;
for (iter = 0; iter < 5; iter++)
{
printf("ledstatus: %d\n", ledstatus);
if (ioctl(ledctrlfd, ledstatus, iter) != 0)
{
Error(strerror(errno));
}
sleep(1);
}
sleep(1);
ledstatus = LED_OFF;
for (iter = 0; iter < 5; iter++)
{
printf("ledstatus: %d\n", ledstatus);
if (ioctl(ledctrlfd, ledstatus, iter) != 0)
{
Error(strerror(errno));
}
sleep(1);
}
sleep(1);
close(ledctrlfd);
return 0;
}
结果就是每次ioctl的ledstatus参数设置为LED_FAULT时,ioctl就出错,错误信息是Bad address
求教各位大侠,这到底是怎么一回事。