使用应用层的调试工具 himm
~ # himm
*** Board tools : ver0.0.1_20121120 ***
[debug]: {
source/utils/cmdshell.c:166}cmdstr:himm
usage: himm <address>. sample: himm 0x80040000
[error]: exit:0XFFFFFFFF.{
source/tools/himm.c:45}
[END]
使用方式是 himm 0x80040000 后面跟的是需要操作的地址信息。
~ # himm 0x80040000
*** Board tools : ver0.0.1_20121120 ***
[debug]: {
source/utils/cmdshell.c:166}cmdstr:himm
====dump memory 0X80040000====
0x80040000: 0xFFBEEFAE
NewValue:
输入后可以得出其寄存器的值,在默认值的基础上我们再做修改。切记只修改需要改变的位,其他寄存器位保持一致。在NewValue中输入改变后的值。
另外还有其他的工具;
~ # himc
*** Board tools : ver0.0.1_20121120 ***
[debug]: {
source/utils/cmdshell.c:166}cmdstr:himc
clear(set) memory.
usage: himc <address> <length> [value].
Address: Phy address. 0x80040000
Length: the length to set
Value: default 0
sample: himc 0x80040000 100 1
Clear memory from 0x80040000, to 0x80040064
[error]: exit:0XFFFFFFFF.{
source/tools/himc.c:50}
[END]
~ # himd
*** Board tools : ver0.0.1_20121120 ***
[debug]: {
source/utils/cmdshell.c:166}cmdstr:himd
usage: himd <address>. sample: himd 0x80040000
[error]: exit:0XFFFFFFFF.{
source/tools/himd.c:107}
[END]
~ # himd.l
*** Board tools : ver0.0.1_20121120 ***
[debug]: {
source/utils/cmdshell.c:166}cmdstr:himd.l
usage: himd.l <address> [length]. sample: himd.l 0x80040000 0x100
[error]: exit:0XFFFFFFFF.{
source/tools/himd.c:50}
[END]
用法有给出来,但是作用的话,我没用过,有用过的同学可以在评论补充下。谢谢。
#include
#include
#include
#include
#include
#include
#include
#include
#include "hi_gpio.h"
int main(int argc, char *argv[])
{
//管脚gpio15_pin4复用为gpio功能
//可以采用HI_S32 HI_MPI_SYS_SetReg(HI_U32 u32Addr, HI_U32 u32Value);和
//HI_S32 HI_MPI_SYS_GetReg(HI_U32 u32Addr, HI_U32 *pu32Value); 来替代
system("himm 0x120F00F0 0x1");
//设置为推挽输出
BSPGpioInit(GPIO_PORT_15, GPIO_Pin_4, IS_INPUT, GPIO_MODE_Out_PP);
//设置为开漏输出
BSPGpioInit(GPIO_PORT_15, GPIO_Pin_4, IS_OUTPUT, GPIO_MODE_Out_OD);
//输出低电平
BSPGpioClearOutput(GPIO_PORT_15, GPIO_Pin_4);
//输出高电平
BSPGpioSetOutput(GPIO_PORT_15, GPIO_Pin_4);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define REG_WRITE(addr, value) ((*(volatile unsigned int *)(addr)) = (value))
#define REG_READ(Addr) (*(volatile unsigned int *)(Addr))
#define GPIO_CONFIG_OFFSET_ADDR 0xF0
#define GPIO_DIR_OFFSET_ADDR 0x400
#define GPIO_DATA_OFFSET_ADDR 0x40 //输出偏移位 gpio15_4
unsigned int muxctrl_virtual_addr = 0;
unsigned int gpio_15_virtual_addr = 0;
static void gpio15_4_output_height();
static void gpio15_4_output_low();
static int hi3536_virtual_addr_map(void)
{
muxctrl_virtual_addr = (unsigned int)ioremap_nocache(GPIO_MUXCTRL_BASE_ADDR, 0x10000);
if(!muxctrl_virtual_addr)
{
printk("GPIO_MUXCTRL_BASE_ADDR ioremap addr failed !\n");
return -1;
}
gpio_15_virtual_addr = (unsigned int)ioremap_nocache(GPIO15_BASE_ADDR, 0x10000);
if(!gpio_15_virtual_addr)
{
printk("GPIO15_BASE_ADDR ioremap addr failed !\n");
return -1;
}
}
static void gpio15_4_output_height()
{
REG_WRITE(gpio_15_virtual_addr + GPIO_DATA_OFFSET_ADDR, 0xFF);//GPIO15_4
}
static void gpio15_4_output_low()
{
REG_WRITE(gpio_15_virtual_addr + GPIO_DATA_OFFSET_ADDR, 0x0);//GPIO15_4
}
//取消地址映射
static void hi3531_virtual_addr_unmap(void)
{
iounmap((void*)muxctrl_virtual_addr);
iounmap((void*)gpio_15_virtual_addr);
}
static void hi3531_button_gpio_config(void)
{
unsigned int u32Reg = 0;
//配置为gpio
REG_WRITE(muxctrl_virtual_addr + GPIO_CONFIG_OFFSET_ADDR, 0x1);//KEY1 - GPIO6_1
//配置为输出
u32Reg = REG_READ(gpio_15_virtual_addr + GPIO_DIR_OFFSET_ADDR);
u32Reg |= (0x10);
REG_WRITE(gpio_15_virtual_addr + GPIO_DIR_OFFSET_ADDR, u32Reg);//GPIO15_4
}
static int __init hi_gpio_init(void)
{
int retval=0;
hi3536_virtual_addr_map();
hi3531_button_gpio_config();
gpio15_4_output_low();
return retval;
}
static void __exit hi_gpio_exit(void)
{
hi3531_virtual_addr_unmap();
printk(" FUNC:%s LINE:%d\n", __func__, __LINE__);
}
module_init(hi_gpio_init);
module_exit(hi_gpio_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Hisilicon");
表13-18 GPIO 寄存器概览
偏移地址 名称 描述
0x000~0x3FC GPIO_DATA GPIO 数据寄存器
0x400 GPIO_DIR GPIO 方向控制寄存器
0x404 GPIO_IS GPIO 中断触发寄存器
0x408 GPIO_IBE GPIO 双沿触发中断寄存器
0x40C GPIO_IEV GPIO 触发中断条件寄存器
0x410 GPIO_IE GPIO 中断屏蔽寄存器
0x414 GPIO_RIS GPIO 原始中断状态寄存器
0x418 GPIO_MIS GPIO 屏蔽状态中断寄存器
0x41C GPIO_IC GPIO 中断清除寄存器
当 GPIO_DIR 相应的比特配置为输入时,有效读取的结果将返回管脚的值;当配置为
输出的时候,有效读取的结果将返回写入的值;
对数据寄存器GPIO_DATA进行说明:
GPIO_DATA 寄存器利用 PADDR[9:2]实现了读写寄存器比特的屏蔽操作。该寄存器对
应 256 个地址空间。PADDR[9:2]分别对应 GPIO_DATA[7:0],当相应的 bit 为高时,则
可以对相应的位进行读写操作;反之,若对应 bit 为低则不能进行操作。例如:
若地址为 0x3FC(0b11_1111_1100),则对 GPIO_DATA[7:0]这 8bit 操作全部有效。
若地址为 0x200(0b10_0000_0000),则仅对 GPIO_DATA[7]的操作有效。
什么意思呢,就是说,地址0x3FC(0b11_1111_1100)[10:2]位分别对应了GPIO_DATA[n]寄存器,相当于mask位的作用。
如果你要操作gpio_data[7] 第7管脚pin7 (海思的gpio脚标从0开始)那你要在0x00的偏移上加0x200 然后让它输出高往里写入0XFF。
上面例子里我操作的是gpio15pin4 也就是gpio_data[4] 也就是(0b00_0100_0000)0x40。
好了通过上面的介绍,我们可以通过himm用命令行操作寄存器让我们的gpio实时的输出高低电平,也可以用应用程序提供的接口来操作gpio。
当然也可以通过底层映射寄存器的方式来直接操作gpio的寄存器,从而达到设置和控制gpio的目的。