// // UART 外设实现 // 基于 UART 规格,包含完整的 FIFO、中断和调制解调器控制功能 // using System; using System.Collections.Generic; using Antmicro.Renode.Core; using Antmicro.Renode.Logging; using Antmicro.Renode.Peripherals.Bus; using Antmicro.Renode.Peripherals.UART; using Antmicro.Renode.Utilities; using Antmicro.Renode.Time; namespace Antmicro.Renode.Peripherals.CustomPeripherals { /// /// 毫秒计数器 /// public class Custom_MS : IDoubleWordPeripheral, IKnownSize { private readonly IMachine machine; public Custom_MS(IMachine machine) { this.machine = machine; // 初始化寄存器 DefineRegisters(); Reset(); this.Log(LogLevel.Info, "Custom_MS initialized"); // 启动后台计时任务 // StartCountingTask(); } public void Reset() { ms_cnt = 0; // 毫秒计数 rstr = 0x00; // 复位/使能寄存器 startTime = machine.ElapsedVirtualTime; //记录启动时间 this.Log(LogLevel.Info, "Custom_MS reset, startTime={0}", startTime.TimeElapsed); } void get_msCnt() { TimeStamp currentTime = machine.ElapsedVirtualTime; TimeInterval timeDifference = currentTime.TimeElapsed - startTime.TimeElapsed; double timeDiffMs = timeDifference.TotalMilliseconds; // ms_cnt = (ushort)(timeDiffMs % 1000); ms_cnt = (ushort)timeDiffMs; this.Log(LogLevel.Info, "Custom_MS currentTime={0}", currentTime.TimeElapsed); this.Log(LogLevel.Info, "Custom_MS timeDiffMs={0}", timeDiffMs); } private void DefineRegisters() { // 寄存器访问通过 ReadDoubleWord/WriteDoubleWord 实现 } // ======================================== // IBusPeripheral 接口实现 // ======================================== public uint ReadDoubleWord(long offset) { return ReadRegisters(offset); } public void WriteDoubleWord(long offset, uint value) { WriteRegisters(offset, value); } // ======================================== // 自定义 // ======================================== public uint ReadRegisters(long offset) { uint value = 0; switch (offset) { case (long)Registers.CNT_REG: // 毫秒延迟计时 get_msCnt(); value = (uint)ms_cnt; this.Log(LogLevel.Info, "Read CNT_REG: {0}", value); break; case (long)Registers.RSTR_REG: // 复位/使能,暂无读操作 value = (uint)(rstr & 0xFF); this.Log(LogLevel.Info, "Read RSTR_REG: 0x{0}", value); break; default: this.Log(LogLevel.Warning, "Read to unknown offset: 0x{0:X}", offset); break; } return value; } public void WriteRegisters(long offset, uint value) { switch (offset) { case (long)Registers.RSTR_REG: // 复位/使能,暂无读操作 rstr = (byte)(value & 0xFF); this.Log(LogLevel.Info, "Write RSTR_REG: 0x{0:X2}", rstr); if ((rstr & 0XFF) == RSTR_RES) { Reset(); } break; default: this.Log(LogLevel.Warning, "Write to unknown offset: 0x{0:X}", offset); break; } } public long Size => 0x80; //uart地址长度总空间 // ======================================== // 寄存器定义 // ======================================== private enum Registers : long { CNT_REG = 0x00, // 毫秒延迟计时 RSTR_REG = 0x7C // 复位/使能 0x55复位清零;其他使能 } // RSTR 复位/使能寄存器 private const byte RSTR_RES = 0x55; // 0x55复位清零,其他使能 // ======================================== // 私有字段 // ======================================== private TimeStamp startTime; // 记录累加器启动时间 // 寄存器 private ushort ms_cnt; // FIFO状态寄存器 private byte rstr; // 复位/使能 } }