編譯環境: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、運行程序,依次循環點亮