feat: 使用SignalR来控制jtag边界扫描

This commit is contained in:
2025-08-01 19:55:55 +08:00
parent 2adeca3b99
commit 9adc5295f8
20 changed files with 973 additions and 571 deletions

View File

@@ -1,15 +1,16 @@
import { ref, reactive, watchPostEffect } from "vue";
import { ref, reactive, watchPostEffect, onMounted, onUnmounted } from "vue";
import { defineStore } from "pinia";
import { useLocalStorage } from "@vueuse/core";
import { isString, toNumber } from "lodash";
import { isString, toNumber, type Dictionary } from "lodash";
import z from "zod";
import { isNumber } from "mathjs";
import { JtagClient, MatrixKeyClient, PowerClient } from "@/APIClient";
import { Mutex, withTimeout } from "async-mutex";
import { useConstraintsStore } from "@/stores/constraints";
import { useDialogStore } from "./dialog";
import { toFileParameterOrUndefined } from "@/utils/Common";
import { AuthManager } from "@/utils/AuthManager";
import { HubConnectionBuilder } from "@microsoft/signalr";
import { getHubProxyFactory, getReceiverRegister } from "@/TypedSignalR.Client";
export const useEquipments = defineStore("equipments", () => {
// Global Stores
@@ -22,13 +23,28 @@ export const useEquipments = defineStore("equipments", () => {
// Jtag
const jtagBitstream = ref<File>();
const jtagBoundaryScanFreq = ref(100);
const jtagBoundaryScanErrorCount = ref(0); // 边界扫描连续错误计数
const maxJtagBoundaryScanErrors = 5; // 最大允许连续错误次数
const jtagClientMutex = withTimeout(
new Mutex(),
1000,
new Error("JtagClient Mutex Timeout!"),
);
const jtagHubConnection = new HubConnectionBuilder()
.withUrl("/hubs/JtagHub")
.withAutomaticReconnect()
.build();
const jtagHubProxy =
getHubProxyFactory("IJtagHub").createHubProxy(jtagHubConnection);
const jtagHubSubscription = getReceiverRegister("IJtagReceiver").register(
jtagHubConnection,
{
onReceiveBoundaryScanData: async (msg) => {
constrainsts.batchSetConstraintStates(msg);
},
},
);
onMounted(() => {
jtagHubConnection.start();
});
// Matrix Key
const matrixKeyStates = reactive(new Array<boolean>(16).fill(false));
@@ -50,41 +66,6 @@ export const useEquipments = defineStore("equipments", () => {
const enableMatrixKey = ref(false);
const enablePower = ref(false);
// Watch
watchPostEffect(async () => {
if (true === enableJtagBoundaryScan.value) {
// 重新启用时重置错误计数器
jtagBoundaryScanErrorCount.value = 0;
jtagBoundaryScan();
}
});
// Parse and Set
function setAddr(address: string | undefined): boolean {
if (isString(address) && z.string().ip("4").safeParse(address).success) {
boardAddr.value = address;
return true;
}
return false;
}
function setPort(port: string | number | undefined): boolean {
if (isString(port) && port.length != 0) {
const portNumber = toNumber(port);
if (z.number().nonnegative().max(65535).safeParse(portNumber).success) {
boardPort.value = portNumber;
return true;
}
} else if (isNumber(port)) {
if (z.number().nonnegative().max(65535).safeParse(port).success) {
boardPort.value = port;
return true;
}
}
return false;
}
function setMatrixKey(
keyNum: number | string | undefined,
keyValue: boolean,
@@ -105,38 +86,12 @@ export const useEquipments = defineStore("equipments", () => {
return false;
}
async function jtagBoundaryScan() {
const release = await jtagClientMutex.acquire();
try {
// 自动开启电源
await powerSetOnOff(true);
const jtagClient = AuthManager.createAuthenticatedJtagClient();
const portStates = await jtagClient.boundaryScanLogicalPorts(
boardAddr.value,
boardPort.value,
);
constrainsts.batchSetConstraintStates(portStates);
// 扫描成功,重置错误计数器
jtagBoundaryScanErrorCount.value = 0;
} catch (error) {
jtagBoundaryScanErrorCount.value++;
console.error(`边界扫描错误 (${jtagBoundaryScanErrorCount.value}/${maxJtagBoundaryScanErrors}):`, error);
// 如果错误次数超过最大允许次数,才停止扫描并显示错误
if (jtagBoundaryScanErrorCount.value >= maxJtagBoundaryScanErrors) {
dialog.error("边界扫描发生连续错误,已自动停止");
enableJtagBoundaryScan.value = false;
jtagBoundaryScanErrorCount.value = 0; // 重置错误计数器
}
} finally {
release();
if (enableJtagBoundaryScan.value)
setTimeout(jtagBoundaryScan, 1000 / jtagBoundaryScanFreq.value);
async function jtagBoundaryScanSetOnOff(enable: boolean) {
enableJtagBoundaryScan.value = enable;
if (enable) {
jtagHubProxy.startBoundaryScan(jtagBoundaryScanFreq.value);
} else {
jtagHubProxy.stopBoundaryScan();
}
}
@@ -144,7 +99,7 @@ export const useEquipments = defineStore("equipments", () => {
try {
// 自动开启电源
await powerSetOnOff(true);
const jtagClient = AuthManager.createAuthenticatedJtagClient();
const resp = await jtagClient.uploadBitstream(
boardAddr.value,
@@ -163,7 +118,7 @@ export const useEquipments = defineStore("equipments", () => {
try {
// 自动开启电源
await powerSetOnOff(true);
const jtagClient = AuthManager.createAuthenticatedJtagClient();
const resp = await jtagClient.downloadBitstream(
boardAddr.value,
@@ -184,7 +139,7 @@ export const useEquipments = defineStore("equipments", () => {
try {
// 自动开启电源
await powerSetOnOff(true);
const jtagClient = AuthManager.createAuthenticatedJtagClient();
const resp = await jtagClient.getDeviceIDCode(
boardAddr.value,
@@ -204,7 +159,7 @@ export const useEquipments = defineStore("equipments", () => {
try {
// 自动开启电源
await powerSetOnOff(true);
const jtagClient = AuthManager.createAuthenticatedJtagClient();
const resp = await jtagClient.setSpeed(
boardAddr.value,
@@ -224,7 +179,8 @@ export const useEquipments = defineStore("equipments", () => {
const release = await matrixKeypadClientMutex.acquire();
console.log("set Key !!!!!!!!!!!!");
try {
const matrixKeypadClient = AuthManager.createAuthenticatedMatrixKeyClient();
const matrixKeypadClient =
AuthManager.createAuthenticatedMatrixKeyClient();
const resp = await matrixKeypadClient.setMatrixKeyStatus(
boardAddr.value,
boardPort.value,
@@ -243,7 +199,8 @@ export const useEquipments = defineStore("equipments", () => {
const release = await matrixKeypadClientMutex.acquire();
try {
if (enable) {
const matrixKeypadClient = AuthManager.createAuthenticatedMatrixKeyClient();
const matrixKeypadClient =
AuthManager.createAuthenticatedMatrixKeyClient();
const resp = await matrixKeypadClient.enabelMatrixKey(
boardAddr.value,
boardPort.value,
@@ -251,7 +208,8 @@ export const useEquipments = defineStore("equipments", () => {
enableMatrixKey.value = resp;
return resp;
} else {
const matrixKeypadClient = AuthManager.createAuthenticatedMatrixKeyClient();
const matrixKeypadClient =
AuthManager.createAuthenticatedMatrixKeyClient();
const resp = await matrixKeypadClient.disableMatrixKey(
boardAddr.value,
boardPort.value,
@@ -290,16 +248,13 @@ export const useEquipments = defineStore("equipments", () => {
return {
boardAddr,
boardPort,
setAddr,
setPort,
setMatrixKey,
// Jtag
enableJtagBoundaryScan,
jtagBoundaryScanSetOnOff,
jtagBitstream,
jtagBoundaryScanFreq,
jtagBoundaryScanErrorCount,
jtagClientMutex,
jtagUploadBitstream,
jtagDownloadBitstream,
jtagGetIDCode,