QT移植到海思平台上步骤-程序员宅基地

技术标签: 操作系统  嵌入式  

刚刚移植完海思。趁新鲜,赶紧写博客记录一下。

刚换新公司,老公司用的平台都是三星的,对Qt等支持都非常好,不需要太多操心。

新公司采用的是海思的平台,自带pdf是没有说明如何使用QT。

QT版本采用Qt4.5.3 

海思使用的是Hi3520D。

首先要安装海思的SDK

1、hi3520D SDK包位置
在"hi3520D_V100R001***/01.software/board"目录下,您可以看到一个 hi3520D_SDK_Vx.x.x.x.tgz 的文件,
该文件就是hi3520D的软件开发包。

2、解压缩SDK包
在linux服务器上(或者一台装有linux的PC上,主流的linux发行版本均可以),使用命令:tar -zxf hi3520D_SDK_Vx.x.x.x.tgz ,
解压缩该文件,可以得到一个hi3520D_SDK_Vx.x.x.x目录。

3、展开SDK包内容
返回hi3520D_SDK_Vx.x.x.x目录,运行./sdk.unpack(请用root或sudo权限执行)将会展开SDK包打包压缩存放的内容,请按照提示完成操作。
如果您需要通过WINDOWS操作系统中转拷贝SDK包,请先运行./sdk.cleanup,收起SDK包的内容,拷贝到新的目录后再展开。

4、在linux服务器上安装交叉编译器
1)安装uclibc交叉编译器(注意,需要有sudo权限或者root权限):
进入hi3520D_SDK_Vx.x.x.x/osdrv/toolchain/arm-hisiv100nptl-linux目录,运行chmod +x cross.install,然后运行./cross.install即可。
2) 安装glibc交叉编译器(注意,需要有sudo权限或者root权限,暂时不支持glibc版本):
进入hi3520D_SDK_Vx.x.x.x/osdrv/toolchain/arm-hisiv200-linux目录,运行chmod +x cross.install,然后运行./cross.install即可。
3) 执行source /etc/profile, 安装交叉编译器的脚本配置的环境变量就可以生效了,或者请重新登陆也可。

然后是编译QT

一、移植Qt4.5.3
 1、获得 Qt4.5.3 的源代码Qt4.5.3源代码的原始包 qt-embedded-opensource-src-4.5.3.tar.gz 将其拷贝到 /opt 下,
    然后在linux终端上输入如下命令(不用键入#),在/opt/下解压Qt4.5.3的源码包
    # cd /opt/
    # tar xvzf /opt/qt-embedded-opensource-src-4.5.3.tar.gz


 2、交叉编译Qt4.5.3
    2.1、#vim mkspecs/qws/linux-arm-g++/qmake.conf,把所有的arm-linux-**改为arm-hisiv100nptl-linux-**


    2.2、#vim examples/examples.pro,
    删除行
    contains(QT_CONFIG, webkit): SUBDIRS += webkit
    否则编译example webkit时会报错


    2.3、#vim demos/demos.pro,
    删除两行
    contains(QT_CONFIG, webkit):contains(QT_CONFIG, svg):SUBDIRS += demos_browser
    demos_browser.subdir = browser
    否则编译demo browser会出错


    问题:
    The tslib functionality test failed!You might need to modify the include and library search paths by editing QMAKE_INCDIR and QMAKE_LIBDIR in...


    2.4、tslib安装路径,注意tslib需交叉编译成功
    在../qt-embedded-linux-opensource-src-4.5.3/mkspecs/qws/linux-arm-g++/qmake.conf文件中加入tslib的安装路径
    QMAKE_INCDIR =/home/littlecc/qt/tslib/tmp/include   //这是我tslib安装路径
    QMAKE_LIBDIR =/home/littlecc/qt/tslib/tmp/lib


    当然也可在./configure里加入-I/=/usr/local/tslib/include -L=/usr/local/tslib/lib来解决问题,
    在./configure选项里加入-verbose,这样可以比较详细地告诉你错误的原因
    
    注意:后面设置环境变量时会用到这个路径 /opt/Qt4.5.3
 
 2.5、执行configure进行配置
  ./configure --prefix=/opt/Qt4.5.3 -no-pch -xplatform qws/linux-arm-g++ -arch arm -embedded arm -no-freetype -qt-mouse-pc -no-webkit -no-largefile -fast -release -no-qt3support -no-cups  -no-opengl -no-phonon -phonon-backend -no-scripttools -no-libtiff -no-gif -no-libmng -no-nis -no-cups -no-svg  
       
       
选择:    
    o
    yes
    
    上面的主要参数含义说明如下:
    -prefix /opt/Qt4.5.3: 表示Qt4.5.3最终的安装路径是 /opt/Qt4.5.3 ,注意,部置到开
    发板时,也需要把Qt4.5.3放在这个路径上;
    -no-pch
    -xplatform qws/linux-arm-g++: 表示使用arm-linux交叉编译器进行编译;
    -arch arm
    -embedded arm: 表示将编译针对arm平台的embedded版本;
    -no-freetype
    -qt-mouse-pc
    -no-webkit


    -qt-mouse-tslib: 表示将使用tslib来驱动触摸屏;
    -opensource
    -qt-libtiff
    -qt-libmng
    -qt-mouse-tslib
    -no-mouse-linuxtp
    -no-neon


    执行以下命令进行编译并安装Qt4.5.3:
    # make && make install
    上面命令中出现的&&符号表示只有左边的make 命令执行成功时(返回0),才会执行右边的make
    install命令。
    编译完成后,Qt4.5.3被安装在 /opt/Qt4.5.3 目录下


    提高编译速度:
    使用选项-nomake examples –nomake demos –nomaketools过滤掉例子、演示和工具目录,他们不进行编译。   
    
    
3、环境搭建
    3.1、
    libstdc++.so.6 libstdc++.so.6.0.3并复制到海思开发板文件系统/lib下;
    交叉工具链的安装目录搜索libgcc_s.so libgcc_s.so.1并复制到海思开发板文件系统/lib下;(测试中只用到了libstdc++.so.6库)


    3.2、挂载调试
    将编译出来的qt库复制到我的挂载目录下
    cp /opt/Qt4.5.3  /home/littlecc/        
   
    做一下软连接,将库连接到海思开发板文件系统/opt目录下,为什么呢因为我们配置的时候 -prefix /opt/Qt4.5.3就是这个目录,不然会出错
    ln -s /mnt/Qt4.5.3 /opt/Qt4.5.3


    3.3
    设置环境变量 直接修改海思开发板/etc/profile文件
    vi /etc/profile
    添加如下:
    QTDIR=/opt/Qt4.5.3      //路径一定要设置对不然程序运行不了
    PATH=$QTDIR/bin:$PATH
    TSLIB_CONSOLEDEVICE=none
    LD_LIBRARY_PATH=$T_ROOT/lib:$QTDIR/lib


    以上四句为环境变量声明,网上很多文章中都还有声明QWS_MOUSE_PROTO、TSLIB_FBDEVICE等,建议不要声明这些变量,
    因为qt会自动匹配相关的鼠标设备和framebuffer设备,有时候声明了反而会影响鼠标的正常工作,我的framebuffer和鼠标设备符分别为/dev/fb0和/dev/mice,
    QT可以自动识别,确保起见,不是这两个名称的宁可用ln -s做一下软链接,也不要随便去设置环境变量


    此时,就可以测试运行一下了,首先运行一下海思SDK中mpp/sample下的hifb测试程序,把framebuffer 0打开,再运行qt的各个example和demo


    ./sample_hifb &
    保证此时可以在显示器上看到测试画面,保证VGA芯片驱动及framebuffer驱动加载运行正确,然后,
    cd /opt/Qt4.5.3/demos/chip/
    ./chip -qws
    即可在显示器上看到QT的测试画面效果;

  我在这一步出现了比较大的问题,我解决的办法是改写了sample_hifb源程序,下面会有改写后的源程序放出。

    如果运行过程中提示“QFontEngineQPF failed”字样,把src/gui/text/qfontdatabase_qws.cpp打开做一下空写操作,然后重新上面所有步骤再编译一遍即可,原因未明。


    注意:
    问题一:/dev/fb0 打开失败问题
    由于海思在操作Framebuffer需要进行相应的配置,如果没有进行相应的配置,那么去打开/dev/fb0是会报错的。
    具体进行了如下两个操作步骤:


    (1)、初始化MPP
    (2)、使能输出设备VO
    经过了以上两个步骤以后,打开/dev/fb0才不会出错

我对海思的MPP不是很熟,辛亏有人帮助下才完成这份改写。

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

#include <sys/poll.h>

#include <sys/time.h>

#include <sys/mman.h>   //mmap

#include <fcntl.h>

#include <errno.h>

#include <pthread.h>

#include <assert.h>

#include <signal.h>



#include "sample_comm.h"

#include "mpi_vb.h"

#include "mpi_sys.h"

#include "mpi_venc.h"

#include "mpi_vi.h"

#include "mpi_vo.h"

#include "mpi_region.h"

#include "hi_tde_api.h"

#include "hi_tde_type.h"

#include "hi_tde_errcode.h"





#include <linux/fb.h>

#include "hifb.h"







static VO_DEV VoDev = SAMPLE_VO_DEV_DHD0;

typedef struct hiPTHREAD_HIFB_SAMPLE

{

    int fd;

    int layer;

    int ctrlkey;

}PTHREAD_HIFB_SAMPLE_INFO;



static struct fb_bitfield g_r16 = {10, 5, 0};

static struct fb_bitfield g_g16 = {5, 5, 0};

static struct fb_bitfield g_b16 = {0, 5, 0};

static struct fb_bitfield g_a16 = {15, 1, 0};

#define HIFB_LAYER_0 0

#define HIFB_LAYER_1 1

#define HIFB_LAYER_2 2

#define HIFB_LAYER_3 3

#define HIFB_LAYER_4 4

#define HIFB_LAYER_CURSOR_0 5

#define HIFB_LAYER_CURSOR_1 6





int main(int argc, char *argv[])

{



    struct fb_fix_screeninfo fix;

    struct fb_var_screeninfo var;

    HI_U32 u32FixScreenStride = 0;

    unsigned char *pShowScreen;

    PTHREAD_HIFB_SAMPLE_INFO stInfo;

    HIFB_ALPHA_S stAlpha;

    HIFB_POINT_S stPoint = {0, 0};

    char file[12] = "/dev/fb0";

    HI_BOOL g_bCompress = HI_FALSE;

    HI_BOOL bShow;

    HIFB_COLORKEY_S stColorKey;



    PTHREAD_HIFB_SAMPLE_INFO *pstInfo;

    HIFB_LAYER_INFO_S* pstLayerInfo;



    VO_PUB_ATTR_S stPubAttr;

    VB_CONF_S stVbConf;

    HI_S32 s32Ret = HI_SUCCESS;

    HI_S32 i;

    SAMPLE_VI_MODE_E enViMode = SAMPLE_VI_MODE_1_D1;

    SAMPLE_VO_MODE_E stVoMode = VO_MODE_1MUX;



    memset(&stVbConf, 0, sizeof(VB_CONF_S));

    stVbConf.u32MaxPoolCnt             = 16;

    stVbConf.astCommPool[0].u32BlkSize = 720*576*2;

    stVbConf.astCommPool[0].u32BlkCnt  = 16;



    stPubAttr.u32BgColor = 0xff00ff00;

    stPubAttr.enIntfType = VO_INTF_VGA;

    stPubAttr.enIntfSync = VO_OUTPUT_720P50;

    stPubAttr.bDoubleFrame = HI_FALSE;



    if(HI_SUCCESS != SAMPLE_COMM_SYS_Init(&stVbConf))

    {

        printf("func:%s,line:%d\n", __FUNCTION__, __LINE__);

        return -1;

    }

    printf("SAMPLE_COMM_SYS_Init success\n");

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

    1 start Vi

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

    s32Ret = SAMPLE_COMM_VI_Start(enViMode, VIDEO_ENCODING_MODE_PAL);

    if (HI_SUCCESS != s32Ret)

    {

        printf("%s: Start Vi failed!\n", __FUNCTION__);

        SAMPLE_COMM_SYS_Exit();

        return -1;

    }

 printf("SAMPLE_COMM_VI_Start success\n");

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

    2 start HD

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

    HI_MPI_SYS_Init();

    s32Ret = SAMPLE_COMM_VO_StartDevLayer(VoDev,&stPubAttr,25);

    if (HI_SUCCESS != s32Ret)

    {

        printf("%s: Start DevLayer failed!\n", __FUNCTION__);

        SAMPLE_COMM_SYS_Exit();

        return -1;

    }

printf("SAMPLE_COMM_VO_StartDevLayer success\n");

    if(HI_SUCCESS != SAMPLE_COMM_VO_StartChn(VoDev, &stPubAttr, stVoMode))

    {

        printf("%s: Start VOChn failed!\n", __FUNCTION__);

        SAMPLE_COMM_SYS_Exit();

        return -1;

    }



    /* if it's displayed on HDMI, we should start HDMI */

    if (stPubAttr.enIntfType & VO_INTF_HDMI)

    {

        if (HI_SUCCESS != SAMPLE_COMM_VO_HdmiStart(stPubAttr.enIntfSync))

        {

            printf("%s: Start HDMI failed!\n", __FUNCTION__);

            SAMPLE_COMM_SYS_Exit();

            return -1;

        }

    }



    for(i=0; i<4; i++)

    {

        s32Ret = SAMPLE_COMM_VO_BindVi(VoDev, i, i);

        if (HI_SUCCESS != s32Ret)

        {

            printf("%s: VI Bind to VO failed!\n", __FUNCTION__);

            SAMPLE_COMM_SYS_Exit();

            return -1;

        }

    }



//    if (tp_comm_semInit(&initFb, 0) < 0)

//    {

//        error_Printf("tp_comm_createSem()");

//    }

    pstInfo = &stInfo;

    /*start hifb                       */

    pstInfo->layer   =  0;  //yangcx 0;*(int *)param1;

    pstInfo->fd      = -1;

    pstInfo->ctrlkey =  0;



    if(HI_NULL == pstInfo)

    {

        return HI_FALSE;

    }



    switch (pstInfo->layer)

    {

    case HIFB_LAYER_0 :

        strcpy(file, "/dev/fb0");

        break;

    case HIFB_LAYER_1 :

        strcpy(file, "/dev/fb1");

        break;

    case HIFB_LAYER_2 :

        strcpy(file, "/dev/fb2");

        break;

    case HIFB_LAYER_3 :

        strcpy(file, "/dev/fb3");

        break;

    case HIFB_LAYER_4 :

        strcpy(file, "/dev/fb4");

        break;

    case HIFB_LAYER_CURSOR_0 :

        strcpy(file, "/dev/fb5");

        break;

    case HIFB_LAYER_CURSOR_1 :

        strcpy(file, "/dev/fb6");

        break;

    default:

        strcpy(file, "/dev/fb0");

        break;

    }



    /* 1. open framebuffer device overlay 0 */

    pstInfo->fd = open(file, O_RDWR, 0);



    if (pstInfo->fd < 0)

    {

        printf("open %s failed!\n",file);

        return HI_FALSE;

    }

    else

    {

        printf("open %s successfully!\n",file);

    }



    if (pstInfo->layer == HIFB_LAYER_0)// && pstInfo->layer <= HIFB_LAYER_4

    {

        if (ioctl(pstInfo->fd, FBIOPUT_COMPRESSION_HIFB, &g_bCompress) < 0)

        {

            printf("Func:%s line:%d FBIOPUT_COMPRESSION_HIFB failed!\n",

                   __FUNCTION__, __LINE__);

            close(pstInfo->fd);

            return HI_FALSE;

        }

        else

        {

            printf("Func:%s line:%d FBIOPUT_COMPRESSION_HIFB successfully!\n",

                   __FUNCTION__, __LINE__);

        }

    }



    bShow = HI_FALSE;

    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)

    {

        printf("FBIOPUT_SHOW_HIFB failed!\n");

        return HI_FALSE;

    }



    /* 2. set the screen original position */

    switch(pstInfo->ctrlkey)

    {

    case 0:

    {

        stPoint.s32XPos= 0;

        stPoint.s32YPos = 0;

    }

        break;

        

    case 1:

    {

        stPoint.s32XPos = 150;

        stPoint.s32YPos = 350;

    }

        break;

        

    case 2:

    {

        stPoint.s32XPos = 384;

        stPoint.s32YPos = 100;

    }

        break;



    case 3:

    {

        stPoint.s32XPos = 150;

        stPoint.s32YPos = 150;

    }

        break;



    default:

    {

        stPoint.s32XPos = 0;

        stPoint.s32YPos = 0;

    }

    }



    if (ioctl(pstInfo->fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)

    {

        printf("set screen original show position failed!\n");

        close(pstInfo->fd);

        return HI_FALSE;

    }

    printf("set screen original show position successfully!\n");



    /* 3.set alpha */

    stAlpha.bAlphaEnable = HI_TRUE;

    stAlpha.bAlphaChannel = HI_TRUE;

    stAlpha.u8Alpha0 = 0xff;

    stAlpha.u8Alpha1 = 0xff;

    stAlpha.u8GlobalAlpha = 0xff;



    if (ioctl(pstInfo->fd, FBIOPUT_ALPHA_HIFB,  &stAlpha) < 0)

    {

        printf("Set alpha failed!\n");

        close(pstInfo->fd);

        return HI_FALSE;

    }



    if(pstInfo->layer == HIFB_LAYER_CURSOR_0 || pstInfo->layer == HIFB_LAYER_CURSOR_1)

    {

        stColorKey.bKeyEnable = HI_TRUE;

        stColorKey.u32Key = 0x0;



        if (ioctl(pstInfo->fd, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)

        {

            printf("FBIOPUT_COLORKEY_HIFB!\n");

            close(pstInfo->fd);

            return HI_FALSE;

        }

    }



    /* 4. get the variable screen info */

    if (ioctl(pstInfo->fd, FBIOGET_VSCREENINFO, &var) < 0)

    {

        printf("Get variable screen info failed!\n");

        close(pstInfo->fd);

        return HI_FALSE;

    }



    /* 5. modify the variable screen info

          the pixel format: ARGB8888

    */



    switch(pstInfo->ctrlkey)

    {

//    case 0:

//    {

//        var.xres_virtual = 1280;

//        var.yres_virtual = 1024;

//        var.xres = 1280;

//        var.yres = 1024;

//    }

//        break;

        

//    case 1:

//    {

//        var.xres_virtual = 100;

//        var.yres_virtual = 100;

//        var.xres = 100;

//        var.yres = 100;

//    }

//        break;

        

//    case 2:

//    {

//        var.xres_virtual = 200;

//        var.yres_virtual = 200;

//        var.xres = 200;

//        var.yres = 200;

//    }

//        break;



    case 3:

    {

        var.xres_virtual = 48;

        var.yres_virtual = 48;

        var.xres = 48;

        var.yres = 48;

    }

        break;

        

    default:

    {

        var.xres_virtual = 1280;

        var.yres_virtual = 720*2;

        var.xres = 1280;

        var.yres = 720;

    }

    }



    var.transp= g_a16;

    var.red = g_r16;

    var.green = g_g16;

    var.blue = g_b16;

    var.bits_per_pixel = 16;

    var.activate = FB_ACTIVATE_NOW;



    /* 6. set the variable screeninfo */

    if (ioctl(pstInfo->fd, FBIOPUT_VSCREENINFO, &var) < 0)

    {

        printf("Put variable screen info failed!\n");

        close(pstInfo->fd);

        return HI_FALSE;

    }

    printf("Put variable screen info successfully!\n");



//    /* add. get the layer info */

//    if(ioctl(pstInfo->fd, FBIOGET_LAYER_INFO, pstLayerInfo) < 0)

//    {

//        printf("Get LAYER INFO failed!\n");

//        close(pstInfo->fd);

//        return HI_FALSE;

//    }



//    pstLayerInfo->BufMode = HIFB_LAYER_BUF_ONE;

//    pstLayerInfo->bPreMul = HI_TRUE;

//    pstLayerInfo->eAntiflickerLevel = HIFB_LAYER_ANTIFLICKER_AUTO;

//    if(ioctl(pstInfo->fd, FBIOPUT_LAYER_INFO, pstLayerInfo) < 0)

//    {

//        printf("PUT LAYER INFO failed!\n");

//        close(pstInfo->fd);

//        return HI_FALSE;

//    }



    /* 7. get the fix screen info */

    if (ioctl(pstInfo->fd, FBIOGET_FSCREENINFO, &fix) < 0)

    {

        printf("Get fix screen info failed!\n");

        close(pstInfo->fd);

        return HI_FALSE;

    }



    u32FixScreenStride = fix.line_length;   /*fix screen stride*/



    /* 8. map the physical video memory for user use */

    printf("this come from %s, fix.smem_len is %d\n", __func__, fix.smem_len);

    pShowScreen = (unsigned char *)mmap(HI_NULL, fix.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, pstInfo->fd, 0);



    if(MAP_FAILED == pShowScreen)

    {

        printf("mmap framebuffer failed!\n");

        close(pstInfo->fd);

        return HI_FALSE;

    }

    printf("mmap framebuffer successfully!\n");



    //        memset(pShowScreen, 0x83E0, fix.smem_len);

    memset(pShowScreen, 0, fix.smem_len);



    /* time to paly*/

    bShow = HI_TRUE;

    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)

    {

        printf("FBIOPUT_SHOW_HIFB failed!\n");

        munmap(pShowScreen, fix.smem_len);

        return HI_FALSE;

    }

    printf("FBIOPUT_SHOW_HIFB successfully!\n");



    printf("Initialize hifb successfully !!!\n");

    //tp_comm_semPost(&initFb);



    if(pstInfo->ctrlkey == 0)

    {

        while(1)

        {

            usleep(100);

        }

    }



    /* unmap the physical memory */

    munmap(pShowScreen, fix.smem_len);



    bShow = HI_FALSE;

    if (ioctl(pstInfo->fd, FBIOPUT_SHOW_HIFB, &bShow) < 0)

    {

        printf("FBIOPUT_SHOW_HIFB failed!\n");

        return HI_FALSE;

    }



    close(pstInfo->fd);



    return HI_SUCCESS;

}

  

 

转载于:https://www.cnblogs.com/plmmlp09/p/4434343.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33747129/article/details/94747748

智能推荐

稀疏编码的数学基础与理论分析-程序员宅基地

文章浏览阅读290次,点赞8次,收藏10次。1.背景介绍稀疏编码是一种用于处理稀疏数据的编码技术,其主要应用于信息传输、存储和处理等领域。稀疏数据是指数据中大部分元素为零或近似于零的数据,例如文本、图像、音频、视频等。稀疏编码的核心思想是将稀疏数据表示为非零元素和它们对应的位置信息,从而减少存储空间和计算复杂度。稀疏编码的研究起源于1990年代,随着大数据时代的到来,稀疏编码技术的应用范围和影响力不断扩大。目前,稀疏编码已经成为计算...

EasyGBS国标流媒体服务器GB28181国标方案安装使用文档-程序员宅基地

文章浏览阅读217次。EasyGBS - GB28181 国标方案安装使用文档下载安装包下载,正式使用需商业授权, 功能一致在线演示在线API架构图EasySIPCMSSIP 中心信令服务, 单节点, 自带一个 Redis Server, 随 EasySIPCMS 自启动, 不需要手动运行EasySIPSMSSIP 流媒体服务, 根..._easygbs-windows-2.6.0-23042316使用文档

【Web】记录巅峰极客2023 BabyURL题目复现——Jackson原生链_原生jackson 反序列化链子-程序员宅基地

文章浏览阅读1.2k次,点赞27次,收藏7次。2023巅峰极客 BabyURL之前AliyunCTF Bypassit I这题考查了这样一条链子:其实就是Jackson的原生反序列化利用今天复现的这题也是大同小异,一起来整一下。_原生jackson 反序列化链子

一文搞懂SpringCloud,详解干货,做好笔记_spring cloud-程序员宅基地

文章浏览阅读734次,点赞9次,收藏7次。微服务架构简单的说就是将单体应用进一步拆分,拆分成更小的服务,每个服务都是一个可以独立运行的项目。这么多小服务,如何管理他们?(服务治理 注册中心[服务注册 发现 剔除])这么多小服务,他们之间如何通讯?这么多小服务,客户端怎么访问他们?(网关)这么多小服务,一旦出现问题了,应该如何自处理?(容错)这么多小服务,一旦出现问题了,应该如何排错?(链路追踪)对于上面的问题,是任何一个微服务设计者都不能绕过去的,因此大部分的微服务产品都针对每一个问题提供了相应的组件来解决它们。_spring cloud

Js实现图片点击切换与轮播-程序员宅基地

文章浏览阅读5.9k次,点赞6次,收藏20次。Js实现图片点击切换与轮播图片点击切换<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <script type="text/ja..._点击图片进行轮播图切换

tensorflow-gpu版本安装教程(过程详细)_tensorflow gpu版本安装-程序员宅基地

文章浏览阅读10w+次,点赞245次,收藏1.5k次。在开始安装前,如果你的电脑装过tensorflow,请先把他们卸载干净,包括依赖的包(tensorflow-estimator、tensorboard、tensorflow、keras-applications、keras-preprocessing),不然后续安装了tensorflow-gpu可能会出现找不到cuda的问题。cuda、cudnn。..._tensorflow gpu版本安装

随便推点

物联网时代 权限滥用漏洞的攻击及防御-程序员宅基地

文章浏览阅读243次。0x00 简介权限滥用漏洞一般归类于逻辑问题,是指服务端功能开放过多或权限限制不严格,导致攻击者可以通过直接或间接调用的方式达到攻击效果。随着物联网时代的到来,这种漏洞已经屡见不鲜,各种漏洞组合利用也是千奇百怪、五花八门,这里总结漏洞是为了更好地应对和预防,如有不妥之处还请业内人士多多指教。0x01 背景2014年4月,在比特币飞涨的时代某网站曾经..._使用物联网漏洞的使用者

Visual Odometry and Depth Calculation--Epipolar Geometry--Direct Method--PnP_normalized plane coordinates-程序员宅基地

文章浏览阅读786次。A. Epipolar geometry and triangulationThe epipolar geometry mainly adopts the feature point method, such as SIFT, SURF and ORB, etc. to obtain the feature points corresponding to two frames of images. As shown in Figure 1, let the first image be ​ and th_normalized plane coordinates

开放信息抽取(OIE)系统(三)-- 第二代开放信息抽取系统(人工规则, rule-based, 先抽取关系)_语义角色增强的关系抽取-程序员宅基地

文章浏览阅读708次,点赞2次,收藏3次。开放信息抽取(OIE)系统(三)-- 第二代开放信息抽取系统(人工规则, rule-based, 先关系再实体)一.第二代开放信息抽取系统背景​ 第一代开放信息抽取系统(Open Information Extraction, OIE, learning-based, 自学习, 先抽取实体)通常抽取大量冗余信息,为了消除这些冗余信息,诞生了第二代开放信息抽取系统。二.第二代开放信息抽取系统历史第二代开放信息抽取系统着眼于解决第一代系统的三大问题: 大量非信息性提取(即省略关键信息的提取)、_语义角色增强的关系抽取

10个顶尖响应式HTML5网页_html欢迎页面-程序员宅基地

文章浏览阅读1.1w次,点赞6次,收藏51次。快速完成网页设计,10个顶尖响应式HTML5网页模板助你一臂之力为了寻找一个优质的网页模板,网页设计师和开发者往往可能会花上大半天的时间。不过幸运的是,现在的网页设计师和开发人员已经开始共享HTML5,Bootstrap和CSS3中的免费网页模板资源。鉴于网站模板的灵活性和强大的功能,现在广大设计师和开发者对html5网站的实际需求日益增长。为了造福大众,Mockplus的小伙伴整理了2018年最..._html欢迎页面

计算机二级 考试科目,2018全国计算机等级考试调整,一、二级都增加了考试科目...-程序员宅基地

文章浏览阅读282次。原标题:2018全国计算机等级考试调整,一、二级都增加了考试科目全国计算机等级考试将于9月15-17日举行。在备考的最后冲刺阶段,小编为大家整理了今年新公布的全国计算机等级考试调整方案,希望对备考的小伙伴有所帮助,快随小编往下看吧!从2018年3月开始,全国计算机等级考试实施2018版考试大纲,并按新体系开考各个考试级别。具体调整内容如下:一、考试级别及科目1.一级新增“网络安全素质教育”科目(代..._计算机二级增报科目什么意思

conan简单使用_apt install conan-程序员宅基地

文章浏览阅读240次。conan简单使用。_apt install conan