feat: 添加debugger后端api,并修改waveformdisplay使其更加通用
This commit is contained in:
		
							
								
								
									
										251
									
								
								server/src/Controllers/DebuggerController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								server/src/Controllers/DebuggerController.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,251 @@
 | 
			
		||||
using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
using Microsoft.AspNetCore.Cors;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Peripherals.DebuggerClient;
 | 
			
		||||
 | 
			
		||||
namespace server.Controllers;
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// FPGA调试器控制器
 | 
			
		||||
/// </summary>
 | 
			
		||||
[ApiController]
 | 
			
		||||
[Route("api/[controller]")]
 | 
			
		||||
[Authorize]
 | 
			
		||||
public class DebuggerController : ControllerBase
 | 
			
		||||
{
 | 
			
		||||
    private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取调试器实例
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    private DebuggerClient? GetDebugger()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var userName = User.Identity?.Name;
 | 
			
		||||
            if (string.IsNullOrEmpty(userName))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            using var db = new Database.AppDataConnection();
 | 
			
		||||
            var userRet = db.GetUserByName(userName);
 | 
			
		||||
            if (!userRet.IsSuccessful || !userRet.Value.HasValue)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            var user = userRet.Value.Value;
 | 
			
		||||
            if (user.BoardID == Guid.Empty)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            var boardRet = db.GetBoardByID(user.BoardID);
 | 
			
		||||
            if (!boardRet.IsSuccessful || !boardRet.Value.HasValue)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            var board = boardRet.Value.Value;
 | 
			
		||||
            return new DebuggerClient(board.IpAddr, board.Port, 1);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取调试器实例时发生异常");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 设置捕获模式
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpPost("SetMode")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 | 
			
		||||
    public async Task<IActionResult> SetMode([FromBody] CaptureMode mode)
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var debugger = GetDebugger();
 | 
			
		||||
            if (debugger == null)
 | 
			
		||||
                return BadRequest("用户未绑定有效的实验板");
 | 
			
		||||
 | 
			
		||||
            var result = await debugger.SetMode(mode);
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"设置捕获模式失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "设置捕获模式失败");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "设置捕获模式时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 启动触发器
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpPost("StartTrigger")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 | 
			
		||||
    public async Task<IActionResult> StartTrigger()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var debugger = GetDebugger();
 | 
			
		||||
            if (debugger == null)
 | 
			
		||||
                return BadRequest("用户未绑定有效的实验板");
 | 
			
		||||
 | 
			
		||||
            var result = await debugger.StartTrigger();
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"启动触发器失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "启动触发器失败");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "启动触发器时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 读取触发器状态标志
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpGet("ReadFlag")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(byte), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 | 
			
		||||
    public async Task<IActionResult> ReadFlag()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var debugger = GetDebugger();
 | 
			
		||||
            if (debugger == null)
 | 
			
		||||
                return BadRequest("用户未绑定有效的实验板");
 | 
			
		||||
 | 
			
		||||
            var result = await debugger.ReadFlag();
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"读取触发器状态标志失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "读取触发器状态标志失败");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "读取触发器状态标志时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 清除触发器状态标志
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpPost("ClearFlag")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 | 
			
		||||
    public async Task<IActionResult> ClearFlag()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var debugger = GetDebugger();
 | 
			
		||||
            if (debugger == null)
 | 
			
		||||
                return BadRequest("用户未绑定有效的实验板");
 | 
			
		||||
 | 
			
		||||
            var result = await debugger.ClearFlag();
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"清除触发器状态标志失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "清除触发器状态标志失败");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "清除触发器状态标志时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 读取捕获数据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpGet("ReadData")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 | 
			
		||||
    public async Task<IActionResult> ReadData([FromQuery] ushort offset = 0)
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var debugger = GetDebugger();
 | 
			
		||||
            if (debugger == null)
 | 
			
		||||
                return BadRequest("用户未绑定有效的实验板");
 | 
			
		||||
 | 
			
		||||
            var result = await debugger.ReadData(offset);
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"读取捕获数据失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "读取捕获数据失败");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 返回Base64编码
 | 
			
		||||
            var base64Data = Convert.ToBase64String(result.Value);
 | 
			
		||||
            return Ok(base64Data);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "读取捕获数据时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 刷新调试器状态
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [HttpPost("Refresh")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
 | 
			
		||||
    public async Task<IActionResult> Refresh()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var debugger = GetDebugger();
 | 
			
		||||
            if (debugger == null)
 | 
			
		||||
                return BadRequest("用户未绑定有效的实验板");
 | 
			
		||||
 | 
			
		||||
            var result = await debugger.Refresh();
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"刷新调试器状态失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "刷新调试器状态失败");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "刷新调试器状态时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "操作失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										356
									
								
								src/APIClient.ts
									
									
									
									
									
								
							
							
						
						
									
										356
									
								
								src/APIClient.ts
									
									
									
									
									
								
							@@ -1637,6 +1637,362 @@ export class DDSClient {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DebuggerClient {
 | 
			
		||||
    private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
 | 
			
		||||
    private baseUrl: string;
 | 
			
		||||
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
 | 
			
		||||
 | 
			
		||||
    constructor(baseUrl?: string, http?: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> }) {
 | 
			
		||||
        this.http = http ? http : window as any;
 | 
			
		||||
        this.baseUrl = baseUrl ?? "http://127.0.0.1:5000";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 设置捕获模式
 | 
			
		||||
     */
 | 
			
		||||
    setMode(mode: string): Promise<boolean> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Debugger/SetMode";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        const content_ = JSON.stringify(mode);
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            body: content_,
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Content-Type": "application/json",
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processSetMode(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processSetMode(response: Response): Promise<boolean> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 400) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result400: any = null;
 | 
			
		||||
            let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result400 = ProblemDetails.fromJS(resultData400);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result400);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 401) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result401: any = null;
 | 
			
		||||
            let resultData401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result401 = ProblemDetails.fromJS(resultData401);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result401);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<boolean>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 启动触发器
 | 
			
		||||
     */
 | 
			
		||||
    startTrigger(): Promise<boolean> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Debugger/StartTrigger";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processStartTrigger(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processStartTrigger(response: Response): Promise<boolean> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 400) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result400: any = null;
 | 
			
		||||
            let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result400 = ProblemDetails.fromJS(resultData400);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result400);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 401) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result401: any = null;
 | 
			
		||||
            let resultData401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result401 = ProblemDetails.fromJS(resultData401);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result401);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<boolean>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 读取触发器状态标志
 | 
			
		||||
     */
 | 
			
		||||
    readFlag(): Promise<number> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Debugger/ReadFlag";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processReadFlag(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processReadFlag(response: Response): Promise<number> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 400) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result400: any = null;
 | 
			
		||||
            let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result400 = ProblemDetails.fromJS(resultData400);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result400);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 401) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result401: any = null;
 | 
			
		||||
            let resultData401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result401 = ProblemDetails.fromJS(resultData401);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result401);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<number>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 清除触发器状态标志
 | 
			
		||||
     */
 | 
			
		||||
    clearFlag(): Promise<boolean> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Debugger/ClearFlag";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processClearFlag(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processClearFlag(response: Response): Promise<boolean> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 400) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result400: any = null;
 | 
			
		||||
            let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result400 = ProblemDetails.fromJS(resultData400);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result400);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 401) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result401: any = null;
 | 
			
		||||
            let resultData401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result401 = ProblemDetails.fromJS(resultData401);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result401);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<boolean>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 读取捕获数据
 | 
			
		||||
     * @param offset (optional) 
 | 
			
		||||
     */
 | 
			
		||||
    readData(offset: number | undefined): Promise<string> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Debugger/ReadData?";
 | 
			
		||||
        if (offset === null)
 | 
			
		||||
            throw new Error("The parameter 'offset' cannot be null.");
 | 
			
		||||
        else if (offset !== undefined)
 | 
			
		||||
            url_ += "offset=" + encodeURIComponent("" + offset) + "&";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processReadData(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processReadData(response: Response): Promise<string> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 400) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result400: any = null;
 | 
			
		||||
            let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result400 = ProblemDetails.fromJS(resultData400);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result400);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 401) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result401: any = null;
 | 
			
		||||
            let resultData401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result401 = ProblemDetails.fromJS(resultData401);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result401);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<string>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 刷新调试器状态
 | 
			
		||||
     */
 | 
			
		||||
    refresh(): Promise<boolean> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Debugger/Refresh";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processRefresh(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processRefresh(response: Response): Promise<boolean> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 400) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result400: any = null;
 | 
			
		||||
            let resultData400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result400 = ProblemDetails.fromJS(resultData400);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result400);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 401) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result401: any = null;
 | 
			
		||||
            let resultData401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result401 = ProblemDetails.fromJS(resultData401);
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers, result401);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<boolean>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class JtagClient {
 | 
			
		||||
    private http: { fetch(url: RequestInfo, init?: RequestInit): Promise<Response> };
 | 
			
		||||
    private baseUrl: string;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,12 +2,12 @@
 | 
			
		||||
  <div
 | 
			
		||||
    class="w-full"
 | 
			
		||||
    :class="{
 | 
			
		||||
      'h-48': !analyzer.logicData.value,
 | 
			
		||||
      'h-150': analyzer.logicData.value,
 | 
			
		||||
      'h-48': !props.data,
 | 
			
		||||
      'h-150': props.data,
 | 
			
		||||
    }"
 | 
			
		||||
  >
 | 
			
		||||
    <v-chart
 | 
			
		||||
      v-if="analyzer.logicData.value"
 | 
			
		||||
      v-if="props.data"
 | 
			
		||||
      class="w-full h-full"
 | 
			
		||||
      :option="option"
 | 
			
		||||
      autoresize
 | 
			
		||||
@@ -17,17 +17,20 @@
 | 
			
		||||
      v-else
 | 
			
		||||
      class="w-full h-full flex flex-col gap-6 items-center justify-center"
 | 
			
		||||
    >
 | 
			
		||||
      <div class="text-center">
 | 
			
		||||
        <h3 class="text-xl font-semibold text-slate-600 mb-2">
 | 
			
		||||
          暂无逻辑分析数据
 | 
			
		||||
        </h3>
 | 
			
		||||
      </div>
 | 
			
		||||
      <template v-if="hasSlot">
 | 
			
		||||
        <slot />
 | 
			
		||||
      </template>
 | 
			
		||||
      <template v-else>
 | 
			
		||||
        <div class="text-center">
 | 
			
		||||
          <h3 class="text-xl font-semibold text-slate-600 mb-2">暂无数据</h3>
 | 
			
		||||
        </div>
 | 
			
		||||
      </template>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, shallowRef } from "vue";
 | 
			
		||||
import { computed, shallowRef, useSlots } from "vue";
 | 
			
		||||
import VChart from "vue-echarts";
 | 
			
		||||
 | 
			
		||||
// Echarts
 | 
			
		||||
@@ -56,9 +59,8 @@ import type {
 | 
			
		||||
  XAXisOption,
 | 
			
		||||
  YAXisOption,
 | 
			
		||||
} from "echarts/types/dist/shared";
 | 
			
		||||
import { useRequiredInjection } from "@/utils/Common";
 | 
			
		||||
import { isUndefined } from "lodash";
 | 
			
		||||
import { useWaveformManager } from "./WaveformManager";
 | 
			
		||||
import type { LogicDataType } from ".";
 | 
			
		||||
 | 
			
		||||
use([
 | 
			
		||||
  TooltipComponent,
 | 
			
		||||
@@ -81,7 +83,12 @@ type EChartsOption = ComposeOption<
 | 
			
		||||
  | MarkLineComponentOption
 | 
			
		||||
>;
 | 
			
		||||
 | 
			
		||||
const analyzer = useRequiredInjection(useWaveformManager);
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  data?: LogicDataType;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const slots = useSlots();
 | 
			
		||||
const hasSlot = computed(() => !!slots.default && slots.default().length > 0);
 | 
			
		||||
 | 
			
		||||
// 添加更新选项来减少重绘
 | 
			
		||||
const updateOptions = shallowRef({
 | 
			
		||||
@@ -91,13 +98,13 @@ const updateOptions = shallowRef({
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const option = computed((): EChartsOption => {
 | 
			
		||||
  if (isUndefined(analyzer.logicData.value)) return {};
 | 
			
		||||
  if (isUndefined(props.data)) return {};
 | 
			
		||||
 | 
			
		||||
  // 只获取启用的通道,使用y数据结构
 | 
			
		||||
  const enabledChannels = analyzer.logicData.value.y.filter(
 | 
			
		||||
  const enabledChannels = props.data.y.filter(
 | 
			
		||||
    (channel) => channel.enabled,
 | 
			
		||||
  );
 | 
			
		||||
  const enabledChannelIndices = analyzer.logicData.value.y
 | 
			
		||||
  const enabledChannelIndices = props.data.y
 | 
			
		||||
    .map((channel, index) => (channel.enabled ? index : -1))
 | 
			
		||||
    .filter((index) => index !== -1);
 | 
			
		||||
 | 
			
		||||
@@ -124,11 +131,11 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
    {
 | 
			
		||||
      type: "category",
 | 
			
		||||
      boundaryGap: true,
 | 
			
		||||
      data: analyzer.logicData.value.x.map((x) => x.toFixed(3)),
 | 
			
		||||
      data: props.data.x.map((x) => x.toFixed(3)),
 | 
			
		||||
      axisLabel: {
 | 
			
		||||
        formatter: (value: string) =>
 | 
			
		||||
          analyzer.logicData.value
 | 
			
		||||
            ? `${value}${analyzer.logicData.value.xUnit}`
 | 
			
		||||
          props.data
 | 
			
		||||
            ? `${value}${props.data.xUnit}`
 | 
			
		||||
            : `${value}`,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
@@ -157,7 +164,7 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
  const series: LineSeriesOption[] = [];
 | 
			
		||||
  enabledChannelIndices.forEach(
 | 
			
		||||
    (originalIndex: number, displayIndex: number) => {
 | 
			
		||||
      const channel = analyzer.logicData.value!.y[originalIndex];
 | 
			
		||||
      const channel = props.data!.y[originalIndex];
 | 
			
		||||
      if (channel.type === "logic") {
 | 
			
		||||
        // logic类型,原样显示
 | 
			
		||||
        series.push({
 | 
			
		||||
@@ -182,7 +189,7 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
        });
 | 
			
		||||
      } else if (channel.type === "number") {
 | 
			
		||||
        const values = channel.value;
 | 
			
		||||
        const xArr = analyzer.logicData.value!.x;
 | 
			
		||||
        const xArr = props.data!.x;
 | 
			
		||||
        // 构造带过渡的点序列
 | 
			
		||||
        function buildVcdLine(valArr: number[], high: number, low: number) {
 | 
			
		||||
          const points: { x: number; y: number }[] = [];
 | 
			
		||||
@@ -208,7 +215,8 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
          let lastIdx = 0;
 | 
			
		||||
          // 格式化函数
 | 
			
		||||
          function formatValue(val: number) {
 | 
			
		||||
            if (channel.base === "hex") return "0x" + val.toString(16).toUpperCase();
 | 
			
		||||
            if (channel.base === "hex")
 | 
			
		||||
              return "0x" + val.toString(16).toUpperCase();
 | 
			
		||||
            if (channel.base === "bin") return "0b" + val.toString(2);
 | 
			
		||||
            return val.toString();
 | 
			
		||||
          }
 | 
			
		||||
@@ -314,12 +322,12 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
      },
 | 
			
		||||
      formatter: (params: any) => {
 | 
			
		||||
        if (Array.isArray(params) && params.length > 0) {
 | 
			
		||||
          const timeValue = analyzer.logicData.value!.x[params[0].dataIndex];
 | 
			
		||||
          const timeValue = props.data!.x[params[0].dataIndex];
 | 
			
		||||
          const dataIndex = params[0].dataIndex;
 | 
			
		||||
          let tooltip = `Time: ${timeValue.toFixed(3)}${analyzer.logicData.value!.xUnit}<br/>`;
 | 
			
		||||
          let tooltip = `Time: ${timeValue.toFixed(3)}${props.data!.xUnit}<br/>`;
 | 
			
		||||
          enabledChannelIndices.forEach(
 | 
			
		||||
            (originalIndex: number, displayIndex: number) => {
 | 
			
		||||
              const channel = analyzer.logicData.value!.y[originalIndex];
 | 
			
		||||
              const channel = props.data!.y[originalIndex];
 | 
			
		||||
              if (channel.type === "logic") {
 | 
			
		||||
                const channelName = channel.name;
 | 
			
		||||
                const originalValue = channel.value[dataIndex];
 | 
			
		||||
 
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
import { createInjectionState } from "@vueuse/core";
 | 
			
		||||
import { shallowRef } from "vue";
 | 
			
		||||
 | 
			
		||||
export type LogicDataType = {
 | 
			
		||||
  x: number[];
 | 
			
		||||
  y: {
 | 
			
		||||
    enabled: boolean;
 | 
			
		||||
    type: "logic" | "number";
 | 
			
		||||
    name: string;
 | 
			
		||||
    color: string;
 | 
			
		||||
    value: number[];
 | 
			
		||||
    base: "bin" | "dec" | "hex";
 | 
			
		||||
  }[];
 | 
			
		||||
  xUnit: "s" | "ms" | "us" | "ns";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 生成4路测试数据的函数
 | 
			
		||||
export function generateTestData(): LogicDataType {
 | 
			
		||||
  // 生成时间轴数据 (0-100ns,每1ns一个采样点)
 | 
			
		||||
  const timePoints = Array.from({ length: 101 }, (_, i) => i);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    x: timePoints,
 | 
			
		||||
    y: [
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "CLK",
 | 
			
		||||
        color: "#ff0000",
 | 
			
		||||
        value: timePoints.map((t) => t % 2), // 时钟信号,每1ns翻转
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "RESET",
 | 
			
		||||
        color: "#00ff00",
 | 
			
		||||
        value: timePoints.map((t) => (t < 10 ? 1 : 0)), // 复位信号,前10ns为高电平
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "number",
 | 
			
		||||
        name: "DATA",
 | 
			
		||||
        color: "#0000ff",
 | 
			
		||||
        value: timePoints.map((t) => Math.floor(t / 4) % 16), // 计数器,每4ns递增
 | 
			
		||||
        base: "hex",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "ENABLE",
 | 
			
		||||
        color: "#ff8800",
 | 
			
		||||
        value: timePoints.map((t) => (t >= 20 && t < 80 ? 1 : 0)), // 使能信号,20-80ns为高电平
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    xUnit: "ns",
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const [useProvideWaveformManager, useWaveformManager] = createInjectionState(
 | 
			
		||||
  () => {
 | 
			
		||||
    const logicData = shallowRef<LogicDataType>();
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      logicData,
 | 
			
		||||
      generateTestData,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export { useProvideWaveformManager, useWaveformManager };
 | 
			
		||||
@@ -1,5 +1,61 @@
 | 
			
		||||
import WaveformDisplay from "./WaveformDisplay.vue";
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
  WaveformDisplay
 | 
			
		||||
export type LogicDataType = {
 | 
			
		||||
  x: number[];
 | 
			
		||||
  y: {
 | 
			
		||||
    enabled: boolean;
 | 
			
		||||
    type: "logic" | "number";
 | 
			
		||||
    name: string;
 | 
			
		||||
    color: string;
 | 
			
		||||
    value: number[];
 | 
			
		||||
    base: "bin" | "dec" | "hex";
 | 
			
		||||
  }[];
 | 
			
		||||
  xUnit: "s" | "ms" | "us" | "ns";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 生成4路测试数据的函数
 | 
			
		||||
export function generateTestData(): LogicDataType {
 | 
			
		||||
  // 生成时间轴数据 (0-100ns,每1ns一个采样点)
 | 
			
		||||
  const timePoints = Array.from({ length: 101 }, (_, i) => i);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    x: timePoints,
 | 
			
		||||
    y: [
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "CLK",
 | 
			
		||||
        color: "#ff0000",
 | 
			
		||||
        value: timePoints.map((t) => t % 2), // 时钟信号,每1ns翻转
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "RESET",
 | 
			
		||||
        color: "#00ff00",
 | 
			
		||||
        value: timePoints.map((t) => (t < 10 ? 1 : 0)), // 复位信号,前10ns为高电平
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "number",
 | 
			
		||||
        name: "DATA",
 | 
			
		||||
        color: "#0000ff",
 | 
			
		||||
        value: timePoints.map((t) => Math.floor(t / 4) % 16), // 计数器,每4ns递增
 | 
			
		||||
        base: "hex",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        type: "logic",
 | 
			
		||||
        name: "ENABLE",
 | 
			
		||||
        color: "#ff8800",
 | 
			
		||||
        value: timePoints.map((t) => (t >= 20 && t < 80 ? 1 : 0)), // 使能信号,20-80ns为高电平
 | 
			
		||||
        base: "bin",
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
    xUnit: "ns",
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { WaveformDisplay };
 | 
			
		||||
 
 | 
			
		||||
@@ -103,15 +103,11 @@ import { isNull, toNumber } from "lodash";
 | 
			
		||||
import { onMounted, ref, watch } from "vue";
 | 
			
		||||
import Debugger from "./Debugger.vue";
 | 
			
		||||
import { useProvideLogicAnalyzer } from "@/components/LogicAnalyzer";
 | 
			
		||||
import { useProvideWaveformManager } from "@/components/WaveformDisplay/WaveformManager";
 | 
			
		||||
import { useProvideOscilloscope } from "@/components/Oscilloscope/OscilloscopeManager";
 | 
			
		||||
 | 
			
		||||
const analyzer = useProvideLogicAnalyzer();
 | 
			
		||||
const waveformManager = useProvideWaveformManager();
 | 
			
		||||
const oscilloscopeManager = useProvideOscilloscope();
 | 
			
		||||
 | 
			
		||||
waveformManager.logicData.value = waveformManager.generateTestData();
 | 
			
		||||
 | 
			
		||||
const checkID = useLocalStorage("checkID", 1);
 | 
			
		||||
 | 
			
		||||
// 定义事件
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user