Tiny6410_LED驱动程序_手动分配主设备号+手动创建设备节点


1. 查看原理图

 

 

 

 

2.查询tiny6410芯片手册

 

 

 

LED1---à GPK4

LED2---à GPK5

LED3---à GPK6

LED4---à GPK7

 

下面还需要3个步骤:

1、设置GPIOOUTPUT

    GPK4GPK5GPK6GPK7设置为输出output=0001

     GPKCON0 [19:16]配置为0001  GPKCON0 [23:20]配置为0001

GPKCON0 [27:24]配置为0001   GPKCON0 [28:31]配置为0001

 

2、设置GPIO的数据。

   GPKDATA4:7位赋值为0

GPKDATA[4] = 01   GPKDATA[5] = 01

GPKDATA[6] = 01   GPKDATA[7] = 01

 

3、设置GPKUP为上拉。

   GPKUP4:7位设置为10

GPKUP [4] = 1   GPKUP [5] = 1

GPKUP [6] = 1  GPKUP [7] = 1

(也可以不用设置)

 

led_drv.c

 

#include <linux/init.h>			/* For __init/__exit/... */
#include <linux/kernel.h>		/* For printk/panic/... */
#include <linux/module.h>		/* For module specific items */
#include <linux/fs.h>			/* For file operations */
#include <linux/types.h>		/* For standard types (like size_t) */
#include <linux/errno.h>		/* For the -ENODEV/... values */
#include <linux/ioport.h>		/* For io-port access */
#include <linux/uaccess.h>		/* For copy_to_user/put_user/... */
#include <linux/io.h>			/* For inb/outb/.../ioremap/... */


#define GPKCON_PA  (0x7F008800)
#define GPKDAT_PA  (0x7F008808)

static int major = 243; /* 首先在开发板上,使用命令cat /proc/devices 查看空余的主设备号*/
static volatile unsigned long *gpkcon = NULL;
static volatile unsigned long *gpkdat = NULL;

static int led_open(struct inode *inode, struct file *file)
{	
	return 0;  
}

/* buf[0] - which led
 *          0 -   GPK4
 *          1 -   GPK5
 *          2 -   GPK6
 *          3 -   GPK7
 * buf[1] - 0:on / 1:off */
static ssize_t led_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	char which;
	char status;
	
	char ker_buf[2];

	copy_from_user(ker_buf, buf, 2);
	which = ker_buf[0];
	status   = ker_buf[1];


	if (which < 0 || which > 3)
	{
		printk("No led%d.\n", (which+1));
		return -EINVAL;
	}
	else
	{	
		printk("led%d, status = %s\n", (which+1), status?("off"):("on"));

		if (status)
			*gpkdat |=  (1<<(which+4));
		else
			*gpkdat &= ~(1<<(which+4));
			
	}
	
	return 2;
}

static int led_release (struct inode *inode, struct file *filp)  
{  
	return 0;  
}

static struct file_operations led_fops = {
	.owner 		= THIS_MODULE,
	.open  		= led_open,
	.write 		= led_write,
	.release 	= led_release,
};

static int led_init(void)
{
	int ret;
	ret = register_chrdev(major, "led", &led_fops);
	if(ret < 0)
	{
		printk("register failed!\n"); 
		return ret;
	}
	
	printk("register char dev successful!\n"); /* 如果没有打印,使用$ dmesg | grep register */
	
	/* 获取对应的虚拟地址 */
	gpkcon = ioremap(GPKCON_PA, 4);
	gpkdat = ioremap(GPKDAT_PA, 4);
	
	/* 配置为输出 */
	*gpkcon &= ~(0xffff<<16);
	*gpkcon |= 0x1111<<16;
	
	/* 熄灭4个led */
	*gpkdat |= (0x1<<4|0x1<<5|0x1<<6|0x1<<7);
	
	return ret;
}

static void led_exit(void)
{
	/* 点亮4个led */
	*gpkdat &= ~(0x1<<4|0x1<<5|0x1<<6|0x1<<7);
	
	iounmap(gpkcon);
	iounmap(gpkdat);
	
	unregister_chrdev(major, "led");
	printk("unregister char dev successful!\n");
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");



led_app.c

 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

/* led_test <which> <on|off> */

void print_usage(char *file)
{
	printf("Usage: \n");
	printf("%s <0 | 1 | 2 | 3> <on | off>\n", file);
}

int main(int argc, char* argv[])
{
	char buf[2];
	int  fd;
	int  len;

	if (argc != 3)
	{
		print_usage(argv[0]);
		return -1;
	}

	fd = open("/dev/my_led", O_RDWR);
	if (fd < 0)
	{	
		printf("Open error!\n");
		exit(-1);
	}
	
	buf[0] = strtoul(argv[1], NULL, 0);
	if (strcmp(argv[2], "on") == 0)
	{	
		buf[1] = 0;
	}
	else if(strcmp(argv[2], "off") == 0)
	{	
		buf[1] = 1;
	}
	else
	{
		print_usage(argv[0]);
		return -1;
	}

	write(fd, buf, 2);
	
	close(fd);
	
	return 0;
}


Makefile

 

KERNELDIR = /sdb/kernel/linux-2.6.38-tiny6410/linux-2.6.38/
PWD := $(shell pwd)

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

.PHONY: modules  clean

obj-m := led_drv.o


编译没有问题,就可以下到板子测试了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 报错信息"Could NOT find TinyXml (missing: TINYXML_LIBRARIES TINYXML_INCLUDE_DIR)"表示找不到TinyXml库。为了解决这个问题,你可以按照以下步骤进行操作: 1. 首先,确保你已经安装了TinyXml库的依赖库。你可以使用以下命令安装缺失的依赖库: ``` apt-get install libtinyxml-dev ``` 2. 如果你已经安装了TinyXml库的依赖库,但仍然出现问题,你可以尝试手动定义TinyXml库的环境变量。你可以在CMakeList.txt文件中添加以下内容: ``` set(TINYXML_LIBRARIES /path/to/tinyxml/lib) set(TINYXML_INCLUDE_DIR /path/to/tinyxml/include) ``` 请确保将"/path/to/tinyxml/lib"和"/path/to/tinyxml/include"替换为实际的TinyXml库的路径。 3. 如果以上步骤都没有解决问题,你可以尝试重新编译TinyXml库。你可以按照以下步骤进行操作: - 下载TinyXml库的源代码。 - 进入TinyXml库的源代码目录。 - 执行以下命令进行编译和安装: ``` make make install ``` 请注意,这些步骤可能因为你的具体环境而有所不同。如果你仍然遇到问题,建议查阅TinyXml库的官方文档或者寻求相关技术支持。 #### 引用[.reference_title] - *1* [Could NOT find LibXml2 (missing: LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)Call Stack](https://blog.csdn.net/quantum7/article/details/127092600)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [TinyXML2(学习记录)](https://blog.csdn.net/qq_34709554/article/details/129937874)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [在Ubuntu上编译QGIS 3.6.*-3.10.* 代码的填坑笔记](https://blog.csdn.net/DanyelleG/article/details/106454423)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值