当前位置:网站首页>CANoe不能自动识别串口号?那就封装个DLL让它必须行
CANoe不能自动识别串口号?那就封装个DLL让它必须行
2022-07-06 09:03:00 【蚂蚁小兵】
前言
比如程控电源,每个同事都需要,但是工程是同一个,那么每个同事在运行工程前,都要选择不同的串口,这就很麻烦,能否让CANoe自动识别程控电源连接在电脑上的串口号呢
CAPL操作串口的内置函数是无法自动识别串口号,经过查找资料,调用Windows 的设备 API是可以实现的,那么就想到了封装个DLL,在CANoe中调用DLL去实现目的。
演示软硬件环境
Win10 x64
;CANoe 11 SP2 x64
;Visual Studio 2019
C++调试工程
1️⃣ 老规矩,封装DLL之前咱先新建一个控制台工程用来调试代码
2️⃣ 下图,是我电脑上连着的COM
- 其中程控电源连接到电脑上的描述是
USB Serial Device (COMxx)
,那么 我就可以通过 关键字符串USB Serial Device
来实现筛选,从而返回COM号
3️⃣ 全部代码,如下:
// PrintDeviceInfo.cpp : 定义控制台应用程序的入口点。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <Windows.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi.lib")
int getSpecialComNum(const char* s, const char* t)
{
char n = t[0];
int l ,i,j, sourlen, tarlen;
char temp[200] = {
0 };
char out[200] = {
0 };
sourlen = strlen(s);
tarlen = strlen(t);
for (i = 0; i < sourlen - tarlen + 1; i++)
{
for (j = 0; j < tarlen; j++)
{
if (s[i + j] != t[j])
{
break;
}
}
if (j == tarlen)
{
return i+7; //find it
}
}
return -1;
}
//从设备信息中 获取特定串口号 @return <=0无效
int getSpecialComNumFromDevInfo(char ComList[][200] , const char* SpecialCom ,int *ComNum)
{
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("SetupDiGetClassDevs Err:%d", GetLastError());
return -2;
};
SP_CLASSIMAGELIST_DATA _spImageData = {
0 };
_spImageData.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
SetupDiGetClassImageList(&_spImageData);
SP_DEVINFO_DATA spDevInfoData = {
0 };
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
int k;
k = 0;
for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
{
char szBuf[MAX_PATH] = {
0 };
int wImageIdx = 0;
short wItem = 0;
char szBuf_byteToChar[256] = {
0 };
int j;
if (!SetupDiGetDeviceRegistryPropertyA(hDevInfo, &spDevInfoData, SPDRP_CLASS, NULL, (PBYTE)szBuf, MAX_PATH, 0))
{
continue;
};
if (strcmp(szBuf, "Ports") != 0) //只取端口
{
continue;
}
//printf("Class1:%s\r\n", szBuf);
if (SetupDiGetClassImageIndex(&_spImageData, &spDevInfoData.ClassGuid, &wImageIdx))
{
char szName[MAX_PATH] = {
0 };
DWORD dwRequireSize;
if (!SetupDiGetClassDescription(&spDevInfoData.ClassGuid, (PWSTR)szBuf, MAX_PATH, &dwRequireSize))
{
continue;
};
//wprintf(L"Class:%s\r\n", szBuf);
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szName, MAX_PATH - 1, 0))
{
//wprintf(L"FriendlyName:%s\r\n\r\n", szName);
sprintf_s(szBuf_byteToChar, "");
for (j = 0; j < sizeof(szName); j++)
{
sprintf_s(szBuf_byteToChar, "%s%c", szBuf_byteToChar, szName[j]);
}
strcpy_s(ComList[k], szBuf_byteToChar);
int comNum = getSpecialComNum(szBuf_byteToChar, SpecialCom);
//wprintf(L"comNum:%s\r\n\r\n", comNum);
k++;
*ComNum = k;
if (comNum > 0)
{
return comNum;
}
}
else if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)szName, MAX_PATH - 1, 0))
{
wprintf(L"Device:%s\r\n\r\n", szName);
}
}
}
SetupDiDestroyClassImageList(&_spImageData);
return -1;
}
int main(int argc, char* argv[])
{
char comList[50][200];
char SpecialCom[100] = "USB Serial Device";
int serialPortsNum;
//printf("Locale is: %s\n", setlocale(LC_ALL, "chs"));
printf("根据描述 %s,查找的串口号:%d\n", SpecialCom,getSpecialComNumFromDevInfo(comList, SpecialCom, &serialPortsNum));
printf("串口号数量: %d\n", serialPortsNum);
for (int i = 0; i < serialPortsNum; i++)
{
printf("%d: %s\n", i,comList[i]);
}
//PrintDevicesInfo2();
getchar();
return 0;
}
4️⃣ Debug 下工程看下结果,返回了我们想要的结果
封装成DLL
- CANoe 封装DLL,这里就不再赘述了,详情可以看 CANoe DLL编程系列文章
CANoe 调用DLL 演示
1️⃣ 新建个NetWork Module Node
2️⃣ can 脚本种的代码如下,:
核心函数:dllGetSeriesPorts(comList,SpecialComDescribtion,serialPortsNum);
- comList :返回的所有的Port口的描述
- SpecialComDescribtion: 输入参数,选择指定Port口的描述, 比如 程控电源的COM描述是
USB Serial Device
- serialPortsNum : 输入参数,返回所有Ports 口的统计数
/*@!Encoding:936*/
includes
{
#pragma library("autoSerialPort.dll")
}
int connectSerialPort(char SpecialComDescribtion[])
{
char comList[50][200];
long serialPortsNum;
long retCom;
int i ,RetVal;
retCom = dllGetSeriesPorts(comList,SpecialComDescribtion,serialPortsNum);
write("Return COM Port:%d",retCom);
write("Total COM Ports Number:%d",serialPortsNum);
for ( i = 0; i < serialPortsNum; i++)
{
write("%d: %s", i,comList[i]);
}
RetVal = RS232Open(retCom);
if (RetVal == 1 )
write("Open port %d Ok.",retCom);
else
write("Open port %d failed.",retCom);
RetVal = RS232Configure(retCom,9600,8,1,0 );
if (RetVal == 1 )
write("Configure port %d Ok.",retCom);
else
write("Configure port %d failed.",retCom);
return RetVal;
}
on key 'k'
{
connectSerialPort("USB Serial Device");
}
3️⃣ 测试结果如下,实现目的
End |
总结
- 要有最朴素的生活,最遥远的梦想,即使明天天寒地冻,路遥马亡!
- 有微信的小伙伴可以关注下浪哥车载诊断,一个行业内小小圈子,群里有
网盘资料
,源码
,还有各路大神
闲时交流交流技术,聊聊工作机会啥的。- 如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。
边栏推荐
- 嵌入式开发中的防御性C语言编程
- MapReduce instance (VIII): Map end join
- What are the models of data modeling
- Day 5 of MySQL learning
- 软件负载均衡和硬件负载均衡的选择
- Redis之Lua脚本
- May brush question 26 - concurrent search
- Global and Chinese market for annunciator panels 2022-2028: Research Report on technology, participants, trends, market size and share
- Nc17 longest palindrome substring
- 美团二面:为什么 Redis 会有哨兵?
猜你喜欢
Elk project monitoring platform deployment + deployment of detailed use (II)
零基础学习单片机切记这四点要求,少走弯路
Redis cluster
DCDC power ripple test
面试突击62:group by 有哪些注意事项?
大学想要选择学习自动化专业,可以看什么书去提前了解?
What you have to know about network IO model
[Yu Yue education] reference materials of complex variable function and integral transformation of Shenyang University of Technology
[deep learning] semantic segmentation: paper reading: (2021-12) mask2former
Mapreduce实例(十):ChainMapReduce
随机推荐
嵌入式中的合作开发--函数指针
Redis之Lua脚本
Mapreduce实例(九):Reduce端join
发生OOM了,你知道是什么原因吗,又该怎么解决呢?
MapReduce instance (V): secondary sorting
Several ways of MySQL database optimization (pen interview must ask)
Mapreduce实例(六):倒排索引
有软件负载均衡,也有硬件负载均衡,选择哪个?
Mapreduce实例(四):自然排序
Popularization of security knowledge - twelve moves to protect mobile phones from network attacks
Why data Tiering
Minio distributed file storage cluster for full stack development
Detailed explanation of cookies and sessions
Redis cluster
May brush question 26 - concurrent search
Solve the problem of inconsistency between database field name and entity class attribute name (resultmap result set mapping)
为什么要数据分层
Solve the problem of too many small files
Publish and subscribe to redis
May brush question 03 - sorting