Skip to content

# 10.4. PCIe 用户态 High Level API介绍

## 10.4.1. 简介

High Level API (libhbpciehl.so) 基于 Low Level API（libhbpcie.so)，抽象出通用的 topic / subscribe / publish 概念，屏蔽不同系列地平线芯片的硬件差异，让用户能够更加便捷的使用 PCIe 进行数据通信。

主要支持如下功能：

- 数据的发送（publish）

- 数据的接收（subscribe）

- 发送/接收Buffer的管理

  - 使用内建buffer

  - 使用用户申请的buffer(要求物理地址连续）

## 10.4.2. API列表

    pcieErrCode pcieInit(pcieHandler *ph, uint8_t chipID, uint8_t topicID);
    pcieErrCode pcieDeInit(pcieHandler ph);
    pcieErrCode pcieGetMaxTopicSize(pcieHandler ph, uint8_t *topicSize);
    pcieErrCode pciePublish(pcieHandler ph, uint8_t weight);
    pcieErrCode pcieSubscribe(pcieHandler ph);
    pcieErrCode pcieGetMaxInnerBufSize(pcieHandler ph, uint32_t *size);
    pcieErrCode pcieAllocInnerBuf(pcieHandler ph, uint32_t size, void **virtualAddr, uint64_t *physAddr);
    pcieErrCode pcieRegisterUserBuf(pcieHandler ph, uint64_t physAddr, uint32_t size);
    pcieErrCode pcieStartRecv(pcieHandler ph, recvDataCallBack fun, void *funData);
    pcieErrCode pcieSendData(pcieHandler ph, uint32_t size);

详细API说明参考 地平线底层接口手册

## 10.4.3. 使用流程

发送方和接收方的流程如下图：

### 10.4.3.1. Publisher(chip#0)

     1void main()
     2{
     3    uint32_t size;
     4    void *addr;
     5    uint64_t phys;
     6    pcieHandler ph;
     7    void *UserBuffer;
     8    uint64_t UserBufferPhys;
     9
    10    /* connect chip1 topic0 */
    11    pcieInit(&ph, 1, 0);
    12
    13    pciePublish(ph);
    14
    15    if (useInnerBuffer) {
    16        pcieGetMaxInnerBufSize(ph, &size);
    17        pcieAllocInnerBuf(ph, &addr, &phys, size);
    18        /* fill user data to inner buffer */
    19        ...
    20
    21    } else {
    22        /* prepare the User data */
    23        ...
    24        /* use data in user buffer */
    25        pcieRegisterUserBuf(ph, UserBufferPhys, size);
    26    }
    27
    28    pcieSendData(ph, size);
    29
    30    pcieDeInit(ph);
    31
    32    return;
    33}

### 10.4.3.2. Subscriber(chip#1)

     1void recvDataHandler(pcieHandler ph, uint32_t RecvSize, void *pData)
     2{
     3    /* deal with the received data */
     4    ...
     5}
     6
     7void main()
     8{
     9    void *pData;
    10    pcieHandler ph;
    11    uint32_t size;
    12    void *addr;
    13    uint64_t phys;
    14
    15    /* connect chip0 topic0 */
    16    pcieInit(&ph, 0, 0);
    17
    18    pcieSubscribe(ph);
    19
    20    if (useInnerBuffer) {
    21        pcieGetMaxInnerBufSize(ph, &size);
    22        pcieAllocInnerBuf(ph, &addr, &phys, size);
    23    } else {
    24        /* alloc user buff */
    25        ...
    26        pcieRegisterUserBuf(ph, UserBufferPhys, size);
    27    }
    28
    29    pcieStartRecv(ph, recvDataHandler, pData);
    30
    31    /* wait for receiving data */
    32    while (1) {
    33        sleep(1);
    34    }
    35
    36    pcieDeInit(ph);
    37
    38    return;
    39}

## 10.4.4. 测试程序说明

`hbpciehl_test` 主要用于High Level API的简单功能测试。

    root@j5dvb:~# hbpciehl_test -h
    hbpciehl_test v1.0 - Hobot PCIe High Level API tester
    USAGE:
    hbpciehl_test [options]
    options:
     -c <chipID>: remote chip ID
     -p <topicID>: Publish with topicID
     -s <topicID>: Subscribe with topicID
     -u <size>: use user buffer instead of the inner buffer for send/receive
     -l <count>: Send/Reveive count
     -v verify data
     -t show transfer speed
     -h show help