hi3531的i2c部分

一、关于编译Hi3531 SDK:
之前编译SDK时编译到make uImage总出错,一是找不到.config文件,这个问题是必须先make menuconfig 然后保存.config文件。
二是编译到make uImage的快结束时,会出现找不到mkimage命令错误。
解决方法:
    查看最底层的Makefile:arch/arm/boot/Makefile,可以看到:
   
quiet_cmd_uimage = UIMAGE  $@
      cmd_uimage = $(CONFIG_SHELL) $( MKIMAGE) -A arm -O linux -T kernel \
                   -C none -a $(LOADADDR) -e $(STARTADDR) \
                   -n 'Linux-$(KERNELRELEASE)' -d $< $@
而 MKIMAGE 的值为:
MKIMAGE          := $(srctree)/scripts/mkuboot.sh
所以打开kernel/scripts/mkuboot.sh,修改mkimage的路径,然后编译,就通过了
 
说明:没有权限向公司的编译服务器拷贝mkimage,只能改Makefile中mkimage的路径
2、注意:最好修改osd目录下的Makefile,将删除linux-3.0.x的命令和重新解压的命令去掉,否则每次都
将之前的删除掉再重新解压,所以每次都要修改,没必要,也比较麻烦,编译也很费时间
 
二、关于I2C支持的工作总结
1、开始在SDK里编译的驱动一直没加上,提示:
# insmod gpioi2c.ko
gpioi2c: version magic '3.0.1 SMP mod_unload ARMv7 ' should be '3.0.1 mod_unload ARMv7 '

insmod: can't insert 'gpioi2c.ko': invalid module format
2、但是,SDK里和gpioi2c放一起的实例跑的是正确的结果:
# ./i2c_write 0x56 0x01 0x11
device_addr:0x56; reg_addr:0x 1; reg_value:0x11.
# ./i2c_read 0x56 0x01
device_addr:0x56; reg_addr:0x 1.
0x11
 
# ./i2c_write 0x56 0x02 0x22
device_addr:0x56; reg_addr:0x 2; reg_value:0x22.
# ./i2c_read 0x56 0x02
device_addr:0x56; reg_addr:0x 2.
0x22
读写的数据一致。
说明原来的驱动没有问题,可能是库里的代码有问题。
 
但是还是编译了SDK里的gpioi2c.ko驱动,因为这一个驱动被其他三个驱动使用了,所以需要先rmmod 那三个驱动,然后再卸载这个驱动。
 
3、先说这个问题怎么解决的:
# insmod gpioi2c.ko
gpioi2c: version magic '3.0.1 SMP mod_unload ARMv7 ' should be '3.0.1 mod_unload ARMv7 '

insmod: can't insert 'gpioi2c.ko': invalid module format
这是因为内核配置的不对,修改内核配置项,取消Kernel type->Symmetrical Multi-Processing这一项,编译出的驱动便可以insmod了。

使用了SDK中所带的驱动代码,因为tw2865、tlv_320aic31和sil9024使用了gpioi2c.ko,所以对这四个驱动都重新编译了。
代码存放路径:
[li_xiangping@xn-linux extdrv_hi3531]$ pwd
/home/li_xiangping/Hi3531_SDK_V1.0.2.0/mpp/extdrv_hi3531
         在该路径下执行make,然后将四个子目录w2865、tlv_320aic31、sil9024和gpio_i2c_8b下的.ko文件拷贝到demo板,替换到原来的驱动

4、 对库的修改:
4.1
将I2cWrite()中的:
           if (ioctl(I2cFd, I2C_WRITE, &Value) < 0)
改为:
           if (ioctl(I2cFd, GPIO_I2C_WRITE, &Value) < 0)
 
4.2
将I2cRead()中的:
if (ioctl(I2cFd, GPIO_I2C_READ, &Value) < 0)
改为:
                  if (ioctl(I2cFd, GPIO_I2C_READ, &Value) < 0)
4.3
在Inner/i2c.h中添加:
#define GPIO_I2C_READ               0x01
#define GPIO_I2C_WRITE                 0x03
 
修改原因:
 ioctl()的cmd值不一致,导致I2cWrite()失败。
写的时候总失败,读出来的数据是正确的,因为原来定义的宏是:
#define I2C_READ               0x01
#define I2C_WRITE                 0x02
修改后便正确了

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/proc_fs.h>
#include <linux/workqueue.h>

#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>

#define DEV_NAME                 "mic i2c driver"
#define DRV_VERSION              "1.0.0"

#define I2C_WAIT_TIME_OUT       0x1000
#define I2C_ADRESS_BASE         0x200D0000
#define I2C_ADRESS_PHY_LEN      0x20

#define MIC_I2C_CLOCK           (110000000)
#define MIC_I2C_RATE            (100000)

#define READ_OPERATION          (1)
#define WRITE_OPERATION         0xfe

/* the offset of reg */
#define I2C_CTRL_REG            0x000
#define I2C_COM_REB             0x004
#define I2C_ICR_REG             0x008
#define I2C_SR_REG              0x00C
#define I2C_SCL_H_REG           0x010
#define I2C_SCL_L_REG           0x014
#define I2C_TXR_REG             0x018
#define I2C_RXR_REG             0x01C

/* I2C_CTRL_REG */
#define I2C_ENABLE             (1 << 8)
#define I2C_UNMASK_TOTAL       (1 << 7)
#define I2C_UNMASK_START       (1 << 6)
#define I2C_UNMASK_END         (1 << 5)
#define I2C_UNMASK_SEND        (1 << 4)
#define I2C_UNMASK_RECEIVE     (1 << 3)
#define I2C_UNMASK_ACK         (1 << 2)
#define I2C_UNMASK_ARBITRATE   (1 << 1)
#define I2C_UNMASK_OVER        (1 << 0)
#define I2C_UNMASK_ALL         (I2C_UNMASK_START | I2C_UNMASK_END |      \
                                    I2C_UNMASK_SEND | I2C_UNMASK_RECEIVE |   \
                                    I2C_UNMASK_ACK | I2C_UNMASK_ARBITRATE |  \
                                    I2C_UNMASK_OVER)

/* I2C_SR_REG */
#define I2C_BUSY           (1 << 7)
#define I2C_START_INTR     (1 << 6)
#define I2C_END_INTR       (1 << 5)
#define I2C_SEND_INTR      (1 << 4)
#define I2C_RECEIVE_INTR   (1 << 3)
#define I2C_ACK_INTR       (1 << 2)
#define I2C_ARBITRATE_INTR (1 << 1)
#define I2C_OVER_INTR      (1 << 0)

/* I2C_ICR_REG */
#define I2C_CLEAR_START (1 << 6)
#define I2C_CLEAR_END (1 << 5)
#define I2C_CLEAR_SEND (1 << 4)
#define I2C_CLEAR_RECEIVE (1 << 3)
#define I2C_CLEAR_ACK (1 << 2)
#define I2C_CLEAR_ARBITRATE (1 << 1)
#define I2C_CLEAR_OVER (1 << 0)
#define I2C_CLEAR_ALL (I2C_CLEAR_START | I2C_CLEAR_END | \
                       I2C_CLEAR_SEND | I2C_CLEAR_RECEIVE | \
                       I2C_CLEAR_ACK | I2C_CLEAR_ARBITRATE | \
                       I2C_CLEAR_OVER)

/* I2C_COM_REB */
#define I2C_SEND_ACK       (~(1 << 4))
#define I2C_START          (1 << 3)
#define I2C_READ           (1 << 2)
#define I2C_WRITE          (1 << 1)
#define I2C_STOP           (1 << 0)

#define  mic_i2c_write(addr, value) ((*(volatile unsigned int *)(addr)) = (value))
#define  mic_i2c_read(addr)         (*(volatile unsigned int *)(addr))

#define MUXCTRL_REG102   IO_ADDRESS(0x200f0000 + 0x198) // I2C_SDA
#define MUXCTRL_REG103   IO_ADDRESS(0x200f0000 + 0x19c) // I2C_SCL

/* i2c controller state */
enum mic_i2c_state {
        STATE_IDLE,
        STATE_START,
        STATE_READ,
        STATE_WRITE,
        STATE_STOP
};

enum mic_i2c_type {
        TYPE_MIC_I2C,
        TYPE_MIC_NULL,
};

struct mic_i2c {
        spinlock_t                lock;
        wait_queue_head_t        wait;
        struct i2c_msg                *msg;
        unsigned int                irq;

        enum mic_i2c_state        state;
        unsigned long                clkrate;

        void __iomem                *regs;
        struct clk                    *clk;
        struct device                *dev;
        struct resource                *ioarea;
        struct i2c_adapter        adap;
};

struct resource mic_i2c_resource[] = {      
[0]={                                                  
  .start =  I2C_ADRESS_BASE,           
  .end   =  I2C_ADRESS_BASE + I2C_ADRESS_PHY_LEN,           
  .flags =  IORESOURCE_MEM,           
  }
};

static short mic_poll_status(struct i2c_adapter *adap, unsigned long bit)
{
        int loop_cntr = 10000;
        unsigned int reg = 0x00;
        struct mic_i2c *i2c = container_of(adap, struct mic_i2c, adap);

        do {
                udelay(10);
        } while (!(reg = mic_i2c_read(i2c->regs + I2C_SR_REG) & bit) && (--loop_cntr > 0));
       
        mic_i2c_write((i2c->regs + I2C_ICR_REG),  I2C_CLEAR_ALL);

        loop_cntr = 10000;
    while((mic_i2c_read(i2c->regs + I2C_SR_REG) & I2C_ACK_INTR) && (--loop_cntr > 0));
       
        return loop_cntr;
}

static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
{
    struct mic_i2c *i2c = container_of(adap, struct mic_i2c, adap);

        /* Read data */
        while(length) {
                /* Send Start */
                if(length - 1)
            mic_i2c_write((i2c->regs + I2C_COM_REB), I2C_READ);
                else
            mic_i2c_write((i2c->regs + I2C_COM_REB), I2C_READ | (~I2C_SEND_ACK));
               
                if(!mic_poll_status(adap, I2C_RECEIVE_INTR)) {
                        dev_info(&adap->dev, "TXRDY timeout\n");                       

                    return -ETIMEDOUT;
                        }

                *buf++ = (mic_i2c_read(i2c->regs + I2C_RXR_REG) & 0xff);
                length--;
                }

        mic_i2c_write((i2c->regs + I2C_ICR_REG), I2C_STOP);       

        return 0;
}

static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
{
    struct mic_i2c *i2c = container_of(adap, struct mic_i2c, adap);
         
        while(length--)
                {
            mic_i2c_write((i2c->regs + I2C_TXR_REG), *buf++);
            mic_i2c_write((i2c->regs + I2C_COM_REB), I2C_WRITE);

                   if(!mic_poll_status(adap, I2C_OVER_INTR))
                {
                dev_dbg(&adap->dev, "TXRDY timeout\n");                       
                    return -ETIMEDOUT;
                       }
           }
      
        return 0;
}

/*
* first port of call from the i2c bus code when an message needs
* transferring across the i2c bus.
*/
static int mic_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
{
    int i, ret;
        unsigned char device_addr = 0x00;
        struct mic_i2c *i2c = container_of(adap, struct mic_i2c, adap);

        for(i = 0; i < num; i++) {  
            mic_i2c_write((i2c->regs + I2C_COM_REB),  I2C_WRITE | I2C_START);

                if((pmsg->addr >> 8) & 0x00ff) {
                       device_addr = (char)((pmsg->flags & I2C_M_RD) ? ((pmsg->addr >> 8) | READ_OPERATION) : ((pmsg->addr >> 8) & WRITE_OPERATION));
                       xfer_write(adap, &device_addr, 1);
                        device_addr = (char)((pmsg->flags & I2C_M_RD) ? (pmsg->addr | READ_OPERATION) : (pmsg->addr & WRITE_OPERATION));
                       xfer_write(adap, &device_addr, 1);
                    }
                else {
                        device_addr = (char)((pmsg->flags & I2C_M_RD) ? (pmsg->addr | READ_OPERATION) : (pmsg->addr & WRITE_OPERATION));
            xfer_write(adap, &device_addr, 1);
                        }

                pmsg->addr = device_addr;
                       
                if (pmsg->len && pmsg->buf) {        /* sanity check */
                        if (pmsg->flags & I2C_M_RD)
                                ret = xfer_read(adap, pmsg->buf, pmsg->len);
                        else
                                ret = xfer_write(adap, pmsg->buf, pmsg->len);
                       }

                /* Wait until transfer is finished */
                mic_i2c_write((i2c->regs + I2C_COM_REB), I2C_STOP);
                if(!mic_poll_status(adap, I2C_OVER_INTR)) {
                 dev_info(&adap->dev, "TXRDY timeout\n");                       
                     return -ETIMEDOUT;

                mic_i2c_write((i2c->regs + I2C_ICR_REG), 0x01);

                if(ret < 0)
                        return ret;
                }
            pmsg++;                /* next message */       
        }

        return i;
}

/* declare our i2c functionality */
static u32 mic_i2c_func(struct i2c_adapter *adap)
{
    printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);
       
        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
}

/* i2c bus registration info */
static const struct i2c_algorithm mic_i2c_algorithm = {
        .master_xfer                = mic_i2c_xfer,
        .functionality                = mic_i2c_func,
};

static int mic_i2c_probe(struct platform_device *pdev)
{
    struct mic_i2c *i2c;       
        int ret;
        unsigned int  value, value_h, value_l;   

        writel(0x01, MUXCTRL_REG102);
        writel(0x01, MUXCTRL_REG103);
   
        i2c = kzalloc(sizeof(struct mic_i2c), GFP_KERNEL);
        if (!i2c) {
                dev_err(&pdev->dev, "no memory for state\n");
                return -ENOMEM;
        }

        snprintf(i2c->adap.name, sizeof(i2c->adap.name), "mic");       
        i2c->adap.algo = &mic_i2c_algorithm;       
        i2c->adap.class = I2C_CLASS_HWMON;       
        i2c->adap.dev.parent = &pdev->dev;
        i2c->adap.nr = pdev->id;
       
        i2c->ioarea = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!i2c->ioarea)
                return -ENXIO;

        if (!request_mem_region(i2c->ioarea->start, resource_size(i2c->ioarea), "mic_i2c"))
                return -EBUSY;

        i2c->regs = ioremap(i2c->ioarea->start, resource_size(i2c->ioarea));
        if (!i2c->regs) {
                ret = -ENOMEM;
                goto fail0;
        }

        spin_lock_init(&i2c->lock);

        /* clk */
        /* Read CTRL */   
        value = mic_i2c_read(i2c->regs + I2C_CTRL_REG);

        /* maskable interrupt of i2c */   
        mic_i2c_write((i2c->regs + I2C_CTRL_REG), (value & (~I2C_UNMASK_TOTAL)));   

        value_h = (MIC_I2C_CLOCK / (MIC_I2C_RATE * 2)) / 2 - 1;   
        mic_i2c_write((i2c->regs + I2C_SCL_H_REG), value_h);
       
        value_l = (MIC_I2C_CLOCK / (MIC_I2C_RATE * 2)) / 2 - 1;   
        mic_i2c_write((i2c->regs + I2C_SCL_L_REG), value_l);   
       
        /* enable interrupt of i2c */   
        mic_i2c_write((i2c->regs + I2C_ICR_REG),  0x03);
        mic_i2c_write((i2c->regs + I2C_CTRL_REG), 0x0187 | value);
       
        platform_set_drvdata(pdev, i2c);

        ret = i2c_add_numbered_adapter(&i2c->adap);
        if (ret) {
                dev_err(&pdev->dev, "Adapter %s registration failed\n",
                                i2c->adap.name);
                goto fail1;
        }

        dev_info(&pdev->dev, "mic i2c bus driver.\n");

        return 0;

fail1:       
        platform_set_drvdata(pdev, NULL);       
       
fail0:
        release_mem_region(i2c->ioarea->start, resource_size(i2c->ioarea));
        iounmap(i2c->regs);
        kfree(i2c);       

        return ret;         
}

static int __devexit mic_i2c_remove(struct platform_device *pdev)
{
        struct mic_i2c *i2c = platform_get_drvdata(pdev);
       
    printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);

        i2c_del_adapter(&i2c->adap);
        platform_set_drvdata(pdev, NULL);
        release_mem_region(i2c->ioarea->start, resource_size(i2c->ioarea));
        iounmap(i2c->regs);
    kfree(i2c);
       
        return 0;
}

#ifdef CONFIG_PM_RUNTIME
static int mic_i2c_suspend_noirq(struct device *dev)
{
        printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);

        return 0;
}

static int mic_i2c_resume(struct device *dev)
{
        printk(KERN_ALERT "%s:%s,%s\r\n", __FUNCTION__,__DATE__,__TIME__);

        return 0;
}

static const struct dev_pm_ops mic_i2c_dev_pm_ops = {
        .suspend_noirq = s3c24xx_i2c_suspend_noirq,
        .resume = mic_i2c_resume,
};

#define MIC_DEV_PM_OPS (&mic_i2c_dev_pm_ops)
#else
#define MIC_DEV_PM_OPS NULL
#endif

static void mic_i2c_release(struct device * dev)
{
}

struct platform_device mic_i2c_device = {
        .name                  = "mic-i2c",
        .id                          = 0,
        .num_resources          = ARRAY_SIZE(mic_i2c_resource),
        .resource              = mic_i2c_resource,
        .dev              =
        {           
         .release           =  mic_i2c_release,
        }  
};

static struct platform_driver mic_i2c_driver = {
        .probe                = mic_i2c_probe,
        .remove                = mic_i2c_remove,
        .driver                = {
                .owner        = THIS_MODULE,
                .name        = "mic-i2c",
                .pm        = MIC_DEV_PM_OPS,
        },
};

static int __init mic_i2c_init(void)
{
    int ret = -ENODEV;

        printk(KERN_INFO "%s %s V%s\n", __func__, DEV_NAME, DRV_VERSION);

    platform_device_register(&mic_i2c_device);
       
    ret = platform_driver_register(&mic_i2c_driver);
        if(ret)
                {
                platform_device_unregister(&mic_i2c_device);
                printk("platform_device_register is fail!\n");
                goto end;
                }
       
end:       
        return ret;  
}
subsys_initcall(mic_i2c_init);

static void __exit mic_i2c_exit(void)
{
    printk(KERN_INFO "%s %s V%s\n", __func__, DEV_NAME, DRV_VERSION);
       
        platform_driver_unregister(&mic_i2c_driver);
        platform_device_unregister(&mic_i2c_device);

}
module_exit(mic_i2c_exit);

MODULE_DESCRIPTION("mic i2c driver");
MODULE_AUTHOR("microcreat <microcreat@gmail.com>");
MODULE_LICENSE("GPL");
直接可以编译成ko,加载进内核,进入内核可以看到i2c设备成功加载!

时间: 2024-09-11 01:58:11

hi3531的i2c部分的相关文章

MiniGUI + Hi3531 笔记 .

一.移动光驱安装Ubuntu 10.04      1.   重启系统按住Delete进入BIOS界面!      2.   退出/高级模式 --> 启动 --> 启动设备选择. 移动光驱正常被识别后这里应该是有2个选项的:            (1)SATA :WOC WD6401AALS-00E3A0 (默认硬盘)            (2)TSSTcorp CDDVDW SE-208AB TS00 (移动光驱)            我们直接点击(2)启动读取移动光驱中的光盘, 耐心

pxa270-关于PXA270的I2C总线共用的问题

问题描述 关于PXA270的I2C总线共用的问题 1.CPU使用PXA270 2.RTC使用外部芯片M41T81,使用IIC总线与PXA270进行通讯: 3.扫描头用来扫描二维码,使用IIC总线与PXA270进行通讯: 4.操作系统用的是wince5.0 问题描述: 当在注册表里注释掉扫描头的启动信息,不让其开机启动,这种情况下,RTC是可以正常工作的,能够在断电情况继续保持守时功能: 但是当我们在注册表里加上扫描头的启动信息,让其开机启动后,不管硬件上扫描头有没有接上,这时RTC都不能正常工作

在Android源码树中添加userspace I2C读写工具(i2c-util)

通过/dev/i2c-n节点,用户可以在userspace直接访问板上的i2c外设寄存器,主要是透过I2C_RDWR这个IO控制命令将i2c_msg数组传递给kernel去执行.下面的代码可以完成这个功能: #include <stdio.h> #include <linux/types.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <sys/t

OpenRisc入门(20) or1200下linux的i2c(二)

上次记得是基于linux系统自带的i2c-ocores.c文件接口写了简单的测试程序,这次就基于opencores社区上大虾写好的i2c controller总线驱动来做一下分析,这个总线驱动在openrisc-3.1\drivers\i2c\busses目录下~这个总线驱动是基于Richard Herveille编写的i2c-master的ipcore,在opencores社区上可以下到这份RTL的代码,然后打开源码里面的i2c_specs说明文档看看这个ipcores的相关操作. openr

OpenRisc入门(19) or1200下linux的i2c(一)

这篇blog介绍I2C的学习了,首先要在我们的or1200_soc上添加进来I2C Controller,到opencores社区上面找到i2c_latest.tar.gz这个工程包. 解压得到如下文件目录: 注意啦,这里的i2c_top.v的顶层文件需要自己编写,因为需要在工程的更顶层将i2c_master_top.v里的输入输出信号组织成三态信号. [plain] view plaincopyprint module i2c_top( //wishbone interfaces wb_clk

i2c-单片机如何监听另外两机的I2C通信内容?

问题描述 单片机如何监听另外两机的I2C通信内容? 不使用查询方式,如何读取但又不影响另外两机(一主一从)的I2C通信(包括读和写)?有什么型号的单片机比较方便做这个活? 本人目前使用stm8s来做,但是进入中断的时候I2C总线的DATA传输已经完成了一个时钟,所以无法获取主机读从机时的完整数据.请问这个有没有什么简单的办法实现?

Hi3531 SDK 安装以及升级使用说明

Hi3531 SDK 安装以及升级使用说明 第一章 Hi3531_SDK_Vx.x.x.x版本升级操作说明    如果您是首次安装本SDK,请直接参看第2章.     第二章 首次安装SDK 1.Hi3531 SDK包位置     在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx.x.x.x.tgz 的文件, 该文件就是Hi3531的软件开发包. 2.解压缩SDK包     在linux服务器上(或者一台装

Ubuntu 上 hi3531 交叉编译环境 arm-hisiv100nptl-linux 搭建过程

安装SDK 1.Hi3531 SDK包位置     在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx.x.x.x.tgz 的文件, 该文件就是Hi3531的软件开发包. 2.解压缩SDK包     在linux服务器上(或者一台装有linux的PC上,主流的linux发行版本均可以),使用命令:tar -zxf Hi3531_SDK_Vx.x.x.x.tgz , 解压缩该文件,可以得到一个Hi3531_SD

hi3531 SDK已编译文件系统制作jffs2文件系统镜像并解决问题 .

一, 安装SDK 1.Hi3531 SDK包位置     在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx.x.x.x.tgz 的文件, 该文件就是Hi3531的软件开发包. 2.解压缩SDK包     在linux服务器上(或者一台装有linux的PC上,主流的linux发行版本均可以),使用命令:tar -zxf Hi3531_SDK_Vx.x.x.x.tgz , 解压缩该文件,可以得到一个Hi3531