linux访问寄存器
1. imx6q linux bsp中怎么读取一个寄存器的值
这一问题来自项目中一个实际的需求:
我需要在Linux启动之后,确认我指定的芯片寄存器是否与我在uboot的配置一致。
举个例子:
寄存器地址:0x20000010负责对DDR2的时序配置,该寄存器是在uboot中设置,现在我想在Linux运行后,读出改寄存器的值,再来检查该寄存器是否与uboot的配置一致。
Linux应用程序运行的是虚拟空间,有没有什么机制可以是完成我提到的这一需求。若行,还请附些测试代码。
谢谢!
这个需要用mmap()函数将寄存器物理地址映射为用户空间的虚拟地址,即将寄存器的那段内存映射到用户空间,函数介绍如下:
void*
mmap(void
*
addr,
size_t
len,
int
prot,
int
flags,
int
fd,
off_t
offset);
该函数映射文件描述符
fd
指定文件的
[offset,
offset
+
len]
物理内存区至调用进程的
[addr,
addr
+
len]
的用户空间虚拟内存区,通常用于内存共享或者用户空间程序控制硬件设备,函数的返回值为最后文件映射到用户空间的地址,进程可直接操作该地址。下面是测试代码(仅供参考):
#define
DDR2_REG_BASE
(0x20000000)
#define
MAP_SIZE
4096UL
#define
MAP_MASK
(MAP_SIZE
-
1)
static
unsigned
int
pTestRegBase;
static
int
dev_fd;
dev_fd
=
open("/dev/mem",
O_RDWR
|
O_NDELAY);
if
(dev_fd
<</SPAN>
0)
{
LOGE("open(/dev/mem)
failed.");
return;
}
pTestRegBase
=
(void
*)mmap(NULL,
MAP_SIZE,
PROT_READ
|
PROT_WRITE,
MAP_SHARED,
dev_fd,DDR2_REG_BASE
&
~MAP_MASK);
if
(MAP_FAILED
==
pTestRegBase)
{
printf("mmap
failed.
fd(%d),
addr(0x%x),
size(%d)\n",
dev_fd,
DDR2_REG_BASE,
MAP_SIZE);
}
else
{
unsigned
int
reg_value
=
*((volatile
unsigned
int
*)(pTestRegBase
+
10));
printf("reg_value
=
0xx\n",
reg_value);
munmap((void*)pTestRegBase,
MAP_SIZE);
}
pTestRegBase
=
0;
if(dev_fd)
close(dev_fd);
这里将DDR2_REG_BASE开始大小为1个page的物理地址映射到了用户空间,然后就可以用pTestRegBase作为起始地址操作寄存器了。
2. linux kernel 怎么读cpu写寄存器 inw
arm裸机下读写寄存器很容易,各个寄存器和内存的地址是单一地址空间,他们是用相同的指令进行读写操作的.而在linux下就要复杂很多,因为linux支持多个体系架构的CPU。比如arm和x86就不一样,具体的差别我暂时也说不上来,这个涉及到CPU体系的设计。目前我只关心:linux为了支持多个硬件体系,在IO访问上做了自己的接口。可以通过IO内存和IO端口这两种方式进行IO访问。在LED的例子上给出这两种方式的具体实现:
1.利用IO Port的方式:
[cpp] view plain
#include <linux/mole.h>
#include <linux/moleparam.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/ioport.h>
#include <mach/regs-gpio.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* _*_user */
#include <asm/io.h>
#define LED_NUM 4
struct led_dev
{
struct cdev dev;
unsigned port;
unsigned long offset;
};
struct led_dev led[4];
dev_t dev = 0;
static struct resource *led_resource;
int led_open(struct inode *inode, struct file *filp)
{
struct led_dev *led; /* device information */
led = container_of(inode->i_cdev, struct led_dev, dev);
filp->private_data = led; /* for other methods */
return 0; /* success */
}
int led_release(struct inode *inode, struct file *filp)
{
return 0;
}
ssize_t led_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
return 0;
}
ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
char data;
struct led_dev *led;
u32 value;
printk(KERN_INFO "debug by kal: led dev write\n");
led = (struct led_dev *)filp->private_data;
_from_user(&data,buf,count);
if(data == '0')
{
printk(KERN_INFO "debug by kal: led off\n");
value = inl((unsigned)(S3C2410_GPBDAT));
outl(value | 1<<led->offset,(unsigned)(S3C2410_GPBDAT));
//value = ioread32(led->base);
//iowrite32( value | 1<<led->offset, led->base);
}
else
{
printk(KERN_INFO "debug by kal: led on\n");
value = inl((unsigned)(S3C2410_GPBDAT));
outl(value & ~(1<<led->offset),(unsigned)(S3C2410_GPBDAT));
//value = ioread32(led->base);
//iowrite32( value & ~(1<<led->offset), led->base);
}
}
struct file_operations led_fops = {
.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
//.ioctl = led_ioctl,
.open = led_open,
.release = led_release,
};
static int led_init(void)
{
int result, i;
result = alloc_chrdev_region(&dev, 0, LED_NUM,"LED");
if (result < 0) {
printk(KERN_WARNING "LED: can't get major %d\n", MAJOR(dev));
return result;
}
led_resource = request_region(0x56000014,0x4,"led");
if(led_resource == NULL)
{
printk(KERN_ERR " Unable to register LED I/O addresses\n");
return -1;
}
for(i = 0; i < LED_NUM; i++)
{
cdev_init( &led[i].dev, &led_fops);
//led[i].port = ioport_map(0x56000014,0x4);
//led[i].base = ioremap(0x56000014,0x4);
led[i].offset = i + 5; //leds GPB5\6\7\8
led[i].dev.owner = THIS_MODULE;
led[i].dev.ops = &led_fops;
result = cdev_add(&led[i].dev,MKDEV(MAJOR(dev),i),1);
if(result < 0)
{
printk(KERN_ERR "LED: can't add led%d\n",i);
return result;
}
}
return 0;
}
static void led_exit(void)
{
int i;
release_region(0x56000014,0x4);
for( i = 0; i < LED_NUM; i++)
{
//iounmap(led[i].base);
cdev_del(&led[i].dev);
}
unregister_chrdev_region(dev, LED_NUM);
}
mole_init(led_init);
mole_exit(led_exit);
MODULE_AUTHOR("Baikal");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple LED Driver");
2.利用IO Mem的方式:
[cpp] view plain
#include <linux/mole.h>
#include <linux/moleparam.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/ioport.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* _*_user */
#include <asm/io.h>
#define LED_NUM 4
struct led_dev
{
struct cdev dev;
void __iomem *base;
unsigned long offset;
};
struct led_dev led[4];
dev_t dev = 0;
int led_open(struct inode *inode, struct file *filp)
{
struct led_dev *led; /* device information */
led = container_of(inode->i_cdev, struct led_dev, dev);
filp->private_data = led; /* for other methods */
return 0; /* success */
}
int led_release(struct inode *inode, struct file *filp)
{
return 0;
}
ssize_t led_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
return 0;
}
ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
char data;
struct led_dev *led;
u32 value;
printk(KERN_INFO "debug by kal: led dev write\n");
led = (struct led_dev *)filp->private_data;
_from_user(&data,buf,count);
if(data == '0')
{
printk(KERN_INFO "debug by kal: led off\n");
value = ioread32(led->base);
iowrite32( value | 1<<led->offset, led->base);
}
else
{
printk(KERN_INFO "debug by kal: led on\n");
value = ioread32(led->base);
iowrite32( value & ~(1<<led->offset), led->base);
}
}
struct file_operations led_fops = {
.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
//.ioctl = led_ioctl,
.open = led_open,
.release = led_release,
};
static int led_init(void)
{
int result, i;
result = alloc_chrdev_region(&dev, 0, LED_NUM,"LED");
if (result < 0) {
printk(KERN_WARNING "LED: can't get major %d\n", MAJOR(dev));
return result;
}
for(i = 0; i < LED_NUM; i++)
{
cdev_init( &led[i].dev, &led_fops);
request_mem_region(0x56000014,0x4,"led");
led[i].base = ioremap(0x56000014,0x4);
led[i].offset = i + 5; //leds GPB5\6\7\8
led[i].dev.owner = THIS_MODULE;
led[i].dev.ops = &led_fops;
result = cdev_add(&led[i].dev,MKDEV(MAJOR(dev),i),1);
if(result < 0)
{
printk(KERN_ERR "LED: can't add led%d\n",i);
return result;
}
}
return 0;
}
static void led_exit(void)
{
int i;
release_mem_region(0x56000014,0x4);
for( i = 0; i < LED_NUM; i++)
{
iounmap(led[i].base);
cdev_del(&led[i].dev);
}
unregister_chrdev_region(dev, LED_NUM);
}
mole_init(led_init);
mole_exit(led_exit);
MODULE_AUTHOR("Baikal");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple LED Driver");
3. Linux如何读取某个寄存器的值如何读
处理概要: 通过制定类型(int,char等)的指针变量,把rw的地址给这个指针。 通过指针操作,取得含有07位的数值,然后通过移位运算即可取得07位的值。 仅供参考。
4. linux系统怎么查看cpu使用情况
1、查看内存:在SSH远程控制端,输入命令“cat /proc/meminfo”,按下“Enter”回车键,即可看到总的内存占用情况。
2、查看CPU:在SSH远程控制端,输入命令“top”,按下“Enter”回车键,即可看到cpu的使用率。
3、Linux上的VNC服务端,比较常用的就是tigervnc和x11vnc。x11vnc可以让远程访问者控制本地的实际显示器,而tigervnc既可以远程控制实际显示器,还可以控制平行独立于当前物理显示器的虚拟显示器。
中央处理器(Central Processing Unit),简称CPU,是1971年推出的一个计算机的运算核心和控制核心,是信息处理、程序运行的最终执行单元。
中央处理器包含运算逻辑部件、寄存器部件和控制部件等,并具有处理指令、执行操作、控制时间、处理数据等功能。
CPU包括运算逻辑部件、寄存器部件和控制部件等。[1]
逻辑部件
英文Logic components;运算逻辑部件,可以执行定点或浮点算术运算操作、移位操作以及逻辑操作,也可执行地址运算和转换。
寄存器
中央处理器
中央处理器
寄存器部件,包括通用寄存器、专用寄存器和控制寄存器。
通用寄存器又可分定点数和浮点数两类,它们用来保存指令执行过程中临时存放的寄存器操作数和中间(或最终)的操作结果。
通用寄存器是中央处理器的重要组成部分,大多数指令都要访问到通用寄存器。通用寄存器的宽度决定计算机内部的数据通路宽度,其端口数目往往可影响内部操作的并行性。
专用寄存器是为了执行一些特殊操作所需用的寄存器。
控制寄存器(CR0~CR3)用于控制和确定处理器的操作模式以及当前执行任务的特性。CR0中含有控制处理器操作模式和状态的系统控制标志;CR1保留不用;CR2含有导致页错误的线性地址;CR3中含有页目录表物理内存基地址.
控制部件
英文Control unit;控制部件,主要是负责对指令译码,并且发出为完成每条指令所要执行的各个操作的控制信号。
其结构有两种:一种是以微存储为核心的微程序控制方式;一种是以逻辑硬布线结构为主的控制方式。
微存储中保持微码,每一个微码对应于一个最基本的微操作,又称微指令;各条指令是由不同序列的微码组成,这种微码序列构成微程序。中央处理器在对指令译码以后,即发出一定时序的控制信号,按给定序列的顺序以微周期为节拍执行由这些微码确定的若干个微操作,即可完成某条指令的执行。
简单指令是由(3~5)个微操作组成,复杂指令则要由几十个微操作甚至几百个微操作组成。