在调用时有两件事对我们不利getStLinkList
特别是“CubeProgrammer_API.dll”库的功能。如果不更正它们,库将无法工作,即使是在 C++ 中也是如此。
首先,在中找到该库的依赖项api/libSTM32CubeProgrammer 安装的文件夹并非全部针对 x64 编译。中的版本bin文件夹是,这些是您希望在运行时可用的库。我通过将工作目录设置为项目调试设置中的该目录来完成此操作。这是通过检查每个 DLL 的目标机器来验证的api/lib and bin文件夹。
二、调用前需要初始化“CubeProgrammer_API.dll”getStLinkList
通过致电setLoadersPath
and setDisplayCallbacks
功能。第一个函数必须提供“Flash Loader”的路径,即bin/FlashLoader就我而言。这setDisplayCallbacks
function 采用三个函数指针的结构。
下面的示例可能不是类型封送的最佳示例,但它将说明该过程。
public static class CubeProgrammerApi
{
public enum DebugConnectionMode
{
NormalMode = 0,
HotplugMode = 1,
UnderResetMode = 2,
PreResetMode = 3
}
public enum DebugResetMode
{
SoftwareReset = 0,
HardwareReset = 1,
CoreReset = 2
}
[StructLayout(LayoutKind.Sequential)]
public class Frequencies
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
uint[] JtagFrequency;
uint JTagFrequencyNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
uint[] SwdFrequency;
uint SwdFrequencyNumber;
}
[StructLayout(LayoutKind.Sequential)]
public class DebugConnectParameters
{
DebugPort DebugPort;
public int Index;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)]
public string SerialNumber;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string FirmwareVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string TargetVoltage;
public int AccesPortNumber;
public int AccessPort;
public DebugConnectionMode connectionMode;
public DebugResetMode resetMode;
public bool IsOldFirmware;
public Frequencies Freqencies;
public int Frequency;
public bool IsBridge;
public int Shared;
}
public delegate void LogMessageReceived(int messageType, [MarshalAs(UnmanagedType.LPWStr)] string message);
public delegate void InitProgressBar();
public delegate void ProgressBarUpdateReceived(int currentProgress, int total);
internal static class NativeMethods
{
public struct DisplayCallbacks
{
public InitProgressBar initProgressBar;
public LogMessageReceived logMessage;
public ProgressBarUpdateReceived loadBar;
}
[DllImport("CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setLoadersPath")]
internal static extern void SetLoadersPath(string path);
[DllImport("CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "setDisplayCallbacks")]
internal static extern void SetDisplayCallbacks(ref DisplayCallbacks callbacks);
[DllImport("CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "getStLinkList")]
internal static extern int GetStLinkList(IntPtr stLinkList, uint shared);
[DllImport("CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void deleteInterfaceList();
[DllImport("CubeProgrammer_API.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "reset")]
internal static extern int Reset([MarshalAs(UnmanagedType.U4)] DebugResetMode rstMode);
}
public static void SetLoadersPath(string path)
{
NativeMethods.SetLoadersPath(path);
}
public static void SetDisplayCallbacks(InitProgressBar initProgressBar, LogMessageReceived messageReceived, ProgressBarUpdateReceived progressBarUpdate)
{
NativeMethods.DisplayCallbacks callbacksHandle;
callbacksHandle.initProgressBar = initProgressBar;
callbacksHandle.logMessage = messageReceived;
callbacksHandle.loadBar = progressBarUpdate;
NativeMethods.SetDisplayCallbacks(ref callbacksHandle);
}
public static IList<DebugConnectParameters> GetStLinkProgrammers(bool shared = false)
{
var listPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
var parametersList = new List<DebugConnectParameters>();
try
{
var size = Marshal.SizeOf<DebugConnectParameters>();
var numberOfItems = NativeMethods.GetStLinkList(listPtr, shared ? 1U : 0U);
var listDereference = Marshal.PtrToStructure<IntPtr>(listPtr);
for (var i = 0; i < numberOfItems; i++)
{
var currentItem = Marshal.PtrToStructure<DebugConnectParameters>(listDereference + (i * size));
parametersList.Add(currentItem);
}
NativeMethods.deleteInterfaceList();
}
finally
{
Marshal.FreeHGlobal(listPtr);
}
return parametersList;
}
public static void FreeStLinkProgrammers()
{
NativeMethods.deleteInterfaceList();
}
}
以及主要:
class Program
{
static void Main(string[] args)
{
CubeProgrammerApi.SetLoadersPath(@"C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\FlashLoader");
CubeProgrammerApi.SetDisplayCallbacks(InitProgressBar, ReceiveMessage, ProgressBarUpdate);
var stLinkList = CubeProgrammerApi.GetStLinkProgrammers();
foreach (var stlink in stLinkList)
{
Console.WriteLine("{0} {1}", stlink.Index, stlink.SerialNumber);
}
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
CubeProgrammerApi.FreeStLinkProgrammers();
}
static void ReceiveMessage(int messgaeType, string message)
{
}
static void InitProgressBar()
{
}
static void ProgressBarUpdate(int currentProgress, int total)
{
}
}
这将输出以下内容,并附加两个调试器,分别是 STLink V3 和 STLink V2。这应该能让您足够了解要使用的正确类型。
0 002F001D3038511834333935
1 34FF6D065250343847110943
Press ENTER to exit