基于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号!

     

时间: 2024-11-29 15:26:51

基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号的相关文章

Linux驱动开发必看详解神秘内核(完全转载)

Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html   IT168 技术文档]在开始步入Linux设备驱动程序的神秘世界之前,让我们从驱动程序开发人员的角度看几个内核构成要素,熟悉一些基本的内核概念.我们将学习内核定时器.同步机制以及内存分配方法.不过,我们还是得从头开始这次探索之旅.因此,本章要先浏览一下内核发出的启动信息,然后再逐个讲解一些有意思的点. 2.1 启动过程 图2-1显示

【ARM】Linux驱动移植

1驱动模块移植过程 1模块的第一种编译方法改kconfig 2模块的第二种编译方法Makefile 2Linux驱动原理 0从哪里切入 1什么是注册 2register_chrdev提交哪些数据 21设备号为什么是231 22设备名随便给 23文件操作结构体怎么设置 什么是THIS_MODULE Opencloseread这些都好理解 3register_chrdev返回什么 31 简洁而高效的goto 32 还记得什么是三目运算符吗 33 返回0表示什么 34 什么情况下返回cd-major

《Android深度探索(卷1):HAL与驱动开发》——1.5节如何学习Linux驱动开发

1.5 如何学习Linux驱动开发 Android深度探索(卷1):HAL与驱动开发 由于Linux的内核版本更新较快(稳定版本1至3月更新一次,升级版本1至2周更新一次),每一次内核的变化就意味着Linux驱动的变化(就算不需要修改驱动代码,至少也得在新的Linux内核版本下重新编译),所以Linux内核的不断变化对从事Linux驱动开发的程序员影响比较大.不过这对于学习Linux驱动开发来说影响相对较小.因为不管是哪个版本的Linux内核,开发Linux驱动的方法和步骤基本相同,只要掌握了一

红帽-台式机x64 架构linux 驱动开发的安装问题

问题描述 台式机x64 架构linux 驱动开发的安装问题 我们知道Linux下的驱动开发可以静态加载也可以动态加载的.本人想在台式机上面的小红帽 下静态安装驱动.每次动态加载太费事了,但是貌似没有嵌入式Linux 下面的简单.有哪些方法可以实现系统自动加载,难道只有修改启动脚本么? 请大牛不吝赐教!跪拜!三客优! 解决方案 自己编译一个系统内核吧,这样想怎么弄就怎么弄了 或者查阅红帽的开发手册,看看有木有说明 解决方案二: 谢谢,网上可以下载到红帽的内核么 台式机上面怎么放系统里面启动呢? 解

linux驱动开发-linux驱动模块加载不成功调试过程

问题描述 linux驱动模块加载不成功调试过程 版本:linux2.6.30 问题出现的过程: 1,我在Ubuntu环境下编译驱动模块 2,编译成功后,在板子上insmod出现了 embest_led: version magic '2.6.30 mod_unload modversions ARMv5 ' should be '2.6.30 preempt mod_unload ARMv5 ' insmod: error inserting 'embest_led.ko': -1 Invali

android开发中获取手机上可用SD卡方法分享

现在的android手机型号复杂多样,造成了开发过程中使用官方的获取sd卡的方法在部分的手机上并不适用,所以需要进行开发的自己封装,以下就是代码,希望分享出来,大家共同学习 /*** 获取手机sd卡的工具类* @author wy*/public class SDCardUtils {/** avoid initializations of tool classes*/private SDCardUtils() {// TODO Auto-generated constructor stub}

linux驱动开发--字符设备:自动创建设备节点

自动创建设备文件 定义在<linux/device.h>中 class结构:该结构体类型变量对应一个设备类,被创建的类存放在/sys目录下面 device结构:该结构体类型变量对应设备,被创建的设备存放于/sys目录下面 在加载驱动模块时,用户空间中的udev会自动响应device_create()函数,在/sys下寻找对应的类,从而为这个设备在/dev目录下创建设备文件 内核版本问题: 在内核2.4版本中使用devfs_register 在内核2.6早起版本中使用class_device_r

linux驱动开发--字符设备:通过cdd_cdev结构中的led变量区分是哪个节点,private_data使用

private_data改进 为设备驱动支持多个设备个体做准备,针对private_data进行改进 在设备打开操作中通过inode中保存的i_cdev获取代表当前设备的cdev对象 通过代表当前设备的cdev对象得到包含该对象的设备私有数据结构体 将设备私有数据结构体指针保存到struct file的private_data成员中 在其它设备操作中直接使用保存在struct file的private_date成员中的当前设备私有数据结构体 /** *Copyright (c) 2013.Tia

linux驱动开发--字符设备:静态分配设备号

字符设备(char device)         采用字节流方式访问的设备称为字符设备,通常智能采用顺序访问方式,也有极少数可以前后移动访问指针的设备(如:帧捕捉卡等设备).系统标准字符设备,例如:字符中断.串口等设备.常见待开发设备驱动的字符设备,例如:触摸屏.键盘.视频捕捉设备.音频设备等. 设备号 主设备号     用于标识设备类型,内核代码根据该号码对应设备文件和对应的设备驱动程序 次设备号     用于标识通类型的不同设备个体,驱动程序根据该号码辨别具体操作的是哪个设备个体. 设备号