ymir

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir  发布于  2015-07-09 14:41:19
采纳率 0%
23个问答
11492

HI3520D-GPIO开发<有示例代码>

 
本帖最后由 ymir 于 2015-7-16 18:47 编辑

个人修改Makefile,使用该Make可以使用海思工具中的某些API进行GPIO开发:
该工具位于目录 osdrv/tools/board_tools/reg-tools-1.0.0
[code]├── include
│   ├── common
│   │   ├── gpio_i2c.h
│   │   ├── hi_bits.h
│   │   ├── hi_config.h
│   │   ├── hi_dbg.h
│   │   ├── hi_defs.h
│   │   ├── hi_error.h
│   │   ├── hi.h
│   │   ├── hi_help_en.h
│   │   ├── hi_i2c.h
│   │   ├── hi_limit.h
│   │   ├── hi_message.h
│   │   ├── hi_module.h
│   │   ├── hi_os.h
│   │   ├── hi_thread.h
│   │   ├── hi_type.h
│   │   ├── hi_utils.h
│   │   ├── hi_version.h
│   │   └── mmpver.h
│   └── utils
│       ├── argparser.h
│       ├── btools.h
│       ├── cmdshell.h
│       ├── memmap.h
│       ├── stat.h
│       └── strfunc.h
├── Makefile
├── source
│   ├── common
│   │   ├── hi_dbg.c
│   │   ├── hi_message.c
│   │   └── hi_thread.c
│   ├── tools
│   │   ├── btools.c
│   │   ├── hiddrs.c
│   │   ├── hii2c.c
│   │   ├── hil2s.c
│   │   ├── himc.c
│   │   ├── himd.c
│   │   ├── himm.c
│   │   └── hivd.c
│   └── utils
│       ├── argparser.c
│       ├── cmdshell.c
│       ├── memmap.c
│       ├── stat.c
│       └── strfunc.c
└── work
    ├── main.c
    └── Makefile
[/code]

[code]# Makefile
# this file is for the develop for the GPIO
# that the file should be in the folder of reg
# set files
TARGET=ARM
CROSS=arm-hisiv100nptl-linux
CC  = $(CROSS)-gcc
STRIP=$(CROSS)-strip
#
# Configuration: Debug
#

TOPDIR=../
INCDIR=$(TOPDIR)include
SRCDIR=$(TOPDIR)source
OUTDIR=$(SRCDIR)

CFG_INC +=-I$(INCDIR)/common\
                  -I$(INCDIR)/utils\
                  -I$(INCDIR)/tools
HICOMMON_OBJ :=



#MAIN_OBJ=main.o
MAIN_SRC :=$(wildcard *.c)
MAIN_OBJ :=$(MAIN_SRC:%.c=%.o)
OUTTARGET :=$(MAIN_OBJ:%.o=%)
#!!!!!!!!!!!!!!! 1 添加生成的可执行文件
CFG_LIB = -lpthread -lrt

HICOMMON_OBJ=$(OUTDIR)/hi_message.o \
             $(OUTDIR)/hi_thread.o  \
             $(OUTDIR)/hi_dbg.o \
             $(OUTDIR)/cmdshell.o \
             $(OUTDIR)/argparser.o
BASE_OBJ=$(OUTDIR)/strfunc.o \
         $(OUTDIR)/memmap.o

OBJ=$(HICOMMON_OBJ) \
    $(BASE_OBJ)

ALL_OBJ = $(OBJ)\
                  $(MAIN_OBJ) \
        

CFG_FLAGS = $(CFG_DEBUG) $(CFG_INC) $(CFG_DEFS)

COMPILE=$(CC) $(CFG_FLAGS) -c -o "$(OUTDIR)/$(*F).o" "$<"

all : $(OUTTARGET)
# complie the base api
$(OUTDIR)/%.o : $(SRCDIR)/utils/%.c
        $(COMPILE)
$(OUTDIR)/%.o : $(SRCDIR)/common/%.c
        $(COMPILE)
$(OUTDIR)/%.o :  $(DRIVERDIR)/memmap/%.c
        $(COMPILE)

$(MAIN_OBJ) :%.o:%.c $(OUTDIR) $(OBJ)
                $(CC) $(CFG_CFLAGS)  $(CFG_INC) -c $(MAIN_SRC)

$(OUTTARGET) :%:%.o $(BASE_OBJ) $(HICOMMON_OBJ)
        $(CC) $(CFG_INC) -lpthread -lm -o $@ $^

clean:
        rm -f $(OUTFILE)
        rm -f $(OBJ)
        rm -f $(OUTDIR)/*.o
        rm -rf $(MAIN_OBJ)
        rm -rf $(OUTTARGET)
        #rm -f himd himm himc himd.l hier hiew
        rm -f hiddrs hil2s

# Clean this project and all dependencies
cleanall: clean
[/code]
我来回答
回答22个
时间排序
认可量排序

jp1017

0个粉丝

78

问答

0

专栏

9

资料

jp1017 2015-07-09 15:13:22
认可0
厉害,学习了,学习!!!

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir 2015-07-09 16:18:43
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=17929&ptid=8068]jp1017 发表于 2015-7-9 15:13[/url]
厉害,学习了,学习!!![/quote]

有没有做过GPIO开发?

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir 2015-07-10 09:59:43
认可0
本帖最后由 ymir 于 2015-7-10 10:00 编辑

测试代码,对GPIO1_0,GPIO1_1 进行寄存器设置
[code]/******************************************************************************

  Copyright (C), 2001-2011, Hisilicon Tech. Co., Ltd.

******************************************************************************
  File Name     : main.c
  Version       : test
  Author        : mike
  Created       : 2015/7/10
  Last Modified :
  Description   : Memory Modify
  Function List :
  History       :
  Modification: Created file

******************************************************************************/

#include
#include
#include
#include "memmap.h"
#include "hi.h"
#include "strfunc.h"

typedef struct{
        char name[128];
        U32 reg;
        U32 value;
        U32 len;
}RegInfo;

#define DEFAULT_LEN 16
static RegInfo reginfo[]={
        {
                .name = "GPIO1_0",
                .reg  = 0x200f00B8,
                .value = 1,
                .len = DEFAULT_LEN,
        },
        {
                .name = "GPIO1_1",
                .reg  = 0x200f00BC,
                .value = 1,
                .len = DEFAULT_LEN,
        },
};

int main(int argc , char* argv[])
{
    U32 ulAddr = 0;
        U32 ulOld,uLNew;
           VOID *pMem = NULL;
        U32 i;
        for(i=0; i<(sizeof(reginfo)/sizeof(RegInfo)); i++)
        {
                if(reginfo.reg > 0)
                {
                        pMem = memmap(reginfo.reg,reginfo.len);
                        ulOld = *(U32*)pMem;
                        printf("Reg %x value:%x\n",reginfo.reg,ulOld);
                        *(U32*)pMem = reginfo.value;
                        ulOld = *(U32*)pMem;
                        printf("Reg %x New value:%x\n",reginfo.reg,ulOld);
                }
        }
   
    return 0;
}


[/code]

该示例代码使用的寄存器为海思tool里的memmap函数,工具中还有许多的函数可以使用,大家可以自行探索

ecomsbz

1个粉丝

22

问答

0

专栏

36

资料

ecomsbz 2015-07-14 14:07:24
认可0
搂主太帅。真不想理你。好东西收了。

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir 2015-07-16 18:46:09
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=18074&ptid=8068]ecomsbz 发表于 2015-7-14 14:07[/url]
搂主太帅。真不想理你。好东西收了。[/quote]

实现GPIO1_0 端口GPIO输出一秒长度的高低电平;
实测通过。
[code]/******************************************************************************

  Copyright (C), 2001-2011, Hisilicon Tech. Co., Ltd.

******************************************************************************
  File Name     : main.c
  Version       : Initial Draft
  Author        : mike
  Created       : 2015/7/16
  Last Modified :
  Description   : GPIO Test GPIO1_0
  Function List :
  History       :

******************************************************************************/

#include
#include
#include
#include
#include
#include "memmap.h"
#include "hi.h"
#include "strfunc.h"

typedef struct{
        char name[128];
        U32 reg;
        U32 value;
        U32 len;
}RegInfo;

#define DEFAULT_LEN 16
static RegInfo reginfo[]={
        {
                .name = "Set Muilt Reg out",
                .reg  = 0x200F00B8,
                .value = 0x00,
                .len = DEFAULT_LEN,
        },
        {
                .name = "Set Dir Register output",
                .reg  = 0x20160400,
                .value = 0xFF,
                .len = DEFAULT_LEN,
        },
        {
                .name = "light:",
                .reg  = 0x20160004,
                .value = 0x00,
                .len = DEFAULT_LEN,
        },
};
#define true        1
#define false        0

void signal_handle(int signo)
{
    if (SIGINT == signo || SIGTSTP == signo)
    {
       printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
    }
         exit(0);
}


int main(int argc , char* argv[])
{
    U32 ulAddr = 0;
        U32 ulOld,uLNew;
           VOID *pMem = NULL;
        int i,j;

        signal(SIGINT, signal_handle);
        signal(SIGTERM, signal_handle);

        for(i=0; i<(sizeof(reginfo)/sizeof(RegInfo)); i++)
        {
        if(reginfo.reg > 0)
                {
                        pMem = memmap(reginfo.reg,reginfo.len);
                        ulOld = *(U32*)pMem;
                        *(U32*)pMem = reginfo.value;
                        ulOld = *(U32*)pMem;
                        printf("Reg %x New value:%x\n",reginfo.reg,ulOld);
                }
        }
        int ok = true;       
        printf("Bgin to mamap memory\n");
        while(1)
        {
                if(reginfo[2].reg > 0)
                {
                        pMem = memmap(reginfo[2].reg,reginfo[2].len);
                        ulOld = *(U32*)pMem;
                        if(ok){
                                ok = false;
                                *(U32*)pMem = 0xFF;
                        }else{
                                ok = true;
                                *(U32*)pMem = 0x00;
                        }
                        printf("%s %s",reginfo[2].name,ok?"on\n":"off\n");
                        ulOld = *(U32*)pMem;
                }
                sleep(1);
        }       
   
    return 0;
}


[/code]

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir 2015-07-17 17:21:08
认可0
写了点GPIO的代码
[url]https://github.com/ppslinux/hi3531-gpio.git[/url]

manu2013

0个粉丝

1

问答

0

专栏

0

资料

manu2013 2015-09-05 21:45:28
认可0
楼主为什么我的sdk包没有osdrv/tools/board_tools/reg-tools-1.0.0?

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir 2015-09-06 17:56:38
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=19877&ptid=8068]manu2013 发表于 2015-9-5 21:45[/url]
楼主为什么我的sdk包没有osdrv/tools/board_tools/reg-tools-1.0.0?[/quote]

到SDK目录;
find . | grep “reg-tools"

manu2013

0个粉丝

1

问答

0

专栏

0

资料

manu2013 2015-09-14 10:07:59
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=19916&ptid=8068]ymir 发表于 2015-9-6 17:56[/url]
到SDK目录;
find . | grep “reg-tools"[/quote]

找到了谢谢,楼主试过gpio中断吗,gpio中断是不是要用gpio驱动?

ymir

2个粉丝

23

问答

0

专栏

8

资料

ymir 2015-09-14 14:48:01
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=20152&ptid=8068]manu2013 发表于 2015-9-14 10:07[/url]
找到了谢谢,楼主试过gpio中断吗,gpio中断是不是要用gpio驱动?[/quote]

这个没搞过,不过方便的方法是通过开个线程来检测端口变化。

sgnah

0个粉丝

0

问答

0

专栏

0

资料

sgnah 2015-11-17 17:12:32
认可0
赞赞赞赞赞赞赞赞赞赞赞

wu0

0个粉丝

7

问答

0

专栏

1

资料

wu0 2015-11-25 13:58:15
认可0
好资料 正参考着 用:P

luffy

0个粉丝

1

问答

0

专栏

0

资料

luffy 2015-12-24 18:01:51
认可0
还没拿到开发板,先收藏了,后面好好学习

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-04-14 17:52:44
认可0
正在折腾外部看门狗,这个看来要用了,谢谢先

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-04-15 01:27:41
认可0
本帖最后由 ngswfx 于 2016-4-15 02:33 编辑

狗已经喂好,不乱咬了,虽然还不太听话(狗软件一退出,就重启了,不合我的设想呀,搞得和海思的狗差不多似的,现象相同,但实质应该不一样,按理说,程序重启前,有过最后一次喂狗,应该等一段时间才重启的。

有可能和这个不知名狗芯片有关,如果喂狗后,1s左右重启,那就说明狗的时间是1.6秒。

但为什么,如果不喂狗,还能进系统,40多秒才重启(估计系统内部有处理动作,因为狗腿子接的VIU1_CLK),这个系统,U-boot,kernel都是我自己弄得,没加过喂狗动作,估计芯片一旦喂狗,时间变了,或者进入数据有要求,才能长时间不用喂,不研究了,啥芯片都不知道,随便找的NVR主板当开发板),但还是感谢,用的代码就是下面的部分:


我没用库,直接调用了,把函数memmap单独摘出来用了,开始的时候,板子启动后,40多秒会自动重启,现在不重启了,测量94腿,一会高,一会儿低,我也不知道这个板子上用的啥狗芯片,5条腿,估计像EM6323这种类型,狗的WDI引脚只要变化,就相当于喂狗。

//////////////////////////////////////////////////////////////////估计原因///////////////////////////////////////////////////
  在CPU上电启动期间内,是不能输出WDI信号去清狗的,而外部硬件看门狗是一上电就开始工作的,CPU的启动时间一般在一两分钟,而看门狗的定时器只有1.6s,超过这个时间不清狗就会输出复位信号对CPU进行复位,如果这样的话,CPU就会每隔1.6s重启一次,不能正常工作,如何规避这种问题的?

    在实际设计中是这样做的,如下图所示,在CPU上电启动的这段时间内,利用系统时钟信号CLK清狗,等CPU启动完成后,SWITCH自动将清狗信号切换成WDI。定时器和切换开关(SWITCH)是用逻辑模拟的,定时器的溢出时间可设(一般比CPU启动时间稍长一点点),等CPU启动完成后,定时器也随之溢出,并产生溢出信号,SWITCH接收到此溢出信号后,立即采取动作,将清狗信号从系统时钟切换到WDI。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
如果如上面所讲,看来还要研究一下系统里面的相关机制,我也来控制这个定时器的切换开关,狗就听话了。


以前,没搞过GPIO,的确可用。

#ifdef SUPPORT_2106C_94_WATCH_DOG  //3520D 94脚 GPIO8_7 连接5腿看门狗电路
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct tag_MMAP_Node
{
        unsigned int Start_P;
        unsigned int Start_V;
        unsigned int length;
    unsigned int refcount;  /* map后的空间段的引用计数 */
        struct tag_MMAP_Node * next;
}TMMAP_Node_t;

TMMAP_Node_t * pTMMAPNode = NULL;
#define PAGE_SIZE 0x1000
#define PAGE_SIZE_MASK 0xfffff000
static int fd_DOG_MEM = -1;
static const char dev[]="/dev/mem";
/* no need considering page_size of 4K */
void * _memmap(unsigned int phy_addr, unsigned int size)
{
        unsigned int phy_addr_in_page;
        unsigned int page_diff;
        unsigned int size_in_page;
        TMMAP_Node_t * pTmp;
        TMMAP_Node_t * pNew;
        void *addr=NULL;
        if(size == 0)
                return NULL;
        /* check if the physical memory space have been mmaped */
        pTmp = pTMMAPNode;
        while(pTmp != NULL)
        {
                if( (phy_addr >= pTmp->Start_P) &&
                        ( (phy_addr + size) <= (pTmp->Start_P + pTmp->length) ) )
                {
            pTmp->refcount++;   /* referrence count increase by 1  */
                        return (void *)(pTmp->Start_V + phy_addr - pTmp->Start_P);
                }
                pTmp = pTmp->next;
        }
        /* not mmaped yet */
        if(fd_DOG_MEM < 0)
        {
                /* dev not opened yet, so open it */
                fd_DOG_MEM = open (dev, O_RDWR | O_SYNC);
                if (fd_DOG_MEM < 0)
                        return NULL;
        }
        /* addr align in page_size(4K) */
        phy_addr_in_page = phy_addr & PAGE_SIZE_MASK;
        page_diff = phy_addr - phy_addr_in_page;
        /* size in page_size */
        size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
        addr = mmap ((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd_DOG_MEM, phy_addr_in_page);
        if (addr == MAP_FAILED)
                return NULL;
        pNew = (TMMAP_Node_t *)malloc(sizeof(TMMAP_Node_t));
    if(NULL == pNew)
        return NULL;
        pNew->Start_P = phy_addr_in_page;
        pNew->Start_V = (unsigned int)addr;
        pNew->length = size_in_page;
    pNew->refcount = 1;
        pNew->next = NULL;
        if(pTMMAPNode == NULL)
                pTMMAPNode = pNew;
        else
        {
                pTmp = pTMMAPNode;
                while(pTmp->next != NULL)
                        pTmp = pTmp->next;
                pTmp->next = pNew;
        }
        return (void *)(addr+page_diff);
}
void StartWatchDog()
{
        unsigned long         ulOld;
           void                         *pMem = NULL;
           //设置GPIO复用 GPIO8_7
        pMem = _memmap(0x200F0008,16);  //偏移地址 0x008
        ulOld = *(unsigned long*)pMem;
        *(unsigned long*)pMem = 0x01;
        ulOld = *(unsigned long*)pMem;
        //printf(" DOG Reg %x New value:%x\n",0x01,ulOld);
        //设置GPIO为输出状态
        pMem = _memmap(0x201D0400,16);
        ulOld = *(unsigned long*)pMem;
        *(unsigned long*)pMem = 0xFF;
        ulOld = *(unsigned long*)pMem;
        //printf(" DOG Reg %x New value:%x\n",0xFF,ulOld);
}
int _STATE_ok = true;
void FeedWatchDog()
{
        unsigned long ulOld;
        void *pMem = NULL;
        pMem = _memmap(0x201D0200,16); //GPIO8_7 为0x200
        ulOld = *(unsigned long*)pMem;
        if(_STATE_ok){
                _STATE_ok = false;
                *(unsigned long*)pMem = 0xFF;
        }else{
                _STATE_ok = true;
                *(unsigned long*)pMem = 0x00;
        }
        //printf("%s %s","_DOG",_STATE_ok?"on\n":"off\n");
        ulOld = *(unsigned long*)pMem;
        //printf(" DOG Reg %x New value:%x\n",0x201D0200,ulOld);

}

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-04-15 04:20:29
认可0
本帖最后由 ngswfx 于 2016-4-15 06:55 编辑

想不到,有内存溢出,每次4K,没搞懂,还在找原因

///////////////////////////////////////////////////////////////////////////////
找到了,是自己程序的问题,代码放到一个保护程序里面,以前这个程序,半分钟才动作一次,现在要1秒钟动作一次,而且自己还弄错了,成了1秒钟动作几十次了,所以很快就增长了4K,很隐蔽,这次顺便发现了



其实就是opendir 之后一定要   closedir(dir); 网上好多代码都有bug,我抄来的,以前没发现这个bug,因为文件操作不多,所以没发现。


///////////////////////////////////////检测某个程序是否在运行///////////////////////////////////////////////////
bool is_prog_run(char *App_Name)
{
        int          fd_T_RUN=NULL;
        char         full_name[1024] = {0};
        char         proc_name[1024] = {0};
        char         found_proc_name[1024] = {0};
        string         Check_If_Run_Name;
        string  other_final_name;
    long         pid;
    int         pt = 0;
    memset(full_name,0,sizeof full_name);
    memset(proc_name,0,sizeof proc_name);
    memset(found_proc_name,0,sizeof found_proc_name);
    Check_If_Run_Name =App_Name ;
    DIR         *dir=NULL;
    struct dirent *result;
    dir = opendir("/proc");
    while((result = readdir(dir)) != NULL)
    {
        if (!strcmp(result->d_name, ".") || !strcmp(result->d_name, "..") || !strcmp(result->d_name, "self") || atol(result->d_name) == pid)
            continue;
        memset(full_name, 0, sizeof(full_name));
        memset(proc_name, 0 ,sizeof(proc_name));
        sprintf(full_name, "/proc/%s/cmdline", result->d_name);
        if (access(full_name, F_OK) == 0) {
                fd_T_RUN = open(full_name,O_RDONLY);
            if (fd_T_RUN == -1)
                continue;
            read(fd_T_RUN, proc_name, 1024);
            close(fd_T_RUN);
            fd_T_RUN=NULL;
            char *q = proc_name;
            pt = 0;
            memset(found_proc_name, 0, sizeof(found_proc_name));
            while(*q != ' ' && *q != '\0') {
                    found_proc_name[pt] = *q;
                q++;
                pt++;
            }
            other_final_name = basename(found_proc_name);
            if (Check_If_Run_Name == other_final_name){
                    closedir(dir);
                    dir=NULL;
                return true;
            }
        }
    }
    return false;
}

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-04-15 06:59:54
认可0
:lol

再次感谢楼主,不但帮我搞定了狗,还发现了虫子

kent_ly

0个粉丝

8

问答

0

专栏

0

资料

kent_ly 2017-03-03 00:38:29
认可0
学习一下,不错的文章

lianiq

0个粉丝

0

问答

0

专栏

0

资料

lianiq 2017-09-22 09:50:26
认可0
下载下来学习一下

hero

0个粉丝

1

问答

0

专栏

0

资料

hero 2017-09-22 11:24:42
认可0
学习一下,不错的文章
加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区