gscoolink:gsv2001的sdk移植

1 前言

  以gsv的sdk的应用代码为例,将应用代码从m0核移植到m1核的mcu上;

  因为用的是hal库,所以互相移植修改的并不多;实际改个头文件就可以编译了;

  虽然我hal库用的是m1核的hal库,但是实际上我直接啥也没改,跑在m4核的gdf303上也没啥问题;

2 修改项目名

  修改.uprojx的名字,为project名;

  manage project items >> project targets >> 修改target名为project,移植就不用再命名了;

  options for target >> output >> select folder for objects >> 选择output目录;

  options for target >> output >> name for execucutable >> 命名改为output.axf;

  options for target >> listing >> select folder for listing >> 选择listing目录,和output目录一起省的多个文件;

  options for target >>user >> run >> 

    fromelf.exe --bin -o ./releaseFile/Test1_Z_SP12CS-V2_V1.0.0a_0691_08009000.bin    ./outputFile/output.axf

    fromelf.exe --bin -o ./releaseFile/Test2_Z_SP12CS-V2_V1.0.0a_0691_08009000.bin   "#L"

3 源码包含

  3.1 包含xx.c和xx.h的文件;

    project目录下的xx.c文件在编译的时候分先后,所以要按顺序包含;

    IncludePaths框内的头文件在包含的时候也分先后,所以要按顺序包含;

    如果不按原有目录的顺序包含,会打乱编译顺序,然后会报错很多undefined的问题;这里卡了一天;

  3.2 包含gsvSDK的文件

    m0,m3,m4核的架构差别不大,加上sdk代码相当于应用层代码,和mcu的hal库以及cm核耦合性并不高;

    av_main.h和bsp.h的那几个#include "stm32f0xx.h" >> #include "stm32f1xx.h",

    还有代码中的一些GPIO寄存器设置注释掉,或者改成对应cortex的对应寄存器就行了;

    这样的话sdk基本就可以编译通过了,先编译通过先,后面再具体修改;

4 gsvSDK修改

  gsv的sdk将音视频的应用代码和bsp板间外设进行了分离,代码移植到不同板子上时只需要修改对应bsp,方便移植;

  gsv给用户封装了两个接口用来作为bsp的回调注册,那么这两个函数都是如何工作的呢?如果要移植我们都需要改啥呢?

/* 1.2 init software package and hookup user's bsp functions */
AvApiInit();
AvApiHookBspFunctions(&BspI2cRead, &BspI2cWrite, &BspUartSendByte,&BspUartGetByte, &BspGetMilliSecond, &BspGetKey, &BspIrdaGetByte);
AvApiHookUserFunctions(&ListenToKeyCommand, &ListenToUartCommand, &ListenToIrdaCommand);

  4.1 AvApiHookBspFunctions函数

/** bsp 函数指针定义 ***************************************************************************/
//hal.h    hardware access functions; cae:I would like to store definitions into uapi.h
typedef AvRet (*AvFpI2cRead)(uint32, uint32, uint8 *, uint16);
typedef AvRet (*AvFpI2cWrite)(uint32, uint32, uint8 *, uint16);
typedef AvRet (*AvFpUartSendByte)(uint8 *, uint16);
typedef AvRet (*AvFpUartGetByte)(uint8 *);
typedef AvRet (*AvFpGetMilliSecond)(uint32 *);
typedef AvRet (*AvFpGetKey)(uint8 *);
typedef AvRet (*AvFpGetIrda)(uint8 *);

//uapi.c   hal functions variables 
AvFpI2cRead        AvHookI2cRead;
AvFpI2cWrite       AvHookI2cWrite;
AvFpUartSendByte   AvHookUartTxByte;
AvFpUartGetByte    AvHookUartRxByte;
AvFpGetMilliSecond AvHookGetMilliSecond;
AvFpGetKey         AvHookGetKey;
AvFpGetIrda        AvHookGetIrda;

//uapi.h  下面的kapi.h就没有用extern;这个gsv的代码对称性不好;
extern  AvFpI2cRead        AvHookI2cRead;
extern  AvFpI2cWrite       AvHookI2cWrite;
extern  AvFpUartSendByte   AvHookUartTxByte;
extern  AvFpUartGetByte    AvHookUartRxByte;
extern  AvFpGetMilliSecond AvHookGetMilliSecond;
extern  AvFpGetKey         AvHookGetKey;
extern  AvFpGetIrda        AvHookGetIrda;

/**av_main.c >> bsp 函数指针注册 *****************************************************************/

//uapi.c  @brief  hookup user's hardware access functions
uapi AvRet AvUapiHookBspFunctions(pin AvFpI2cRead i2cRd, pin AvFpI2cWrite i2cWr, pin AvFpUartSendByte uartTxB, pin AvFpUartGetByte uartRxB, pin AvFpGetMilliSecond getMs, pin AvFpGetKey getKey,pin AvFpGetIrda getIrda)
{
    AvRet ret = AvOk;
    AvHookI2cRead = i2cRd;
    AvHookI2cWrite = i2cWr;
    AvHookUartTxByte = uartTxB;
    AvHookUartRxByte = uartRxB;
    AvHookGetMilliSecond = getMs;
    AvHookGetKey = getKey;
    AvHookGetIrda = getIrda;
    AvUapiOutputDebugMessage(" ");
    AvUapiOutputDebugMessage("-------------------------------------------------------------------");
    AvUapiOutputDebugMessage("    |> Audio/Video Software %s", AvVersion);
    AvUapiOutputDebugMessage("-------------------------------------------------------------------");
    return ret;
}

//av_main.c
AvApiHookBspFunctions(&BspI2cRead, &BspI2cWrite, &BspUartSendByte,&BspUartGetByte, &BspGetMilliSecond, &BspGetKey, &BspIrdaGetByte);

/** bsp 函数指针回调******************************************************************************/
//hal.h
#define AvI2cRead         AvHookI2cRead
#define AvI2cWrite        AvHookI2cWrite
#define AvUartTxByte      AvHookUartTxByte
#define AvUartRxByte      AvHookUartRxByte
#define AvGetMilliSecond  AvHookGetMilliSecond
#define AvGetKey          AvHookGetKey
#define AvIrdaRxByte      AvHookGetIrda

//hal.c  以重新封装的Avxx宏去调用,这样就实现了bsp隔离;
AvRet AvHalI2cRead(pin uint32 devAddress, pin uint32 regAddress, pout uint8 *avdata, pin uint16 count)
{
    AvRet ret = AvOk;
    ret = AvI2cRead(devAddress, regAddress, avdata, count);
    return ret;
}

//把 &BspI2cRead 封装成 AvHookI2cRead,然后又封装成AvI2cRead; 双重封印;
//如果是我我只会封一层,这玩意干嘛要封两层?

  4.2 AvApiHookUserFunctions函数  

/**kapi.h userFunction 函数指针定义 *****************************************************************/
typedef void (*AvFpKeyCommand) (AvPort *port);
typedef void (*AvFpUartCommand) (AvPort *port);
typedef void (*AvFpIrdaCommand) (AvPort *port);

//kapi.c
AvFpKeyCommand   AvHookKeyCmd;
AvFpUartCommand  AvHookUartCmd;
AvFpIrdaCommand  AvHookIrdaCmd;

/**kapi.h userFunction 函数指针注册 *****************************************************************/
//kapi.c  @brief  hookup user layer access functions
kapi AvRet AvKapiHookUserFunctions(pin AvFpKeyCommand keyCmd, pin AvFpUartCommand uartCmd,pin AvFpIrdaCommand IrdaCmd)
{
    AvRet ret = AvOk;
    AvHookKeyCmd = keyCmd;
    AvHookUartCmd = uartCmd;
    AvHookIrdaCmd = IrdaCmd;
    return ret;
}

//av_main.c
AvApiHookUserFunctions(&ListenToKeyCommand, &ListenToUartCommand, &ListenToIrdaCommand);

/**kapi.h userFunction 函数指针回调 *****************************************************************/
//kapi.h 
#define AvUserUartCmd       AvHookUartCmd
#define AvUserKeyCmd        AvHookKeyCmd
#define AvUserIrdaCmd       AvHookIrdaCmd

//kapi.c
while(TempPort){
    /* Make Key Response and Uart Response faster */
    AvUserUartCmd(FirstPort);
    AvUserKeyCmd(FirstPort);
    AvUserIrdaCmd(FirstPort);
    //...
}

  4.3 bsp修改

    对于iic而言,软件模拟的,可以直接用gsv写的;只要改一下GPIO寄存器操作; 参考修改GPIO的IIC的CRH或CRL寄存器

    对于uart而言,注释掉gsv的bsp回调函数,使用已有的uartBsp回调;

    对于按键而言,注释掉gsv的bsp回调函数;

//kapi.h 下面的监听回调是封装在kapi.h中的;而bsp的调用宏是封装在hal.h中;
#define AvUserUartCmd       //AvHookUartCmd
#define AvUserKeyCmd        //AvHookKeyCmd
#define AvUserIrdaCmd       //AvHookIrdaCmd

//i2c.c
#define SET_SCL0_1     GPIOB->BSRR = GPIO_PIN_13           // Pin I2C_SCL
#define SET_SDA0_1     GPIOB->BSRR = GPIO_PIN_14           // Pin I2C_SDA
#define SET_SCL0_0     GPIOB->BSRR = GPIO_PIN_13<<16U      // Pin I2C_SCL
#define SET_SDA0_0     GPIOB->BSRR = GPIO_PIN_14<<16U      // Pin I2C_SDA
#define GET_SDA0       ((GPIOB->IDR & GPIO_PIN_14)? 1:0)   // Pin I2C_SDA
#define SCL0_IN        GPIOB->CRH = ( ((GPIOB->CRH)&0xff0fffff)|0x00400000 )
#define SCL0_OUT       GPIOB->CRH = ( ((GPIOB->CRH)&0xff0fffff)|0x00700000 )
#define SDA0_IN        GPIOB->CRH = ( ((GPIOB->CRH)&0xf0ffffff)|0x04000000 )
#define SDA0_OUT       GPIOB->CRH = ( ((GPIOB->CRH)&0xf0ffffff)|0x07000000 )

  4.4 printf修改

//uapi.c  本来的打印函数使用gsv的bsp的uart,改一下用printf;这样关个宏就可以了,不用改bsp;
uapi AvRet AvUapiOuputDbgMsg(pin schar *stringToFormat, ...){

    AvRet ret = AvOk;
    #if AvEnableDebugFsm
        va_list ap;
        va_start(ap, stringToFormat);
        vprintf(stringToFormat, ap);  // 使用vprintf直接打印格式化字符串
        va_end(ap);
        printf("\r\n");
    #endif
    return ret;
}

  4.5 gsvMain

    函数改成case语句,然后搞个while(1)或者task来调用即可;这样就移植完成了;

void gsv2k1_Main(void){
    static uint8_t state = 0;
    switch(state){
        case 0:
            CAE("gsv2k1_Main() ");
            GsvMain();
            state++;
        break;
        case 1:
            AvApiUpdate();
            AvPortConnectUpdate(&devices[0]);
        break;
    }
}

5 小结

  问题想清楚之后执行就好了,行动才是生产力;

  这个东西移植起来事后复盘还是比较简单的,但是移植了好几天,因为还用了一半以上时间去确认有没有遗漏;

  今天移植6k7代码用了一天;因为没有把串口打印出来,没有及时调试导致早早就飞了野指针;

  写代码还是要及时调试;

posted @ 2024-11-21 19:57  caesura_k  阅读(22)  评论(0编辑  收藏  举报