驱动学习5: zynq实现点亮led
驱动代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/irq.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/device.h> //包含了device、class 等结构的定义
#include <asm/io.h> //包含了ioremap、iowrite等内核访问IO内存等函数
#include <linux/uaccess.h> //包含了copy_to_user、copy_from_user等 #define DEVICE_NAME "axiled"
#define CLASS_NAME "zynqebb" /* XGPIO Physical address */
#define XGPIO_PHY_ADDR 0x41200000 //This Address is based SDK
/* Register Offset Definitions */
#define XGPIO_DATA_OFFSET (0x0) /* Data register */
#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ volatile unsigned long *Gpio_DIR = NULL;
volatile unsigned long *Gpio_DATA = NULL; MODULE_AUTHOR("Xilinx ");
MODULE_DESCRIPTION("AXI GPIO moudle dirver");
MODULE_VERSION("v1.0");
MODULE_LICENSE("GPL"); static int axi_gpio_driver_major;
static struct class* axi_gpio_driver_class = NULL;
static struct device* axi_gpio_driver_device = NULL; unsigned long axi_gpio_virt_addr = ; //AXI_GPIO moulde's visual address static ssize_t axi_gpio_write(struct file * file, const char * buf, size_t count,loff_t *off)
{
//printk("axi_gpio_write\n");
int val;
copy_from_user(&val,buf,count);
printk("before Gpio_DATA:%lx,%lx.\n",Gpio_DATA,ioread32(Gpio_DATA)); if(val == )
{
//点灯
//*Gpio_DATA = (unsigned long )0x00000005; //设置AXI GPIO的方向输出全为高
iowrite32(0x0000000F,Gpio_DATA); //设置AXI GPIO的方向输出全为高
}
else
{
//灭灯
iowrite32(0x00000000,Gpio_DATA); //设置AXI GPIO的方向输出全为低
}
printk("after Gpio_DATA:%lx,%lx.\n",Gpio_DATA,ioread32(Gpio_DATA));
return ; } static int axi_gpio_open(struct inode *inode, struct file *filp)
{
//printk("axi_gpio_open\n"); //配置led管脚为输出
printk("before Gpio_DIR:%lx,%lx.\n",Gpio_DIR,ioread32(Gpio_DIR));
//*Gpio_DIR = (unsigned long )0x00000000; //设置AXI GPIO的方向输出
iowrite32(0x00000000,Gpio_DIR); //设置AXI GPIO的方向输出 printk("after Gpio_DIR:%lx,%lx.\n",Gpio_DIR,ioread32(Gpio_DIR)); return ;
} static struct file_operations axi_gpio_fops = {
.owner = THIS_MODULE,
.write = axi_gpio_write,
.open = axi_gpio_open,
}; static int __init axi_gpio_driver_module_init(void)
{
int ret; axi_gpio_driver_major=register_chrdev(, DEVICE_NAME, &axi_gpio_fops );//内核注册设备驱动
if (axi_gpio_driver_major < ){
printk("failed to register device.\n");
return -;
} axi_gpio_driver_class = class_create(THIS_MODULE, CLASS_NAME);//创建设备类
if (IS_ERR(axi_gpio_driver_class)){
printk("failed to create zxi_gpio moudle class.\n");
unregister_chrdev(axi_gpio_driver_major, DEVICE_NAME);
return -;
} axi_gpio_driver_device = device_create(axi_gpio_driver_class, NULL, MKDEV(axi_gpio_driver_major, ), NULL, DEVICE_NAME);
if (IS_ERR(axi_gpio_driver_device)){
printk("failed to create device .\n");
unregister_chrdev(axi_gpio_driver_major, DEVICE_NAME);
return -;
} //To get Custom IP--gpio moudle's virtual address
#if 1
if(request_mem_region(XGPIO_PHY_ADDR, 0x1000,DEVICE_NAME) == NULL ){
printk( "request_mem_region failed\n");
return -;
}
#endif
axi_gpio_virt_addr = (unsigned long)ioremap(XGPIO_PHY_ADDR, sizeof(u32));
//将模块的物理地址映射到虚拟地址上
printk( "ioremap called: phys %#08x -> virt %#08x\n",XGPIO_PHY_ADDR, axi_gpio_virt_addr );
//指定需要操作的寄存器的地址
Gpio_DIR = (unsigned long *)(axi_gpio_virt_addr + XGPIO_TRI_OFFSET);
Gpio_DATA = (unsigned long *)(axi_gpio_virt_addr + XGPIO_DATA_OFFSET); return ;
}
static void __exit axi_gpio_driver_module_exit(void)
{ //撤销映射关系
iounmap((void *)axi_gpio_virt_addr);
#if 1
release_mem_region(XGPIO_PHY_ADDR, 0x1000);
#endif
device_destroy(axi_gpio_driver_class, MKDEV(axi_gpio_driver_major, ));
class_unregister(axi_gpio_driver_class);
class_destroy(axi_gpio_driver_class);
unregister_chrdev(axi_gpio_driver_major, DEVICE_NAME);
printk("axi_gpio module exit.\n");
} module_init(axi_gpio_driver_module_init);
module_exit(axi_gpio_driver_module_exit);
应用层代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> /* firstdrvtest on
* firstdrvtest off
*/
int main(int argc, char **argv)
{
int fd;
int val = ;
fd = open("/dev/axiled", O_RDWR);
if (fd < )
{
printf("can't open!\n");
}
if (argc != )
{
printf("Usage :\n");
printf("%s <on|off>\n", argv[]);
return ;
} if (strcmp(argv[], "on") == )
{
val = ;
}
else
{
val = ;
} write(fd, &val, );
return ;
}
插入模块:
root@plnx_arm:/mnt# insmod mytest.ko
ioremap called: phys 0x41200000 -> virt 0xf09f0000
测试设备号:

运行应用程序:

驱动学习5: zynq实现点亮led的更多相关文章
- zigbee学习之路(二)点亮LED
一.前言 今天,我来教大家如何点亮led,这也是学习开发板最基础的步骤了. 二.原理分析 cc2530芯片跟虽然是51的内核,但是它跟51单片机还是有区别的,51单片机不需要对IO口进行配置,而cc2 ...
- 学习笔记——单片机简介 & 点亮LED & 流水灯 & 电路基础【更新Ing】
视频地址:https://www.bilibili.com/video/av10765766 超详细!!!!!! 单片机内部三大资源 [资源:单片机可提供使用的东西] FLASH 可以重复擦写 断电后 ...
- 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- STM32学习笔记——点亮LED
STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...
- ARM学习篇一 点亮LED
要点亮LED,先决条件是什么,当然得有相应的硬件设施.板子的整个电路图比较大,我就直接取相关部分. 给发光二级管加上3.3v电压后,通过1k电阻,直接与S3C2440连接.至于为什么要加电阻,大家应该 ...
- liunx驱动----点亮LED
自动挂接根文件系统(直接从NFS启动) 修改uboot命令行 把 bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 ...
- JZ2440开发板:用按键点亮LED灯(学习笔记)
本文是对韦东山嵌入式第一期学习的记录之一,如有您需要查找的信息,可以继续往下阅读. 想要用按键点亮LED灯,就需要知道按键和LED灯的相关信息,这样才可以进行之后的操作.阅读JZ2440的原理图,可以 ...
- JZ2440裸机点亮LED【学习笔记】
平台:jz2440 作者:庄泽彬(欢迎转载,请注明作者) 说明:韦东山一期视频学习笔记 一.我们首先来做第一个实验,用汇编语言点亮板子上的LED. 1.1 LED的原理图 从下面的原理图可知LED1是 ...
随机推荐
- 亚马逊6月18日发布惊世之作 或为3D智能手机
亚马逊将在 6 月 18 日举行一个产品发布会. 其内容可能是关于传闻已久的亚马逊智能手机.该公司在 YouTube 上公布了一段炫耀这款设备的视频.这段视频展示了很多人在这款产品前摇头晃脑,并且表现 ...
- CentOS-6.x系列查看cpu核数
使用CentOS7.x使用习惯了后用top命令,然后按1就可以查看相关的cpu核心数等相关信息 相关概念: 物理CPU:实际Server中插槽上的CPU个数. 物理cpu数量:可以数不重复的 phys ...
- 使用coding.net上传项目
鉴于上一次上传托管代码的惨烈教训,痛定思痛,决定把这次使用cooding.net上传的过程记录下来.也算是一篇简单的cooding初级使用教程了. 1.首先在cooding上新建项目 (1)填写项目名 ...
- .NET中的堆(Heap)和栈(Stack)的本质
计算机的内存可以分为代码块内存,Stack内存和Heap内存.代码块内存是在加载程序时存放程序机器代码的地方. 栈(Stack)一般存放函数内的局部变量. 堆(Heap)一般存放全局变量和类对象实例等 ...
- php框架中常用的设计模式
1.单例模式 //单例模式 class Demo { private static $obj; private function __construct() { } private function ...
- 九度-题目1026:又一版 A+B
http://ac.jobdu.com/problem.php?pid=1026 题目描述: 输入两个不超过整型定义的非负10进制整数A和B(<=231-1),输出A+B的m (1 < m ...
- 包装类 integer 当做 list的参数时候 会出现无法删除成功的现象
- 秒杀多线程第七篇 经典线程同步 互斥量Mutex(续)
java使用Synchronized关键字实现互斥,而同时有Lock支持. 这两个的效果是等同的,Synchronized性能的起伏较大,而lock比较收敛. 为了代码的可读性,Synchronize ...
- Day 2 笔记 数据结构
Day 2 笔记 数据结构 1.栈.队列.链表等数据结构都是线性数据结构 2.树状数据结构:二叉堆,线段树,树状数组,并查集,st表... 优先队列其实与二叉堆的存储方式并不相同. 一.二叉堆 1.二 ...
- 算法08 五大查找之:二叉排序树(BSTree)
上一篇总结了索引查找,这一篇要总结的是二叉排序树(Binary Sort Tree),又称为二叉查找树(Binary Search Tree) ,即BSTree. 构造一棵二叉排序树的目的,其实并不是 ...