基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
每个CPU,都有它固定的ID号,ID号就是这个CPU唯一的标识,它可能隐含着CPU的生产日期,版本号,型号等等,那么,在我们的这款友善之臂Tiny4412的板子上,我的这个CPU的ID又是多少呢?从我在光盘里拿到的linux-3.5内核其实已经将ID相关的驱动开发好了,我们在内核启动的过程中就可以看到板子CPU的ID:
看下图,我们看到CPU EXYNOS4412 (Id 0xe4412011)。这个就是我板子上CPU的ID号。其它跟我相同的板子,虽然CPU也是相同的,但是板子的ID号会不一样,不信可以试试
那么,现在我不加载linux-3.5这个内核上的ID,我自己写一个驱动程序来将这个ID读出来,能否实现?
验证结果:如果我写的驱动程序读出来的ID和linux内核3.5启动过程中的ID:0xe4412011相同的话,那么就证明我读对了。
好,我们来看看具体如何来实现这个驱动程序。
还是一样的,和以前的步骤相同,但是这里的话就不用看电路图了,因为ID号是CPU内部的,我们只需要去看手册配置寄存器就可以得到相应的ID号了。
1、看手册
从手册上看到,大概的意思就是,如果要读出CPU的ID号,那么就需要先把PRO_ID的物理地址映射为虚拟地址,然后再读PRO_ID即可得到CPU的ID号。
接下来来看看驱动程序如何编写:
2、编写驱动程序
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/io.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #define DEV_NAME "test-dev" //板子ID的物理地址 #define PRO_ID 0x10000000 //定义一个虚拟地址变量 unsigned int *virtul = NULL ; //open方法,不需要实现 int id_open(struct inode *inode, struct file *filp) { printk("id_open\n"); return 0; } //read方法,实现虚拟地址的返回 ssize_t id_read(struct file *file , char __user *buf ,size_t size ,loff_t *offset) { printk("id_read\n"); if(size < 4){ return -1 ; } //将虚拟地址转化为32位整型数 return ioread32(virtul); } struct file_operations fops = { .owner = THIS_MODULE , .open = id_open, .read = id_read, }; int major ; int test_init(void) { printk("id_init\n"); //注册设备 major = register_chrdev(major, DEV_NAME, &fops); //虚拟地址映射 virtul = ioremap(PRO_ID , 4); //判断是否为空或出现错误,如果出现返回-1 if(IS_ERR_OR_NULL(virtul)) { return -1 ; } return 0; } void test_exit(void) { printk("id_exit\n"); //注销设备 unregister_chrdev(major, DEV_NAME); //取消映射 iounmap(virtul); } module_init(test_init); module_exit(test_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Y.X.YANG"); MODULE_VERSION("2016.1.16");
3、编写测试程序
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char **argv) { int fd; unsigned int id_val = 0 ; char id_buf[4] = {0}; fd = open("/dev/test-dev",O_RDWR) ; if(-1 == fd) { printf("open fair!\n"); return -1 ; } //获取ID的值 id_val = read(fd , id_buf , 4); //以地址的形式打印 printf("id_val = %p\n",id_val); return 0; }
4、makefile(略)
5、编译
6、插入模块,显示模块,查看主设备号,创建设备节点(略)
7、运行结果:
果然,读出来的ID号正是内核启动时的ID:CPU EXYNOS4412 (Id 0xe4412011) .
驱动验证成功!成功获取板子CPU_ID号!
基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号的更多相关文章
- 如何获取板子上独有的ID号EXYNOS4412/Imx6ul【转】
本文转载自:http://blog.csdn.net/u010871058/article/details/75637175 每个CPU,都有它固定的ID号,ID号就是这个CPU唯一的标识,它可能隐含 ...
- Linux 驱动开发
linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...
- Linux驱动开发必看详解神秘内核(完全转载)
Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html IT168 技术文档]在开始步入L ...
- 浅析基于ARM的Linux下的系统调用的实现
在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的. t8.c 1: #include <stdio.h> ...
- Linux内核(17) - 高效学习Linux驱动开发
这本<Linux内核修炼之道>已经开卖(网上的链接为: 卓越.当当.china-pub ),虽然是严肃文学,但为了保证流畅性,大部分文字我还都是斟词灼句,反复的念几遍才写上去的,尽量考虑到 ...
- 嵌入式Linux驱动开发日记
嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...
- 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- 【转】linux驱动开发的经典书籍
原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书 ...
- 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
随机推荐
- Android自定义控件及自定义属性
Android自定义控件及自定义属性 自定义控件 创建自定义控件 自定义一个类,继承View 继承View还是哪个类,取决于你要实现一个什么样的控件 如果你要实现的是一个线性布局的组合控件,就可以继承 ...
- EJB_开发EJB容器模型的WEB服务
开发EJB容器模型的WEB服务 WEB服务 Web服务也是一种分布式技术,它与EJB最大的不同是,Web服务属于行业规范,可以跨平台及语言.而EJB属于Java平台的规范,尽管理论上可以跨平台,但实现 ...
- Android开发之Intent.Action 各种Action的常见作用
1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始.比较常用. Input:nothing Outpu ...
- Spring整合DWR comet 实现无刷新 多人聊天室
用dwr的comet(推)来实现简单的无刷新多人聊天室,comet是长连接的一种.通常我们要实现无刷新,一般会使用到Ajax.Ajax 应用程序可以使用两种基本的方法解决这一问题:一种方法是浏览器每隔 ...
- Android存储之SharedPreferences
Android数据存储之SharedPreferences SharedPreferences对象初始化 SharedPreferences mSharedPreferences = getShare ...
- mysql数据库连接池使用(一)dbcp方式的配置
Apache的数据库连接池 DBCP的常用配置说明,因为项目中用到了需要对其封装,所以必须先了解怎么配置以及各个配置字段的含义,理解的基础上开发我们自己的数据库连接池.可以参考官网dbcp官网. db ...
- 基于V4L2摄像头采集图片程序设计
#ifndef __COMMON_H #define __COMMON_H //该头文件定义的是摄像头在屏幕上显示的宽度和高度 #include<stdio.h> #include< ...
- Java进阶(三十八)快速排序
Java进阶(三十八)快速排序 前言 有没有既不浪费空间又可以快一点的排序算法呢?那就是"快速排序"啦!光听这个名字是不是就觉得很高端呢. 假设我们现在对"6 1 2 7 ...
- RecyclerView下拉刷新上拉加载(一)
listview下拉刷新上拉加载扩展(一) http://blog.csdn.net/baiyuliang2013/article/details/50252561 listview下拉刷新上拉加载扩 ...
- Sybase - tempdb
前沿:换了新公司,公司使用的Sybase数据库.现在开始学习Sybase数据库了.希望未来的几个月能对Sybase由浅入深的了解和研究. Tempdb的作用 sybase server端内部使用 排序 ...