编译环境:ubuntu Kylin 14.04 LTS
编译工具:gcc-4.4.4-glibc-2.11.1-multilib-1.0_EasyARM-iMX283.tar.bz2
测试硬件:EasyARM-iMX283A AP-283Demo扩展板
1、通过AP-283Demo数据手册查询到要点亮的四个LED所对应的GPIO并短接扩展板的J8A与J8C管脚
2、编写LED的驱动,驱动这里时参照资料包里led驱动编写,目前只了解大概意思,说不出个所以然来,所以直接贴代码:
代码只是例程代码复制了四份修改了下函数名
//#define LED_GPIO MXS_PIN_TO_GPIO(PINID_LCD_D23) //for 283 287A/B
#define LED1_GPIO MXS_PIN_TO_GPIO(PINID_SAIF1_SDATA0) //for 283 287A/B
#define LED2_GPIO MXS_PIN_TO_GPIO(PINID_SAIF0_BITCLK) //for 283 287A/B
#define LED3_GPIO MXS_PIN_TO_GPIO(PINID_SAIF0_MCLK) //for 283 287A/B
#define LED4_GPIO MXS_PIN_TO_GPIO(PINID_SSP0_DATA7) //for 283 287A/B
static int gpio_open(struct inode *inode, struct file *filp);
static int gpio_release(struct inode *inode, struct file *filp);
ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos);
static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg);
static int gpio_init(void);
static void gpio_exit(void);
/*--------------------------------------------------------------------------------------------------------
*/
// led1 func
static int gpio_open(struct inode *inode, struct file *filp){
gpio_request(LED1_GPIO, "imx283_led");
return 0;
}
static int gpio_release(struct inode *inode, struct file *filp){
gpio_free(LED1_GPIO);
return 0;
}
ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos){
char data[2];
copy_from_user(data, buf, count);
gpio_direction_output(LED1_GPIO, data[0]);
return count;
}
static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg){
int data;
switch (command) {
case 0:
gpio_direction_output(LED1_GPIO, 0);
break;
case 1:
gpio_direction_output(LED1_GPIO, 1);
break;
}
return 0;
}
static struct file_operations gpio_fops1={
.owner = THIS_MODULE,
.open = gpio_open,
.write = gpio_write,
.release = gpio_release,
.ioctl = gpio_ioctl,
};
// led2 func
static int gpio_open2(struct inode *inode, struct file *filp){
gpio_request(LED2_GPIO, "imx283_led");
return 0;
}
static int gpio_release2(struct inode *inode, struct file *filp){
gpio_free(LED2_GPIO);
return 0;
}
ssize_t gpio_write2(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos){
char data[2];
copy_from_user(data, buf, count);
gpio_direction_output(LED2_GPIO, data[0]);
return count;
}
static int gpio_ioctl2(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg){
int data;
switch (command) {
case 0:
gpio_direction_output(LED2_GPIO, 0);
break;
case 1:
gpio_direction_output(LED2_GPIO, 1);
break;
}
return 0;
}
static struct file_operations gpio_fops2={
.owner = THIS_MODULE,
.open = gpio_open2,
.write = gpio_write2,
.release = gpio_release2,
.ioctl = gpio_ioctl2,
};
// led3 func
static int gpio_open3(struct inode *inode, struct file *filp){
gpio_request(LED3_GPIO, "imx283_led");
return 0;
}
static int gpio_release3(struct inode *inode, struct file *filp){
gpio_free(LED3_GPIO);
return 0;
}
ssize_t gpio_write3(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos){
char data[2];
copy_from_user(data, buf, count);
gpio_direction_output(LED3_GPIO, data[0]);
return count;
}
static int gpio_ioctl3(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg){
int data;
switch (command) {
case 0:
gpio_direction_output(LED3_GPIO, 0);
break;
case 1:
gpio_direction_output(LED3_GPIO, 1);
break;
}
return 0;
}
static struct file_operations gpio_fops3={
.owner = THIS_MODULE,
.open = gpio_open3,
.write = gpio_write3,
.release = gpio_release3,
.ioctl = gpio_ioctl3,
};
// led4 func
static int gpio_open4(struct inode *inode, struct file *filp){
gpio_request(LED4_GPIO, "imx283_led");
return 0;
}
static int gpio_release4(struct inode *inode, struct file *filp){
gpio_free(LED4_GPIO);
return 0;
}
ssize_t gpio_write4(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos){
char data[2];
copy_from_user(data, buf, count);
gpio_direction_output(LED4_GPIO, data[0]);
return count;
}
static int gpio_ioctl4(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg){
int data;
switch (command) {
case 0:
gpio_direction_output(LED4_GPIO, 0);
break;
case 1:
gpio_direction_output(LED4_GPIO, 1);
break;
}
return 0;
}
static struct file_operations gpio_fops4={
.owner = THIS_MODULE,
.open = gpio_open4,
.write = gpio_write4,
.release = gpio_release4,
.ioctl = gpio_ioctl4,
};
static struct miscdevice gpio_miscdev1 = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME1,
.fops = &gpio_fops1,
};
static struct miscdevice gpio_miscdev2 = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME2,
.fops = &gpio_fops2,
};
static struct miscdevice gpio_miscdev3 = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME3,
.fops = &gpio_fops3,
};
static struct miscdevice gpio_miscdev4 = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME4,
.fops = &gpio_fops4,
};
static int __init gpio_init(void)
{
misc_register(&gpio_miscdev1);
misc_register(&gpio_miscdev2);
misc_register(&gpio_miscdev3);
misc_register(&gpio_miscdev4);
return 0;
}
static void __exit gpio_exit(void)
{
misc_deregister(&gpio_miscdev1);
misc_deregister(&gpio_miscdev2);
misc_deregister(&gpio_miscdev3);
misc_deregister(&gpio_miscdev4);
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zhuguojun, ZhiYuan Electronics Co, Ltd.");
MODULE_DESCRIPTION("GPIO DRIVER FOR EasyARM-i.MX28xx");
3、编译生成驱动并加载驱动,led驱动依赖gpio驱动,所以先加载gpio_driver.ko驱动,再加载编译生成的led.ko
查看生成的设备
4、至此可以在程序中对led对应的IO进行open、write 操作
int fd1,fd2,fd3,fd4;
char buf[1] = {0};
fd1 = open("/dev/imx283_led1", O_RDWR);
fd2 = open("/dev/imx283_led2", O_RDWR);
fd3 = open("/dev/imx283_led3", O_RDWR);
fd4 = open("/dev/imx283_led4", O_RDWR);
printf("fd = %d-%d-%d-%d\n",fd1,fd2,fd3,fd4);
if (!(fd1 && fd2 && fd3 && fd4 )) {
perror("open /dev/imx283_led*");
}
printf("test write....\n");
if(fd1 && fd2 && fd3 && fd4){
buf[0] = 0;
write(fd1, buf, 1);
write(fd2, buf, 1);
write(fd3, buf, 1);
write(fd4, buf, 1);
while(1){
buf[0] = 1; //true on led1
write(fd1, buf, 1);
sleep(1);
buf[0] = 0; //true off led1
write(fd1, buf, 1);
buf[0] = 1; //rue on led2
write(fd2, buf, 1);
sleep(1);
buf[0] = 0; //true off led2
write(fd2, buf, 1);
buf[0] = 1; //rue on led3
write(fd3, buf, 1);
sleep(1);
buf[0] = 0; //true off led3
write(fd3, buf, 1);
buf[0] = 1; //rue on led4
write(fd4, buf, 1);
sleep(1);
buf[0] = 0; //rue off led4
write(fd4, buf, 1);
}
}
printf("test ioctl..... \n");
ioctl(fd1, 0);
sleep(2);
ioctl(fd1, 1);
}
5、运行程序,依次循环点亮