当前位置:网站首页>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 |
总结


- 要有最朴素的生活,最遥远的梦想,即使明天天寒地冻,路遥马亡!
- 有微信的小伙伴可以关注下浪哥车载诊断,一个行业内小小圈子,群里有
网盘资料,源码,还有各路大神闲时交流交流技术,聊聊工作机会啥的。- 如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。
边栏推荐
- 五月刷题01——数组
- Regular expressions are actually very simple
- [Yu Yue education] reference materials of power electronics technology of Jiangxi University of science and technology
- 有软件负载均衡,也有硬件负载均衡,选择哪个?
- Redis distributed lock implementation redison 15 questions
- Oom happened. Do you know the reason and how to solve it?
- 为拿 Offer,“闭关修炼,相信努力必成大器
- 六月刷题02——字符串
- Redis' performance indicators and monitoring methods
- Servlet learning diary 7 -- servlet forwarding and redirection
猜你喜欢

Sentinel mode of redis

Hero League rotation map automatic rotation

51单片机进修的一些感悟
![[deep learning] semantic segmentation: paper reading: (CVPR 2022) mpvit (cnn+transformer): multipath visual transformer for dense prediction](/img/f1/6f22f00843072fa4ad83dc0ef2fad8.png)
[deep learning] semantic segmentation: paper reading: (CVPR 2022) mpvit (cnn+transformer): multipath visual transformer for dense prediction
![[deep learning] semantic segmentation: paper reading: (2021-12) mask2former](/img/dd/fe2bfa3563cf478afe431ac87a8cb7.png)
[deep learning] semantic segmentation: paper reading: (2021-12) mask2former

Compilation of libwebsocket

A wave of open source notebooks is coming

MapReduce instance (VIII): Map end join

一大波开源小抄来袭

Mapreduce实例(九):Reduce端join
随机推荐
Lua script of redis
面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了
Libuv thread
单片机如何从上电复位执行到main函数?
Leetcode:608 树节点
What is an R-value reference and what is the difference between it and an l-value?
Withdrawal of wechat applet (enterprise payment to change)
The order of include header files and the difference between double quotation marks "and angle brackets < >
Scoped in webrtc_ refptr
机械工程师和电气工程师方向哪个前景比较好?
为什么大学单片机课上51+汇编,为什么不直接来STM32
Sentinel mode of redis
What are the models of data modeling
Une grande vague d'attaques à la source ouverte
基于B/S的医院管理住院系统的研究与实现(附:源码 论文 sql文件)
软件负载均衡和硬件负载均衡的选择
基于B/S的影视创作论坛的设计与实现(附:源码 论文 sql文件 项目部署教程)
Redis' performance indicators and monitoring methods
Global and Chinese market of AVR series microcontrollers 2022-2028: Research Report on technology, participants, trends, market size and share
Basic concepts of libuv

