1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using Antmicro.Renode.Peripherals.Timers; 10 using NUnit.Framework; 11 using System.Threading; 12 using System.Diagnostics; 13 using Antmicro.Renode.Time; 14 using Antmicro.Renode.Core; 15 using Antmicro.Renode.Peripherals; 16 17 namespace Antmicro.Renode.UnitTests 18 { 19 [TestFixture] 20 public class CoreTimerTest 21 { 22 [Test] ShouldBeAscending()23 public void ShouldBeAscending() 24 { 25 var manualClockSource = new ManualClockSource(); 26 var timer = new LimitTimer(manualClockSource, 100, null, String.Empty, 100000, Direction.Ascending, true); 27 var oldValue = 0UL; 28 for(var i = 0; i < 100; i++) 29 { 30 manualClockSource.AdvanceBySeconds(1); 31 var value = timer.Value; 32 Assert.Greater(value, oldValue, "Timer is not monotonic."); 33 oldValue = value; 34 } 35 } 36 37 [Test] ShouldBeDescending()38 public void ShouldBeDescending() 39 { 40 var manualClockSource = new ManualClockSource(); 41 var timer = new LimitTimer(manualClockSource, 100, null, String.Empty, 100000, Direction.Descending, true); 42 var oldValue = timer.Limit; 43 for(var i = 0; i < 100; i++) 44 { 45 manualClockSource.AdvanceBySeconds(1); 46 var value = timer.Value; 47 Assert.Less(value, oldValue, "Timer is not monotonic."); 48 oldValue = value; 49 } 50 } 51 52 [Test] ShouldNotExceedLimitAscending()53 public void ShouldNotExceedLimitAscending() 54 { 55 var limit = 100UL; 56 var manualClockSource = new ManualClockSource(); 57 var timer = new LimitTimer(manualClockSource, 1, null, String.Empty, limit, Direction.Ascending, true); 58 manualClockSource.AdvanceBySeconds(limit - 1); 59 for(var i = 0; i < 3; ++i) 60 { 61 var value = timer.Value; 62 Assert.LessOrEqual(value, limit, "Timer exceeded given limit."); 63 Assert.GreaterOrEqual(value, 0, "Timer returned negative value."); 64 manualClockSource.AdvanceBySeconds(1); 65 } 66 } 67 68 [Test] ShouldNotExceedLimitDescending()69 public void ShouldNotExceedLimitDescending() 70 { 71 var limit = 100UL; 72 var manualClockSource = new ManualClockSource(); 73 var timer = new LimitTimer(manualClockSource, 1, null, String.Empty, limit, Direction.Descending, true); 74 manualClockSource.AdvanceBySeconds(limit - 1); 75 for(var i = 0; i < 3; i++) 76 { 77 var value = timer.Value; 78 Assert.LessOrEqual(value, limit, "Timer exceeded given limit."); 79 Assert.GreaterOrEqual(value, 0, "Timer returned negative value."); 80 manualClockSource.AdvanceBySeconds(1); 81 } 82 } 83 84 [Test] ShouldHandleMicrosecondPrecisionTimerEvents()85 public void ShouldHandleMicrosecondPrecisionTimerEvents() 86 { 87 uint activationCounter = 0; 88 89 var limit = 4UL; 90 var manualClockSource = new ManualClockSource(); 91 var timer = new LimitTimer(manualClockSource, 1000000, null, String.Empty, limit, Direction.Descending, true); 92 timer.EventEnabled = true; 93 timer.LimitReached += () => activationCounter++; 94 manualClockSource.Advance(TimeInterval.FromMicroseconds(10)); 95 96 Assert.AreEqual(2, activationCounter, "Timer did not go off twice."); 97 Assert.AreEqual(2, timer.Value, "Timer value is not expected."); 98 } 99 100 [Test] ShouldHandleSubMicrosecondPrecisionTimerEvents()101 public void ShouldHandleSubMicrosecondPrecisionTimerEvents() 102 { 103 uint activationCounter = 0; 104 105 var limit = 4UL; 106 var manualClockSource = new ManualClockSource(); 107 var timer = new LimitTimer(manualClockSource, 10000000, null, String.Empty, limit, Direction.Descending, true); 108 timer.EventEnabled = true; 109 timer.LimitReached += () => activationCounter++; 110 manualClockSource.Advance(TimeInterval.FromMicroseconds(1)); 111 112 Assert.AreEqual(2, activationCounter, "Timer did not go off twice."); 113 Assert.AreEqual(2, timer.Value, "Timer value is not expected."); 114 } 115 116 [Test] ShouldSwitchDirectionProperly()117 public void ShouldSwitchDirectionProperly() 118 { 119 var manualClockSource = new ManualClockSource(); 120 var timer = new LimitTimer(manualClockSource, 100, null, String.Empty, 100000, Direction.Ascending, true); 121 timer.EventEnabled = true; 122 var ticked = false; 123 timer.LimitReached += () => ticked = true; 124 manualClockSource.AdvanceBySeconds(2); 125 timer.Direction = Direction.Descending; // and then change the direction 126 manualClockSource.AdvanceBySeconds(2); 127 Assert.IsTrue(ticked); 128 } 129 130 [Test] ShouldNotFireAlarmWhenInterruptsAreDisabled()131 public void ShouldNotFireAlarmWhenInterruptsAreDisabled() 132 { 133 var manualClockSource = new ManualClockSource(); 134 var timer = new LimitTimer(manualClockSource, 1, null, String.Empty, 10, Direction.Descending, true); 135 var ticked = false; 136 timer.LimitReached += () => ticked = true; 137 manualClockSource.AdvanceBySeconds(11); 138 Assert.IsFalse(ticked); 139 } 140 141 [Test] ShouldFireAlarmWhenInterruptsAreEnabled()142 public void ShouldFireAlarmWhenInterruptsAreEnabled() 143 { 144 var manualClockSource = new ManualClockSource(); 145 var timer = new LimitTimer(manualClockSource, 1, null, String.Empty, 10, Direction.Descending, true); 146 timer.EventEnabled = true; 147 var ticked = false; 148 timer.LimitReached += () => ticked = true; 149 // var val =timer.Value; 150 manualClockSource.AdvanceBySeconds(10); 151 Assert.IsTrue(ticked); 152 } 153 154 private class ManualClockSource : BaseClockSource 155 { AdvanceBySeconds(ulong seconds)156 public void AdvanceBySeconds(ulong seconds) 157 { 158 Advance(TimeInterval.FromSeconds(seconds)); 159 } 160 } 161 } 162 } 163 164