亲爱的各位嘉宾大家好,我是Self,十多年蓝牙经验,专业可靠!
蓝牙门诊部,(简称门诊)专业解客户Bug
蓝牙生产科,(简称产科)专门解决客户量产问题
以上两个部门简称:产科门诊
攻城狮每天设计,程序猿日夜奋战,终于完成蓝牙方案。俗话说十月怀胎,一朝分娩,迫在眉睫,蓝牙批量生产,这可让工厂生产小妹为难,我们连线一位工厂小妹,“客户要的太多,都要生产,客都接不过来啦”
生产订单多,我们蓝牙设备一个个下载程序,造成工厂小妹们巨大的痛楚,急需攻城狮改善量产方案,此时程序猿是刚下刀山,又进火海。后来多亏我们蓝牙生产科,批量生产一拖多!
这个设计怎么样?
客户们的需求,是否可以得到满足?
小妹们的痛楚,是否可以得到缓解?
攻城狮的理想,是否可以得到实现?
真是妙手回春!
且听我一一道来!
正所谓:蓝牙门诊部胜过铁匠铺,蓝牙生产科超越装甲车!(蓝牙门诊部与蓝牙生产科两个部门简称产科门诊)
总之:产科门诊,妙手回春
大大通独家赞助,欢迎收看!
1、一拖一 PK 一拖多
提到蓝牙生产,我们之前有很多专题,大大通搜索“蓝牙量产必备”
这里有设备信息读写的,比如名称地址修改:
文章链接:QCC512x 与QCC302X 蓝牙系列量产必备:设备信息修改
还有顺利生产的,比如 Flash 擦除操作
文章链接:QCC512x 与QCC302X 蓝牙系列量产必备:擦除Flash
也有产后修复的,比如频偏校准,
文章链接:QCC 蓝牙系列量产必备:设备频偏校准
产后修复部分后续会着重讲解,但并不是本集重点!本集主要讲解生产烧录,生产烧录可以分为两种操作:
(1)一对一操作,详见:
文章链接:QCC512x 与QCC302X 蓝牙系列量产必备:擦除Flash
(2)一托多操作, 详见
文章链接:QCC51XX 与30XX 蓝牙系列量产必备:一拖多擦除
在往期蓝牙生产科文章:QUALCOMM QCC51XX 与30XX 蓝牙系列量产必备:一拖多擦除中,我们提到电脑上最多连接几台耳机设备,烧录也是这样的!
2、开发环境与程序接口
2.1、开发环境设置
开发环境:C++(Microsoft Visual Studio)
头文件:TestFlash.h
库文件:TestFlash.lib
运行环境:Windows 系统,TestFlash.dll 相关DLL,为了使得工具能够运行,可以把TestFlash.dll 相关DLL所在文件夹路径:C:\Program Files (x86)\QTIL\BlueSuite 3.3.8,
设置成Path环境变量,这样工具程序就可以动态调用DLL相关库运行了。
2.2、Flash升级接口
QCC51XX/30XX Flash 参数 升级接口, 在我们的 Bluesuite 库 TestFlash API 中,
在Bluesuite 安装路径下面,找到TestFlash.chm
TestFlash API :flmProgramSpawn
int32 flmProgramSpawn(
uint32 deviceMask,
uint8 eraseFirst,
uint8 verifyAfter,
uint8 restartAfter
);
Parameters
deviceMask
- Specifies which devices will be programmed. See flmOpen for the details of this parameter.
- Set to 1 to erase the entire NVM of all devices before programming. Set to 0 if erase is not required.
- Set to 1 to verify the NVM contents of devices after completion of the programming process. Set to 0 if verify is not required.
- Set to 1 to restart all devices after completion of the programming process. Set to 0 if restart is not required.
其中传入的 deviceMask 一个32位的整数,每个位代表一个设备,理论上是32 台。实际上,如前所说,还要考虑供电等稳定性因素,接个十台八台耳机设备,已经够可以了
3、开发流程
3.1、程序设计
打开Microsoft Visual Studio 集成开发环境,新建Win32-> console application,输入Project名BT_Info_Mag,选择console application—>Empty project->Finish 确认。
添加 BT_Info_Mag.cpp,代码如下:详见附件源文件,登录即可下载
//BT_Info_Mag.cpp
#include "include\\testengine.h"
#include "include\\TestFlash.h"
#include "iostream"
#include"conio.h"
#include"Windows.h"
#include"tchar.h"
using namespace std;
#include "vector"
// Program 2 devices
//uint32 g_devMask = 0x3;
uint32 g_devMask=0;//升级设备的MASK,每一位代表一个设备
uint32 m_Conected_Devices=0;
//#define _Test_Engine_
/**枚举Debug 端口**/
int IGetAvailablePorts(vector& ports,vector& trans);
/**分割字串到相应的ports**/
vector split(const string &s, const string &seperator);
char sXUVFilename[]="D:\\3024.xuv";
uint8 m_eraseFirst=0;
uint8 m_verifyAfter=1;
uint8 m_restartAfter=1;
int main(int argc, char** argv){
int32 status;//是否枚举出端口
vector m_vPorts; // The human readable port strings (e.g. "USBDBG(100)")
vector m_vTrans; // The transport option strings (e.g. "SPITRANS=USBDBG SPIPORT=1")
status=IGetAvailablePorts(m_vPorts,m_vTrans);
if(status){
BYTE Bl=m_vPorts.size();
printf("DebugPorts:len:%d\n",Bl);
int i=0;
for(vector::iterator iter1=m_vPorts.begin(); iter1!=m_vPorts.end(); ++iter1 ){
g_devMask+=(1<<i);
i++;
printf("DebugPorts %d :%s\r\n",i,iter1->c_str());
}
m_Conected_Devices=i;
}
bool success = 0;
/**********************************
TestFlash Return Values
#define TFL_OK 0
#define TFL_ERROR -1
#define TFL_DEVICE_ERROR -2
#define TFL_ERROR_UNSUPPORTED -3
*****************************************/
int32 flReturn;
// Convert the port specification in to a specification suitable for multiple
// device open
// For the purposes of this example, we're just using the first in the list
char* newTransStr = new char[m_vTrans.at(0).length() + 1];
uint32 device;
status = flmConvertPort(m_vTrans.at(0).c_str(), newTransStr, &device);
if( status != TFL_OK )
{
cout << "Error converting port to transport" << endl;
delete[] newTransStr;
return status;
}
int k=0;
// Open the port using the trans string
flReturn = flmOpenTrans(g_devMask, newTransStr, 32);
while(flReturn != TFL_OK)//self
{
Sleep(1000);
flReturn = flmOpenTrans(g_devMask, newTransStr, 32);
k++;
if(k>=5){
_tprintf(_T("Failed to open TestFlash connection"));
break;
}
}
if(flReturn == TFL_OK)
{
success = true;
if (flmReadProgramFiles(sXUVFilename) != TFL_OK)
{
cout << "Failed to read flash program files" << endl;
success = false;
}
if (success && flmSetFlashType(g_devMask, TFL_TYPE_SQIF) != TFL_OK)
{
cout << "Failed to set flash type" << endl;
success = false;
}
if (success && flmSetSubsysBank(g_devMask, 4, 0) != TFL_OK)
{
cout << "Failed to set subsystem and bank" << endl;
success = false;
}
if (success && flmProgramSpawn(g_devMask, m_eraseFirst, m_verifyAfter, m_restartAfter) != TFL_OK)
{
cout << "Failed to spawn flash program thread" << endl;
success = false;
}
if (success)
{
uint16 devicesRunning;
int32 progress;
int32* progressArray= new int32[m_Conected_Devices];
do
{
devicesRunning = 0;
for (uint32 devIndex = 0; devIndex < m_Conected_Devices; ++devIndex)
{
// Only check the progress if the device is in the mask
//if ((devMask >> devIndex) & 1)
//if(m_isChecked[devIndex]==1)
{
progressArray[devIndex]=progress = flmGetDeviceProgress(devIndex);
if (progress < 100)
{
++devicesRunning;
}
cout << "dev" << devIndex << ":Programming progress = " << progress << "%" << endl;
}
}
Sleep(1000);
} while (devicesRunning > 0);
delete[] progressArray;
cout << "Completed" << endl;
int32 error = flmGetLastError();
if (error != TFL_OK)
{
cout << "Programming failed with error: " << error << ". Failed devices mask = " << flmGetBitErrorField() << endl;
success = false;
}
error=flmGetBitErrorField();
}
if (success)
{
cout << "Successfully programmed devices" << endl;
}
flmClose(g_devMask);
}
delete[] newTransStr;
}
vector split(const string &s, const string &seperator)
{
vector result;
typedef string::size_type string_size;
string_size i = 0;
while(i != s.size()){
//找到字符串中首个不等于分隔符的字母;
int flag = 0;
while(i != s.size() && flag == 0){
flag = 1;
for(string_size x = 0; x < seperator.size(); ++x)
if(s[i] == seperator[x]){
++i;
flag = 0;
break;
}
}
//找到又一个分隔符,将两个分隔符之间的字符串取出;
flag = 0;
string_size j = i;
while(j != s.size() && flag == 0){
for(string_size x = 0; x < seperator.size(); ++x)
if(s[j] == seperator[x]){
flag = 1;
break;
}
if(flag == 0)
++j;
}
if(i != j){
result.push_back(s.substr(i, j-i));
i = j;
}
}
return result;
}
int IGetAvailablePorts(vector& ports,vector& trans)
{
int32 status;
uint16 maxLen(256);
uint16 count(0);
char* portsStr = new char[maxLen];
char* transStr = new char[maxLen];
int k=0;
#if defined(_Test_Engine_)
status = teGetAvailableDebugPorts(&maxLen, portsStr, transStr, &count);
while( (status != TE_OK || count == 0))
#else
status = flGetAvailablePorts(&maxLen, portsStr, transStr, &count);
while( (status != TFL_OK || count == 0) )
#endif
{
k++;
printf("teGetAvailableDebugPorts %d 次失败\r\n",k);
Sleep(900);
#if defined(_Test_Engine_)
status = teGetAvailableDebugPorts(&maxLen, portsStr, transStr, &count);
#else
status = flGetAvailablePorts(&maxLen, portsStr, transStr, &count);
#endif
if(k>=6){
delete[] portsStr;
delete[] transStr;
return status&&count;
}
}
#if defined(_Test_Engine_)
if( status != TE_OK && maxLen != 0 )
#else
if( status != TFL_OK && maxLen != 0 )
#endif
{
// Not enough space - resize the storage
delete[] portsStr;
portsStr = new char[maxLen];
delete[] transStr;
transStr = new char[maxLen];
#if defined(_Test_Engine_)
status = teGetAvailableDebugPorts(&maxLen, portsStr, transStr, &count);
#else
status = flGetAvailablePorts(&maxLen, portsStr, transStr, &count);
#endif
}
ports=split( portsStr,(const std::string ) ","); // Use these for user selection (e.g. drop down list)
trans=split( transStr, (const std::string )","); // Use these to open a transport
delete[] portsStr;
delete[] transStr;
#if defined(_Test_Engine_)
return status&&count;
#else
return !status&&count;
#endif
}
然后把TestFlash.lib 添加进来,就可以编译通过
3.2、运行结果
QCC51Xx 与QCC30XX 系列的两块板子,通过 USB 连上PC,(限于开发板数量,我们用两台实例做演示,客户可以用八台设备的生产夹具)运行应用程序,xuv 程序升级到两块板子的Flash 中,大概需要半分钟,过程中还有下载程序的进度打印出来。
真正做到:产科门诊,妙手回春
以上是本篇博文的全部内容!
大大通方案与博文,十分精彩,引人入胜,如果不在登录状态的看官,大大通则视为“匆匆之过客”很快就“不见庐山真面目”了,看的正过瘾啊!怎么会这样,急死人了,怎么办?
各位看官!不要着急!只需一个小小的动作而已:登录!没账号咋办尼? 很简单,请扫描下面二维码注册。
而且还附带小编联系方式,各位看官,如有疑问,请在博文下方评论留言,或者私信给我,收到之后会第一时间回复哦!
想要了解更多内容,请多多关注小编与大大通平台,我们会不断分享最新的热点技术!
评论