fix: frontend upload bitstream failed

This commit is contained in:
SikongJueluo 2025-05-19 15:56:23 +08:00
parent 5042bf8ce5
commit ba6ec73b84
No known key found for this signature in database
6 changed files with 99 additions and 102 deletions

View File

@ -3,6 +3,8 @@ import { isNull, isUndefined } from "lodash";
export namespace Common {
export function toFileParameter(object: File): FileParameter {
if (isNull(object) || isUndefined(object))
throw new Error("File is Null or Undefined");
return {
data: object,
fileName: object.name

View File

@ -31,10 +31,9 @@ import { useDialogStore } from "@/stores/dialog";
import { isNull, isUndefined } from "lodash";
interface Props {
uploadEvent?: Function;
downloadEvent?: Function;
uploadEvent?: (file: File) => Promise<boolean>;
downloadEvent?: () => Promise<boolean>;
maxMemory?: number;
defaultFile?: string;
}
const props = withDefaults(defineProps<Props>(), {
@ -53,7 +52,10 @@ const buttonText = computed(() => {
});
const fileInput = useTemplateRef("fileInput");
const bitstream = defineModel<File | undefined>();
const bitstream = defineModel("bitstreamFile", {
type: File,
default: undefined,
});
onMounted(() => {
if (!isUndefined(bitstream.value) && !isNull(fileInput.value)) {
let fileList = new DataTransfer();
@ -94,10 +96,10 @@ async function handleClick(event: Event): Promise<void> {
return;
}
// Upload - bitstream.valuebitstream
isUploading.value = true;
try {
const ret = await props.uploadEvent(event, bitstream.value);
const ret = await props.uploadEvent(bitstream.value);
console.debug(`After upload bistream: ${bitstream.value}, result: ${ret}`);
if (isUndefined(props.downloadEvent)) {
if (ret) {
dialog.info("上传成功");
@ -105,6 +107,10 @@ async function handleClick(event: Event): Promise<void> {
} else dialog.error("上传失败");
return;
}
if (!ret) {
isUploading.value = false;
return;
}
} catch (e) {
dialog.error("上传失败");
console.error(e);

View File

@ -10,15 +10,15 @@
</svg>
</div>
<Teleport to="#ComponentCapabilities" v-if="selectecComponentID === props.componentId">
<MotherBoardCaps :jtagAddr="eqps.boardAddr" :jtagPort="eqps.boardPort.toString()" />
<MotherBoardCaps :jtagAddr="props.boardAddr" :jtagPort="toNumber(props.boardPort)" />
</Teleport>
</template>
<script setup lang="tsx">
import MotherBoardCaps from "./MotherBoardCaps.vue";
import { useEquipments } from "@/stores/equipments";
import { ref, computed, watchEffect, inject } from "vue";
import { CanvasCurrentSelectedComponentID } from "../InjectKeys";
import { toNumber } from "lodash";
//
export interface MotherBoardProps {
@ -39,16 +39,6 @@ const selectecComponentID = inject(CanvasCurrentSelectedComponentID, ref(null));
const width = computed(() => 800 * props.size);
const height = computed(() => 600 * props.size);
// Global store
const eqps = useEquipments();
const bitstreamFile = ref<File | null>();
watchEffect(() => {
eqps.setAddr(props.boardAddr);
eqps.setPort(props.boardPort);
});
//
defineExpose({
getInfo: () => ({

View File

@ -3,7 +3,7 @@
<h1 class="font-bold text-center text-2xl">Jtag</h1>
<div class="flex flex-col">
<p class="grow">Jtag Addr: {{ props.jtagAddr }}</p>
<p class="grow">Jtag Port: {{ props.jtagPort }}</p>
<p class="grow">Jtag Port: {{ props.jtagPort?.toString() }}</p>
<div class="flex justify-between grow">
<p>IDCode: 0x{{ jtagIDCode.toString(16).padStart(8, "0") }}</p>
<button class="btn btn-circle w-6 h-6" :onclick="getIDCode">
@ -17,7 +17,8 @@
</div>
</div>
<div class="divider"></div>
<UploadCard class="bg-base-200" :upload-event="uploadBitstream" :download-event="downloadBitstream">
<UploadCard class="bg-base-200" :upload-event="uploadBitstream" :download-event="downloadBitstream"
:bitstream-file="eqps.jtagBitstream" @update:bitstream-file="handleBitstreamChange">
</UploadCard>
<div class="divider"></div>
<button class="btn w-full btn-primary" :class="isEnableJtagBoundaryScan ? '' : 'btn-soft'"
@ -32,16 +33,15 @@ import { JtagClient } from "@/APIClient";
import z from "zod";
import UploadCard from "@/components/UploadCard.vue";
import { useDialogStore } from "@/stores/dialog";
import {
useConstraintsStore,
type ConstraintLevel,
} from "@/stores/constraints";
import { isUndefined, toNumber } from "lodash";
import { ref, computed, watch } from "vue";
import { Common } from "@/Common";
import { useEquipments } from "@/stores/equipments";
import { useConstraintsStore } from "@/stores/constraints";
import { isUndefined } from "lodash";
import { ref, watchEffect } from "vue";
interface CapsProps {
jtagAddr?: string;
jtagPort?: string;
jtagPort?: number;
}
const props = withDefaults(defineProps<CapsProps>(), {});
@ -49,16 +49,17 @@ const props = withDefaults(defineProps<CapsProps>(), {});
// Global Stores
const dialog = useDialogStore();
const constrainsts = useConstraintsStore();
const eqps = useEquipments();
const jtagController = new JtagClient();
const isEnableJtagBoundaryScan = ref(false);
// 使
const jtagIDCode = ref(0);
const boardAddress = computed(() => props.jtagAddr);
const boardPort = computed(() =>
isUndefined(props.jtagPort) ? undefined : toNumber(props.jtagPort),
);
function handleBitstreamChange(file: File | undefined) {
eqps.jtagBitstream = file;
}
async function toggleJtagBoundaryScan() {
isEnableJtagBoundaryScan.value = !isEnableJtagBoundaryScan.value;
@ -68,8 +69,8 @@ async function toggleJtagBoundaryScan() {
async function jtagBoundaryScan() {
try {
const portStates = await jtagController.boundaryScanLogicalPorts(
boardAddress.value,
boardPort.value,
props.jtagAddr,
props.jtagPort,
);
constrainsts.batchSetConstraintStates(portStates);
@ -78,75 +79,78 @@ async function jtagBoundaryScan() {
console.error(error);
isEnableJtagBoundaryScan.value = false;
} finally {
if (isEnableJtagBoundaryScan.value) setTimeout(jtagBoundaryScan, 100);
if (isEnableJtagBoundaryScan.value) setTimeout(jtagBoundaryScan, 50);
}
}
async function uploadBitstream(event: Event, bitstream: File) {
if (!isUndefined(boardAddress.value) || !isUndefined(boardPort.value)) {
async function uploadBitstream(bitstream: File): Promise<boolean> {
if (isUndefined(props.jtagAddr) || isUndefined(props.jtagPort)) {
dialog.error("开发板地址或端口空缺");
return;
return false;
}
const fileParam = {
data: bitstream,
fileName: bitstream.name,
};
try {
console.debug(`Before upload bistream: ${bitstream}`);
const resp = await jtagController.uploadBitstream(
boardAddress.value,
fileParam,
);
return resp;
} catch (e) {
dialog.error("上传错误");
}
}
async function downloadBitstream() {
if (!boardAddress.value || !boardPort.value) {
dialog.error("开发板地址或端口空缺");
return;
}
try {
const resp = await jtagController.downloadBitstream(
boardAddress.value,
boardPort.value,
props.jtagAddr,
Common.toFileParameterOrNull(bitstream),
);
return resp;
} catch (e) {
dialog.error("上传错误");
console.error(e);
return false;
}
}
watch([boardAddress, boardPort], () => {
if (
z.string().ip().safeParse(boardAddress).success &&
z.number().positive().safeParse(boardPort).success
)
getIDCode();
});
async function downloadBitstream(): Promise<boolean> {
if (isUndefined(props.jtagAddr) || isUndefined(props.jtagPort)) {
dialog.error("开发板地址或端口空缺");
return false;
}
async function getIDCode() {
if (!boardAddress.value || !boardPort.value) {
try {
const resp = await jtagController.downloadBitstream(
props.jtagAddr,
props.jtagPort,
);
return resp;
} catch (e) {
dialog.error("上传错误");
console.error(e);
return false;
}
}
async function getIDCode(isQuiet: boolean = false) {
if (isUndefined(props.jtagAddr) || isUndefined(props.jtagPort)) {
dialog.error("开发板地址或端口空缺");
return;
}
try {
const resp = await jtagController.getDeviceIDCode(
boardAddress.value,
boardPort.value,
props.jtagAddr,
props.jtagPort,
);
jtagIDCode.value = resp;
} catch (e) {
dialog.error("获取IDCode错误");
console.error(e);
if (!isQuiet) dialog.error("获取IDCode错误");
}
}
watchEffect(() => {
eqps.setAddr(props.jtagAddr);
eqps.setPort(props.jtagPort);
});
watchEffect(() => {
if (
z.string().ip().safeParse(props.jtagAddr).success &&
z.number().positive().safeParse(props.jtagPort).success
)
getIDCode(true);
});
</script>
<style scoped lang="postcss">

View File

@ -7,11 +7,16 @@ import { isNumber } from 'mathjs';
export const useEquipments = defineStore('equipments', () => {
const boardAddr = ref("127.0.0.1")
const boardPort = ref(1234)
function setAddr(address: string) {
const jtagBitstream = ref<File>()
function setAddr(address: string | undefined) {
if (isUndefined(address)) return;
if (z.string().ip("4").safeParse(address).success)
boardAddr.value = address;
}
function setPort(port: string | number) {
function setPort(port: string | number | undefined) {
if (isUndefined(port)) return;
if (isString(port) && port.length != 0) {
const portNumber = toNumber(port);
@ -23,8 +28,6 @@ export const useEquipments = defineStore('equipments', () => {
boardPort.value = port;
}
}
const jtagBitstream = ref<File | undefined>()
const remoteUpdateBitstream = ref<File | undefined>()
return {
boardAddr,
@ -32,7 +35,6 @@ export const useEquipments = defineStore('equipments', () => {
setAddr,
setPort,
jtagBitstream,
remoteUpdateBitstream,
}
})

View File

@ -44,7 +44,8 @@
import { JtagClient, type FileParameter } from "@/APIClient";
import UploadCard from "@/components/UploadCard.vue";
import { useDialogStore } from "@/stores/dialog";
import { toNumber } from "lodash";
import { Common } from "@/Common";
import { toNumber, isUndefined } from "lodash";
import { ref } from "vue";
const jtagController = new JtagClient();
@ -54,39 +55,30 @@ const dialog = useDialogStore();
const boardAddress = ref("127.0.0.1"); // IP
const boardPort = ref("1234"); //
async function uploadBitstream(event: Event, bitstream: File) {
if (boardAddress.value.length == 0) {
dialog.error("开发板地址空缺");
return;
}
if (boardPort.value.length == 0) {
dialog.error("开发板端口空缺");
return;
async function uploadBitstream(bitstream: File): Promise<boolean> {
if (isUndefined(boardAddress.value) || isUndefined(boardPort.value)) {
dialog.error("开发板地址或端口空缺");
return false;
}
const fileParam: FileParameter = {
data: bitstream,
fileName: bitstream.name,
};
try {
console.debug(`Before upload bistream: ${bitstream}`);
const resp = await jtagController.uploadBitstream(
boardAddress.value,
fileParam,
Common.toFileParameterOrNull(bitstream),
);
return resp
return resp;
} catch (e) {
dialog.error("上传错误");
console.error(e);
return false;
}
}
async function downloadBitstream() {
if (boardAddress.value.length == 0) {
dialog.error("开发板地址空缺");
return;
}
if (boardPort.value.length == 0) {
dialog.error("开发板端口空缺");
return;
async function downloadBitstream(): Promise<boolean> {
if (isUndefined(boardAddress.value) || isUndefined(boardPort.value)) {
dialog.error("开发板地址或端口空缺");
return false;
}
try {
@ -98,6 +90,7 @@ async function downloadBitstream() {
} catch (e) {
dialog.error("上传错误");
console.error(e);
return false;
}
}
</script>