IMX257实现GPIO-查询按键驱动程序

发布时间:2024-08-16  

前面我们介绍了简单的通用字符设备驱动程序,接下来,我们在它的基础上来实现GPIO的查询按键功能。

先附上驱动程序代码

 

 

  1 /******************************

  2     linux key_query

  3  *****************************/

  4 #include

  5 #include

  6 #include

  7 #include

  8 #include

  9 #include

 10 #include

 11 #include

 12 #include //包含了用于自动创建设备节点的函数device_create

 13 #include //包含了copy_to_user 函数等

 14 

 15 #include 'mx257_gpio.h'

 16 #include 'mx25_pins.h'

 17 #include 'iomux.h'

 18 

 19 #define Driver_NAME 'key_query'

 20 #define DEVICE_NAME 'key_query'

 21 

 22 #define GPIO2_21    MX25_PIN_CLKO

 23 #define GPIO3_15    MX25_PIN_EXT_ARMCLK

 24 #define GPIO2_10    MX25_PIN_A24

 25 #define GPIO2_11    MX25_PIN_A25

 26 #define GPIO2_8     MX25_PIN_A22

 27 #define GPIO2_9     MX25_PIN_A23

 28 #define GPIO2_6     MX25_PIN_A20

 29 #define GPIO2_7     MX25_PIN_A21

 30 //command

 31 #define key_input     0

 32 #define version        1

 33 //用于保存主设备号

 34 static int major=0;

 35 //用于自动创建设备节点 代替了手动敲mknod命令

 36 //auto to create device node

 37 static struct class *drv_class = NULL;

 38 static struct class_device *drv_class_dev = NULL;

 39 

 40 

 41 /* 应用程序对设备文件/dev/key_query执行open(...)时,

 42  * 就会调用key_open函数*/

 43 static int key_open(struct inode *inode, struct file *file)

 44 {

 45     printk('<0>function open!nn');

 46     

 47     return 0;

 48 }

 49 /*当应用程序中read(fd,buff,sizeof(buff))时调用此key_read函数*/

 50 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

 51 {

 52     int ret;

 53     //nt cnt=0;

 54     unsigned char key_vals[8];

 55     // reading the pins value

 56     key_vals[0] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_6)) ? 1 : 0;

 57     key_vals[1] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_7)) ? 1 : 0;

 58     key_vals[2] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_8)) ? 1 : 0;

 59     key_vals[3] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_9)) ? 1 : 0;

 60     key_vals[4] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_10)) ? 1 : 0;

 61     key_vals[5] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_11)) ? 1 : 0;

 62     key_vals[6] = gpio_get_value(IOMUX_TO_GPIO(GPIO2_21)) ? 1 : 0;

 63     key_vals[7] = gpio_get_value(IOMUX_TO_GPIO(GPIO3_15)) ? 1 : 0;

 64     

 65     ret = copy_to_user(buff,key_vals,sizeof(key_vals));

 66     if(ret){

 67         ;

 68     }

 69     

 70     //printk('<0>%04d key pressed: %d %d %d %d %d %d %d %dn',cnt++,key_vals[0],key_vals[1],key_vals[2],key_vals[3],key_vals[4],key_vals[5],key_vals[6],key_vals[7]); 

 71 

 72     return sizeof(key_vals);

 73 }

 74  /* 当应用程序中使用write函数时,调用此函数**/

 75 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

 76 {

 77     printk('<0>function write!nn');

 78     

 79     return 1;

 80 }

 81 

 82 static int  key_release(struct inode *inode, struct file *filp)

 83 {

 84     printk('<0>function release!nn');

 85     return 0;

 86 }

 87  /* 当用户调用ioctl(fd,version,NULL);时,会进入此函数,

 88   * 在SWITCH中配对command,然后执行相应的语句 

 89   * 注意command 一定为整数,需在前面定义*/

 90 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)

 91 {

 92     printk('<0>function ioctl!nn');

 93     switch (command) {

 94         case key_input:

 95             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_21));

 96             gpio_direction_input(IOMUX_TO_GPIO(GPIO3_15));

 97             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));

 98             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));

 99             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_8));

100             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));

101             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_6));

102             gpio_direction_input(IOMUX_TO_GPIO(GPIO2_7));

103             //设置所有引脚为上拉模式

104             mxc_iomux_set_pad(GPIO2_6, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

105             mxc_iomux_set_pad(GPIO2_7, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

106             //mxc_iomux_set_pad(GPIO2_8, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

107             mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

108             mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

109             mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

110             mxc_iomux_set_pad(GPIO2_21, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

111             //mxc_iomux_set_pad(GPIO3_15, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_22K_PU);

112             break;

113         case version:

114             printk('<0>hello,the version is 0.1.0nn');

115             break;

116         default:

117               printk('<0>command error n');

118             printk('<0>ioctl(fd, (unsigned int)command, (unsigned long) arg;n');

119             printk('<0>command: nn');

120             return -1;

121     }

122     return 0;    

123 }

124 

125 /* 这个结构是字符设备驱动程序的核心

126  * 当应用程序操作设备文件时所调用的open、read、write等函数,

127  * 最终会调用这个结构中指定的对应函数

128  */

129 static struct file_operations key_fops = {

130     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

131     .open   =   key_open,     

132     .read    =    key_read,       

133     .write    =    key_write,       

134     .release=   key_release,

135     .ioctl  =   key_ioctl,    

136 };

137     

138 /*

139  * 执行insmod命令时就会调用这个函数 

140  */

141 static int __init key_init(void)

142 {

143     printk('<0>nHello,this is %s module!nn',Driver_NAME);

144     //register and mknod

145     //注册字符设备,系统会自动分配一个主设备号,保存在major中

146     major = register_chrdev(0,Driver_NAME,&key_fops);

147     //自动在/dev/目录下创建设备节点

148     drv_class = class_create(THIS_MODULE,Driver_NAME);

149     drv_class_dev = device_create(drv_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME);    /*/dev/key_query*/

150 

151     //set all pins to GPIO mod  ALF5

152     //设置所有的GPIO引脚为GPIO功能

153     mxc_request_iomux(GPIO2_21, MUX_CONFIG_ALT5);

154     mxc_request_iomux(GPIO3_15, MUX_CONFIG_ALT5);

155       mxc_request_iomux(GPIO2_10, MUX_CONFIG_ALT5);

156        mxc_request_iomux(GPIO2_11, MUX_CONFIG_ALT5);

157     mxc_request_iomux(GPIO2_8, MUX_CONFIG_ALT5);

158     mxc_request_iomux(GPIO2_9, MUX_CONFIG_ALT5);

159     mxc_request_iomux(GPIO2_6, MUX_CONFIG_ALT5);

160     mxc_request_iomux(GPIO2_7, MUX_CONFIG_ALT5);

161     

162     

163             printk('<0>have setting all pins to gpio input mod !n');

164     //request IOMUX GPIO

165     gpio_request(IOMUX_TO_GPIO(GPIO2_21), 'GPIO2_21');

166      gpio_request(IOMUX_TO_GPIO(GPIO3_15), 'GPIO3_15');

167      gpio_request(IOMUX_TO_GPIO(GPIO2_10), 'GPIO2_10');

168        gpio_request(IOMUX_TO_GPIO(GPIO2_11), 'GPIO2_11');

169     gpio_request(IOMUX_TO_GPIO(GPIO2_8), 'GPIO2_8');

170      gpio_request(IOMUX_TO_GPIO(GPIO2_9), 'GPIO2_9');

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>