Add support for setting VCP baud rate in Silabs JLink devices (#142)

This commit is contained in:
José Simões 2022-07-13 19:12:02 +01:00 коммит произвёл GitHub
Родитель 8b51b4f272
Коммит 181bbb4193
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 212 добавлений и 0 удалений

Двоичные данные
lib/silink/JLinkARM.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/Qt5Core.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/Qt5Network.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/emdll0.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/libapack.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/libgcc_s_dw2-1.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/libstdc++-6.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/libwinpthread-1.dll Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/silink.exe Normal file

Двоичный файл не отображается.

Двоичные данные
lib/silink/zlib1.dll Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -208,6 +208,12 @@ namespace nanoFramework.Tools.FirmwareFlasher
[Display(Name = "No J-Link device found. Make sure it's connected.")]
E8001 = 8001,
/// <summary>
/// Error executing silink command.
/// </summary>
[Display(Name = "Error executing silink CLI command.")]
E8002 = 8002,
////////////////////////////////
// Application general Errors //
////////////////////////////////

Просмотреть файл

@ -1125,6 +1125,7 @@ namespace nanoFramework.Tools.FirmwareFlasher
var connectedJLinkDevices = JLinkDevice.ListDevices();
if (o.BinFile.Any()
&& connectedJLinkDevices.Count != 0)
{
@ -1147,6 +1148,9 @@ namespace nanoFramework.Tools.FirmwareFlasher
Console.WriteLine($"Connected to J-Link device with ID {jlinkDevice.ProbeId}");
}
// set VCP baud rate (if needed)
_ = SilinkCli.SetVcpBaudRate(o.JLinkDeviceId is null ? connectedJLinkDevices.First() : "");
// set verbosity
jlinkDevice.Verbosity = _verbosityLevel;
@ -1196,6 +1200,9 @@ namespace nanoFramework.Tools.FirmwareFlasher
operationPerformed = true;
// set VCP baud rate (if needed)
_ = SilinkCli.SetVcpBaudRate(o.JLinkDeviceId is null ? connectedJLinkDevices.First() : "");
if (_exitCode != ExitCodes.OK)
{
// done here

Просмотреть файл

@ -0,0 +1,197 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
namespace nanoFramework.Tools.FirmwareFlasher
{
internal class SilinkCli
{
private const int SilinkTelnetPort = 49000;
private const int SilinkAdminPort = SilinkTelnetPort + 2;
private const int TargetBaudRate = 921600;
/// <summary>
/// This will set the baud rate of the VCP in a Silabs Jlink board.
/// Before setting the value the devices is queried and the new setting is applied only if needed.
/// </summary>
/// <param name="probeId">Id of the JLink probe to adjust the baud rate.</param>
/// <param name="verbosity">Verbosity level for the operation. <see cref="VerbosityLevel.Quiet"/> will be used if not specified.</param>
/// <returns></returns>
/// <remarks>
/// Currently this operation is only supported in Windows machines.
/// </remarks>
public static ExitCodes SetVcpBaudRate(
string probeId,
VerbosityLevel verbosity = VerbosityLevel.Quiet)
{
// check that we can run on this platform
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)
|| RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Setting VCP baud rate in {OSPlatform.OSX} is not supported.");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
return ExitCodes.E8002;
}
// launch silink
var silinkCli = RunSilinkCLI(Path.Combine(probeId));
var silinkSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint silinkEndPoint = new(IPAddress.Parse("127.0.0.1"), SilinkAdminPort);
try
{
silinkSocket.Connect(silinkEndPoint);
Thread.Sleep(250);
// query current config
byte[] buffer = Encoding.Default.GetBytes("serial vcom\r");
silinkSocket.Send(buffer);
Thread.Sleep(250);
buffer = new byte[1024];
int receiveCount = silinkSocket.Receive(buffer, 0, buffer.Length, 0);
var currentConfig = Encoding.Default.GetString(buffer, 0, receiveCount);
if (!string.IsNullOrEmpty(currentConfig))
{
// interpret reply
const string regexPattern = "(?:Stored port speed : )(?'baudrate'\\d+)";
var myRegex1 = new Regex(regexPattern, RegexOptions.Multiline);
var currentBaud = myRegex1.Match(currentConfig);
if (currentBaud.Success)
{
// verify current setting
if (int.TryParse(currentBaud.Groups["baudrate"].Value, out int baudRate) && baudRate == TargetBaudRate)
{
return ExitCodes.OK;
}
}
// need to set baud rate because it's different
if (verbosity >= VerbosityLevel.Normal)
{
Console.Write("Setting VCP baud rate...");
}
Thread.Sleep(250);
// compose command
buffer = Encoding.Default.GetBytes("serial vcom config speed {TargetBaudRate}\r");
silinkSocket.Send(buffer);
Thread.Sleep(250);
buffer = new byte[1024];
receiveCount = silinkSocket.Receive(buffer, 0, buffer.Length, 0);
var opResult = Encoding.Default.GetString(buffer, 0, receiveCount);
if (opResult.Contains("Baudrate set to 921600 bps"))
{
if (verbosity >= VerbosityLevel.Normal)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(" OK");
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.White;
}
return ExitCodes.OK;
}
else
{
if (verbosity >= VerbosityLevel.Normal)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("FAILED!");
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{opResult.Replace("PK> ", "")}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
}
return ExitCodes.E8002;
}
}
}
catch (Exception ex)
{
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"Error occurred: {ex.Message}");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
return ExitCodes.E8002;
}
finally
{
// close socket
silinkSocket?.Close();
// kill process tree (to include JLink)
silinkCli.Kill(true);
}
return ExitCodes.E8002;
}
internal static Process RunSilinkCLI(string probeId)
{
// prepare the process start of J-Link
string appName = "silink.exe";
string appDir = Path.Combine(Program.ExecutingPath, "silink");
Process silinkCli = new Process();
string parameter = $" -sn {probeId} -automap {SilinkTelnetPort}";
silinkCli.StartInfo = new ProcessStartInfo(Path.Combine(appDir, appName), parameter)
{
WorkingDirectory = appDir,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WindowStyle = ProcessWindowStyle.Hidden
};
// start siLink CLI and...
silinkCli.Start();
// ... return the process
return silinkCli;
}
}
}

Просмотреть файл

@ -103,6 +103,8 @@
</None>
<None Include="..\lib\jlinkLinux\**" Link="jlinkLinux\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always">
</None>
<None Include="..\lib\silink\**" Link="silink\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always">
</None>
</ItemGroup>
<ItemGroup>
<None Include="..\lib\uniflash\**" Link="uniflash\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="Always">