protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (var pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetDescription("Установка переменных окружения U-Boot"); pc.SetToIntermediate(); Context.Surfer.SeekForMatches(Context.Terminal, new CommandExpectation(@"SMDKC100 #", Context.Terminal, "setenv bootdelay 0")); Context.Surfer.SeekForMatches(Context.Terminal, new CommandExpectation(@"SMDKC100 #", Context.Terminal, @"setenv bootcmd nand read {0:x} {1:x} {2:x}\;bootm {0:x}", _temporaryAddress, _kernlPosition.Address, _kernlPosition.AlignedSize)); Context.Surfer.SeekForMatches(Context.Terminal, new CommandExpectation(@"SMDKC100 #", Context.Terminal, @"setenv bootargs s3c2410-wdt.tmr_margin=25")); Context.Surfer.SeekForMatches(Context.Terminal, new CommandExpectation(@"SMDKC100 #", Context.Terminal, "saveenv")); Context.Surfer.SeekForMatches(Context.Terminal, new DelegateExpectation(@"s3c-nand: (?<bits>\d+) bit(s) error detected, (?<result>.+)\n", m => { if (m.Groups["result"].Value != "corrected successfully") throw new NandWriteErrorDnwBurningException( "Ошибка при выполнении команды saveenv"); return false; }), new BarrierExpectation(@"Writing to Nand... done")); } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetProgress(0); pc.SetDescription(Name + "..."); var cts = new CancellationTokenSource(); const int sleepingDiscrete = 100; Task.Factory.StartNew( () => { for (int i = 0; i < _expectedDeploymentTime.TotalMilliseconds - sleepingDiscrete * 2; i += sleepingDiscrete) { cts.Token.ThrowIfCancellationRequested(); Thread.Sleep(sleepingDiscrete); pc.SetProgress(i / _expectedDeploymentTime.TotalMilliseconds); } if (!cts.Token.IsCancellationRequested) pc.SetToIntermediate(); }, cts.Token); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new DelegateExpectation(@"ERROR: can't get kernel image!", true, m => { throw new WrittenImageWasCorruptedDnwBurningException(); }), new DelegateExpectation(@"INITIALIZATION COMPLEATED", true, m => cts.Cancel())); } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetProgress(0); pc.SetDescription(string.Format("Запись образа {0} на NAND {{0:P0}}", _dataName), Progress); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new CommandExpectation(@"SMDKC100 #", Context.Terminal, @"nand write.yaffs {0:x} {1:x} {2:x}", _dataRamAddress, _destinationAddress, _dataLength)); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new DelegateExpectation(@"Writing data at 0x(?<address>[0-9a-zA-Z]+) --\s+(?<progress>\d+)% complete\.", false, match => { if (uint.Parse(match.Groups["address"].Value, NumberStyles.HexNumber) >= _destinationAddress + _partitionSize) throw new YaffsOutOfBoundsException(); pc.SetProgress(0.01 * int.Parse(match.Groups["progress"].Value)); }), new DelegateExpectation(@"(?<length>\d+) bytes written\: (?<result>.+)\n", true, match => { if (match.Groups["result"].Value != "OK") throw new NandWriteErrorDnwBurningException(match.Groups["result"].Value); })); } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetDescription("Загрузка системы"); Context.Surfer.SeekForMatches(Context.Terminal, new CommandExpectation(@"SMDKC100 #", Context.Terminal, @"boot")); } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { string command = string.Format("nand write {0:x} {1:x} {2:x}", DataRamAddress, DestinationAddress, DataLength); ExecuteOperation(Context, pc, command, CancellationToken); PostPositionInformation(DataRamAddress, DataLength); } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetToIntermediate(); pc.SetDescription(Name); var re = new ManualResetEventSlim(false); var t = new Task(() => { while (!re.IsSet) { Context.Terminal.WriteLine(); Thread.Sleep(100); } }); Stopwatch sw = Stopwatch.StartNew(); while (true) { try { Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new DelegateExpectation(@"U-Boot", true, Match => t.Start())); break; } catch (TimeoutTerminalException e) { if (sw.Elapsed >= _timeout) throw new CanNotConnectToUBoot(e); } } sw.Stop(); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new DelegateExpectation(@"NAND:\s+(?<size>\d+) MB", false, m => Context.NandSize = ulong.Parse(m.Groups["size"].Value) * 1024 * 1024), new DelegateExpectation(@"NAND read", true, Match => { throw new UBootInterruptionWasSkippedDnwBurningException(); }), new DelegateExpectation(@"SMDKC100 #", true, Match => { re.Set(); Context.Terminal.WriteLine(); })); re.Set(); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new CommandExpectation(@"SMDKC100 #", Context.Terminal, "version")); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new DelegateExpectation(@"U-Boot (?<version>[\d\.]+).*\n", true, m => CheckUBootVersion(Version.Parse(m.Groups["version"].Value)))); Context.State = ProgrammingContextState.UBoot; } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (var pc = new ProgressController(Progress)) { pc.SetDescription("Подключение по USB..."); using (UsbConnection connection = Context.Usb.Connect(_usbConnectionTimeout, CancellationToken)) { pc.SetDescription(string.Format("Отправка {0} по USB {{0:P0}}", _dataName), Progress); connection.Write(_data, _address, Progress, CancellationToken); } } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { var transferProgress = new SubprocessProgressToken(); var checkProgress = new SubprocessProgressToken(); using (new CompositeProgressManager(Progress, transferProgress, checkProgress)) { Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new CommandExpectation(@"SMDKC100 #", Context.Terminal, "dnw {0:x}", _address)); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new AbortExpectation(@"SMDKC100 #", m => new UnexpectedOutputDnwException()), new BarrierExpectation(@"Insert a OTG cable into the connector!"), new BarrierExpectation(@"OTG cable Connected!")); Thread.Sleep(500); using (IProgressController pc = Context.ProgressControllerFactory.CreateController(transferProgress)) { pc.SetDescription("Подключение к U-Boot по USB..."); using (UsbConnection usb = Context.Usb.Connect(_usbConnectionTimeout, CancellationToken, UsbBlockSize)) { pc.SetDescription(string.Format("Отправка {0} по USB {{0:P0}}", _dataName), transferProgress); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new AbortExpectation(@"SMDKC100 #", m => new UnexpectedOutputDnwException()), new BarrierExpectation(@"Now, Waiting for DNW to transmit data")); Thread.Sleep(500); usb.Write(_data, _address, transferProgress, CancellationToken); } } using (IProgressController pc = Context.ProgressControllerFactory.CreateController(checkProgress)) { pc.SetDescription(string.Format("Подсчёт контрольной суммы {0} {{0:P0}}", _dataName), checkProgress); int i = 0; Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new BarrierExpectation(@"Checksum is being calculated")); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new AbortExpectation(@"SMDKC100 #", m => new UnexpectedOutputDnwException()), new DelegateExpectation(@"^\.$", false, match => pc.SetProgress((double)(++i) * 1041360 / _data.Length)), new DelegateExpectation(@"Checksum (?<result>.*)\n", true, match => { if (match.Groups["result"].Value != "O.K.") { throw new UsbTransmitChecksumMismatchDnwBurningException( match.Groups["result"].Value); } }, SurfingMethod.ByCharacter)); } } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { Stopwatch sw = Stopwatch.StartNew(); using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetDescription("Ожидание..."); pc.SetProgress(0); while (sw.Elapsed < _duration) { CancellationToken.ThrowIfCancellationRequested(); Thread.Sleep((int)Math.Min(SleepDiscredMs, _duration.TotalMilliseconds - sw.ElapsedMilliseconds)); pc.SetProgress(sw.ElapsedMilliseconds / _duration.TotalMilliseconds); } } }
protected void ExecuteOperation(OperatingContext Context, IProgressController pc, string Command, CancellationToken CancellationToken) { pc.SetProgress(0); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new CommandExpectation(@"SMDKC100 #", Context.Terminal, Command)); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new DelegateExpectation(@"Writing data at 0x([0-9a-fA-F]+) --\s+(?<progress>\d+)% complete\.", false, match => pc.SetProgress(0.01 * int.Parse(match.Groups["progress"].Value))), new DelegateExpectation(@"(?<length>\d+) bytes written\: (?<result>.+)\n", true, match => { if (match.Groups["result"].Value != "OK") throw new NandWriteErrorDnwBurningException(match.Groups["result"].Value); })); }
public void Operate(OperatingContext Context, CancellationToken CancellationToken) { ProgrammingContextState stateRestriction = GetType().GetMethod("OperateImpl", BindingFlags.Instance | BindingFlags.NonPublic) .GetCustomAttributes(typeof (StateRestrictionAttribute), true) .OfType<StateRestrictionAttribute>() .Select(a => a.RequiredState) .DefaultIfEmpty(ProgrammingContextState.Any) .First(); if (stateRestriction != ProgrammingContextState.Any && stateRestriction != Context.State) throw new WrongProgrammingContextException(Context.State, stateRestriction, this); Debug.Print("Начинаем операцию {0}", GetType().Name); Stopwatch sw = Stopwatch.StartNew(); OperateImpl(Context, CancellationToken); sw.Stop(); Debug.Print("Завершили операцию за {0:F3} сек, ожидали {1:F3} сек.", sw.Elapsed.TotalSeconds, Progress.Weight * 0.001); Debug.Print("--------------------------------------------------------"); }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetProgress(0); pc.SetDescription("Отчистка NAND {0:P0}", Progress); var badBlocks = new SortedSet<uint>(); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new CommandExpectation(@"SMDKC100 #", Context.Terminal, "nand erase {0:X} {1}", _startAddress, _endAddress != null ? _endAddress.Value.ToString("X") : "")); Context.Surfer.SeekForMatches(Context.Terminal, CancellationToken, new AbortExpectation(@"SMDKC100 #", m => new UnexpectedOutputDnwException()), new DelegateExpectation(@"Erasing at 0x([0-9a-fA-F]+) --\s+(?<progress>\d+)% complete", false, match => pc.SetProgress(0.01 * int.Parse(match.Groups["progress"].Value))), new DelegateExpectation(@"Skipping bad block at\s+0x(?<bad>[A-Za-z\d]+)\s*\n", false, match => badBlocks.Add(uint.Parse(match.Groups["bad"].Value, NumberStyles.HexNumber))), new BarrierExpectation(@"OK")); Context.BadBlocks = badBlocks; } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { if (Context.BadBlocks == null) throw new BadBlocksNotRequestedException(); using (IProgressController pc = Context.ProgressControllerFactory.CreateController(Progress)) { pc.SetDescription(string.Format("{0} {{0:P0}}", Name), Progress); uint address = DestinationAddress; int alignedLength = Context.BlockSize * (int)Math.Ceiling((double)DataLength / Context.BlockSize); while (Context.BadBlocks.Any(b => b + Context.BlockSize > address && b < address + DataLength)) { address = Context.BadBlocks.First(b => b >= address) + (uint)Context.BlockSize; if (address + DataLength > DestinationAddress + _partitionSize) throw new NandPlacementException(); } string command = string.Format("nand write {0:x} {1:x} {2:x}", DataRamAddress, address, alignedLength); ExecuteOperation(Context, pc, command, CancellationToken); PostPositionInformation(address, alignedLength); } }
protected override void OperateImpl(OperatingContext Context, CancellationToken CancellationToken) { int badSize = Context.BadBlocks.Count * Context.BlockSize; if (badSize > _allowableBadMemoryPortion * Context.NandSize) throw new TooManyBadBlocksDnwBurningException(badSize, Context.NandSize); }
protected abstract void OperateImpl(OperatingContext Context, CancellationToken CancellationToken);