内容简介

介绍如何利用CSR102x tools下的API来开发自己的量产工具。

虽然这个是针对CSR102x的,但是高通其他的蓝牙开发工具也差不多,都是提供类似于这种的API,所以,理论上也适用于其他蓝牙平台,比如CSR867x、QCC302x、QCC512x、QCC304x、QCC514x等。

不像部分原厂,会提供合适的量产工具给客户,高通的蓝牙也秉承了CSR蓝牙的一贯作风,只有提供研发使用的工具,对于产线,并不十分友好,只提供了API函数,显然,让工人去操作研发工具进行量产,绝对是做好了当炮灰准备的公司才会去冒的险。

不过原厂这么做,有好处也有坏处,坏处是增加产线成本,需要额外开发对产线工人更友好的工具。好处呢,也很明显,利用API可以制作更适合特定公司的量产工具,当然也有一个更重要的好处,就是,增加就业!增加就业!增加就业!看看外面很多专门做量产、测试软件的公司就知道了。看来,为了增加就业岗位,老外也真是操碎了心,点赞!

写此篇的另一个目的,就是官方对如何开发量产工具的技术文档真的是少的可怜,很多人都不知道如何下手。所以在这里,打算用一个小小的例子教大家入门。

测试工具

Hardware:官方CSR1020开发板

CSR102x tools:Qualcomm CSR102x tools 3.1.3

开发环境:vs2019,win10

开发语言:C++

1.      引子

在开始之前,需要安装Qualcomm CSR102x tools,然后用工具下面的任意一个工具测试开发板是否能正常联通,比如用ConfigApp:

Android 高通平台f2fs 高通api_Android 高通平台f2fs

上图中是烧录了默认gatt_server程序后的情况(蓝牙地址有改动过)。

然后打开tools的安装目录,找到API的帮助文件:

Android 高通平台f2fs 高通api_蓝牙地址的name为null_02

所有的API帮助都在这里了,码农们只能根据这个来开发自己的工具。比如本次测试用到的API在uEnergyTest.chm文档中:

Android 高通平台f2fs 高通api_蓝牙地址的name为null_03

uetCsReadItem为读取某个配置信息,比如蓝牙地址。

uetCsWriteItem为往CSR1020写入一个配置信息。

以上两个函数在uetCsFileMerge这个API下面有example(如前面的图片中有显示),开发者可以参考这些代码来写。

2.      代码编写

在visualstudio下新建一个工程,我这里直接新建了一个控制台应用程序。

拷贝CSR102xTools下面的include文件夹、lib文件夹,以及其他所有的除了exe以外的文件到工程下面。

当然这里拷贝所有的是偷懒的办法,你可以根据自己的需求拷贝必须的文件到工程中,或者,直接从工程中指定调用CSR102x Tools下的文件即可,自由发挥。

在工程属性中添加库目录为“.\lib”

Android 高通平台f2fs 高通api_Android 高通平台f2fs_04

添加依赖项uEnergyTest.lib:

Android 高通平台f2fs 高通api_蓝牙地址的name为null_05

正式添加代码如下(代码参考了uetCsFileMerge下的例子,并做适当修改):

Android 高通平台f2fs 高通api_利用java实现正弦函数的绘制_06

Android 高通平台f2fs 高通api_如何测试程序是否_07

Android 高通平台f2fs 高通api_如何测试程序是否_08

Android 高通平台f2fs 高通api_蓝牙地址的name为null_09

代码很简单,一看就懂,几个关键的地方解释一下。

1. #include"include/uEnergyTest.h"

需要包含之前拷贝的include下的对应.h文件。

2.staticconstchar* const CS_DB_FILE = "CSR102x.sdb:fht_SDK_3_1_3_335_A06_ROM_1902011404";

这个参数是在用uetOpen打开handle时需要用到的第二个参数。如何确定这个参数呢?

打开CSR102xtools下的config app这个程序,选择“file=>changesystem”:

Android 高通平台f2fs 高通api_如何测试程序是否_10

按照实际情况选择上面的参数即可。

3. int32retVal = uetOpen("SPITRANS=USB SPIPORT=0", CS_DB_FILE, &handle);

这里的关键就是uetOpne的第一个参数“”SPITRANS=USB SPIPORT=0"”,就是选择打开的参数,一般现在都是选USB,然后只有一个设备的话SPIPORT为0,如果有两个,那第二个应该是1吧,没测试,估计是这样的。

4. retVal = uetCsReadItem(handle, "1:15:2", value,&length);

这里要注意的是第二个参数,参考帮助文档:

Android 高通平台f2fs 高通api_利用java实现正弦函数的绘制_11

PSID和STORE ID可以用configapp确定:

Android 高通平台f2fs 高通api_如何测试程序是否_12

我们这次要往SMEM中写入蓝牙地址,所以PSID=1,STORE_ID=0x000F,DEVICE_ID=2,所以就有了"1:15:2"。

5. retVal =uetCsWriteItem(handle, "1:15", newValue, &length);

这里的解释跟上面的差不多,直接参考API的说明即可:

Android 高通平台f2fs 高通api_自己编写的fft程序_13

3.      测试

程序实现的功能是读取当前SMEM中的蓝牙地址,然后输入一个新蓝牙地址并且写入到SMEM中,再重新读一遍蓝牙地址。

测试前,先用config app读取一下SMEM中的蓝牙地址:

Android 高通平台f2fs 高通api_自己编写的fft程序_14

运行程序:

Android 高通平台f2fs 高通api_Android 高通平台f2fs_15

保险起见,再用config app读一遍:

Android 高通平台f2fs 高通api_Android 高通平台f2fs_16

跟我们刚刚写入的一致,测试成功。

最后附上完整的代码:

#include 
#include 
#include"include/uEnergyTest.h"
using namespace std;
int main()
{
   static const char* const CS_DB_FILE ="CSR102x.sdb:fht_SDK_3_1_3_335_A06_ROM_1902011404";
   // Open connection to device
   CsrHandle_t handle = NULL;
   int32 retVal = uetOpen("SPITRANS=USB SPIPORT=0", CS_DB_FILE,&handle);
   if (retVal == UET_OK)
   {
        cout << "transport opensuccess" << endl;
        // Read item from chip
        static const uint16 ARRAY_SIZE = 3;
        uint16 value[ARRAY_SIZE] = { 0 };
        uint16 length = ARRAY_SIZE;
        if (retVal == UET_OK)
        {
            retVal = uetCsReadItem(handle,"1:15:2", value, &length);
            if (retVal == UET_OK &&length != ARRAY_SIZE)
           {
                retVal = UET_ERR_GENERAL;
            }
            if (retVal == UET_OK)
            {
                cout << "read MACsuccess, MAC = ";
                cout << hex <
                cout << hex <
                cout << hex <
            }
            else
                cout << "read MACfail" << endl;
        }
        // Write that item with a differentvalue
        if (retVal == UET_OK)
        {
            length = ARRAY_SIZE;
            uint16 newValue[ARRAY_SIZE] = {0x2222, 0x1111, 0x0002 };
            cout << "Input newMAC:" << endl;
            cin >> hex >> newValue[0];
            cin >> hex >>newValue[1];
            cin >> hex >>newValue[2];
            retVal = uetCsWriteItem(handle,"1:15", newValue, &length);
            if (retVal == UET_OK)
                cout << "write MACsuccess, try to read it again..." << endl;
            else
                cout << "write MACfail" << endl;
        }
        //read addr once more
        if (retVal == UET_OK)
        {
            retVal = uetCsReadItem(handle,"1:15:2", value, &length);
            if (retVal == UET_OK &&length != ARRAY_SIZE)
            {
                retVal = UET_ERR_GENERAL;
            }
            if (retVal == UET_OK)
            {
                cout << "read MACsuccess, new MAC = ";
                cout << hex <
                cout << hex <
                cout << hex <
            }
            else
                cout << "read newMAC fail" << endl;
        }
        retVal = uetClose(handle);
   }
   else
   {
        cout << "port open failed" << endl;
   }
   return 0;
}