666666 有深度!
:lol你的支持,我进步的动力
满月 发表于 2015-11-11 20:32 static/image/common/back.gif
666666 有深度!
:lol你的支持,我进步的动力
本帖最后由 简单侶途 于 2015-11-13 16:09 编辑
期待大家的不断改进我的代码!!{:soso_e100:}
满月 发表于 2015-11-11 20:32 static/image/common/back.gif
666666 有深度!
多谢支持,希望你也来共享点资源啊,求学艰苦!:'(
本帖最后由 简单侶途 于 2015-11-13 16:12 编辑
第五个程序目的是控制不同的LED实现方法是利用程序里面申请主设备号:
major = register_chrdev(0, "led", &leddrv_fops);
利用自动分配申请的major主设备号,接着利用major下自我分配利用的次设备号实现匹配同一类的不同minor,系统自动分配完major后,默认分配次设备号minor = 0,接着我们就在minor那里作文章了,minor使用范围是0~255
这个minor就可以让我们识别同一类设备类下的不同led设备节点
下图所示:242为major,242后面的0,1,2就是minor了
1.驱动程序部分:#include<linux/fs.h>
#include<linux/module.h>
#include<linux/errno.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/cdev.h>
#include<linux/uaccess.h>
#include<linux/device.h>
#include<linux/types.h>
#include <asm/gpio.h>
#include <linux/gpio.h>
#include <plat/sys_config.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/moduleparam.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/ipmi.h>
#include <linux/mutex.h>
#include <linux/compat.h>
/*两种方法寻找GPIO寄存器地址*/
//#define PIO_BASE 0x01C20800
#define PH_BASE (PIO_BASE + 7*0x24)
#define PH_CFG2 (PH_BASE + 0x08)
#define PH_DAT (PH_BASE + 0x10)
//#define PH_BASE(PIO_BASE + 0xFC)
//#define PH_CFG2(PIO_BASE + 0x104)
//#define PH_DAT (PIO_BASE + 0X10C)
static volatile unsigned int *ph_cfg2;
static volatile unsigned int *ph_dat;
//设备类
static struct class *leddrv_class;
//分配 cdev
static struct class_device *leddrv_class_dev;
//主设备号
static int major;
static int led_open(struct inode *inode, struct file *file)
{
/*bit20,bit21
*open the roange_led and blue_led GPIO output
*Output is 001
*/
*ph_cfg2 &= ~((7<<16) | (7<<20));//清零000,这个步骤很重要,注释掉可以看下效果如何blue_led不能控制了
*ph_cfg2 |= ((1<<16) | (1<<20));//设置001
return 0;
}
static ssize_t led_write (struct file *file,char __user *buf,
size_t count,loff_t *f_pos)
{
int val;
int minor = MINOR(file->f_dentry->d_inode->i_rdev);
/*1.从用户空间读取数据到内核空间*/
copy_from_user(&val,buf,4);
/*2.判断传入值val,进行GPIO电平控制*/
switch (minor){
case 0: /*/dev/leds*/
{
if(val == 1)
*ph_dat |= ((1<<20) | (1<<21));
else
*ph_dat &= ~((1<<20) | (1<<21));
}
break;
case 1:/*/dev/led1*/
{
if(val == 1)
*ph_dat |= (1<<20);
else
*ph_dat &= ~(1<<20);
}
break;
case 2: /*/dev/led2*/
{
if(val == 1)
*ph_dat |=(1<<21);
else
*ph_dat &=~(1<<21);
}
break;
}
return 0;
}
//分配驱动操作
static struct file_operations leddrv_fops = {
.owner = THIS_MODULE,
.open = led_open,
.write = led_write,
};
static intled_init(void)
{
int minor = 0;
ph_cfg2 = ioremap(PH_CFG2, 4);
ph_dat= ioremap(PH_DAT, 4);
major = register_chrdev(0, "led", &leddrv_fops);
leddrv_class = class_create(THIS_MODULE, "led");
leddrv_class_dev = device_create(leddrv_class, NULL, MKDEV(major, 0), NULL, "led0"); /* /dev/ledwht */
for(minor=1;minor<3;minor ++)
leddrv_class_dev = device_create(leddrv_class, NULL, MKDEV(major, minor), NULL,
return 0;
}
static void led_exit(void)
{
int minor;
unregister_chrdev(major,"led");
/*2.删除设备节点*/
for(minor = 0; minor<3; minor++)
device_destroy(leddrv_class, MKDEV(major, minor));
class_destroy(leddrv_class);
iounmap(ph_cfg2);
iounmap(ph_dat);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
2.应用程序部分:#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
/*测试方法
*/led_test on
*/led_test off
*/
int main(int argc, char *argv[])
{
int fd;
int val = 1;
char* filename;
if (argc != 3) {
printf("usage:\n%s </dev/led?> <on|off>\n", argv);
return 0;
}
filename = argv;
fd = open(filename, O_RDWR);
if (fd < 0) {
printf("open led failed.\n");
return 0;
}
if (strcmp(argv, "on") == 0) {
//开灯
val = 1;
}
else if (strcmp(argv, "off") == 0) {
//关灯
val = 0;
}
write(fd, &val, 4);
return 0;
}
3.show图ing
操作步骤如下
LED操作显示
赞认真学习的态度
楼主 我编译bin2fex fex2bin的时候为什么报错呢
/opt/sunxi-tools/fel.c:1328: undefined reference to `libusb_strerror'
提示这个未定义 我下载的官网文件啊
页:
1
[2]