public bool FlashWrite(UInt32 Addr, UInt32 Size, byte[] Data) { bool status = false; Int32 Size_Left = (Int32)Size; Int32 len_actual = 0; UInt32 offset = 0; if (IsInited & Data.Length >= Size & Size > 0) { CallbackLog?.Invoke(String.Format("Flash Write at 0x{0:X}, size {1}", Addr, Size)); status = true; TimeSpan time = StopwatchUtil.Time(() => { //JLinkARM.JLINKARM_SetBP(0, AmebaZ_Addresses.FlasherBreakpoint); JLinkARM.JLINKARM_SetBPEx(AmebaZ_Addresses.FlasherBreakpoint, (0x000000F0 | 0xFFFFFF00 | 0x1)); //Thread.Sleep(25); //JLinkARM.JLINKARM_GoEx(0x8000_0000, 1); while (status) { len_actual = Size_Left; if (len_actual > AmebaZ_Addresses.FlasherDataLen) { len_actual = (Int32)AmebaZ_Addresses.FlasherDataLen; } int halted = JLinkARM.JLINKARM_WaitForHalt(2000); if (halted == 0) { CallbackError?.Invoke(String.Format("Wait for flasher Timeout!")); status = false; break; } else if (halted < 0) { CallbackError?.Invoke(String.Format("SoC Halt Error!")); status = false; break; } byte[] Data_RAW = new byte[len_actual]; Array.Copy(Data, offset, Data_RAW, 0, len_actual); GCHandle Data_RAW_hndl = GCHandle.Alloc(Data_RAW, GCHandleType.Pinned); IntPtr Data_RAW_Ptr = Data_RAW_hndl.AddrOfPinnedObject(); JLinkARM.JLINKARM_WriteMem(AmebaZ_Addresses.FlasherData, (UInt32)len_actual, Data_RAW_Ptr); Data_RAW_hndl.Free(); WriteU32(AmebaZ_Addresses.FlasherWriteAddr, Addr + offset); WriteU32(AmebaZ_Addresses.FlasherBlockWriteSize, (UInt32)len_actual); // старт записи Size_Left -= len_actual; offset += (UInt32)len_actual; if (Size_Left == 0) { break; } //JLinkARM.JLINKARM_Go(); JLinkARM.JLINKARM_GoEx(0x8000_0000, 1); } }); WriteU8(AmebaZ_Addresses.FlasherSetComplete, 0x01); // выходим из загрузчика //JLinkARM.JLINKARM_Go(); JLinkARM.JLINKARM_GoEx(0x8000_0000, 1); CallbackLog?.Invoke(String.Format("Time {0:0.00} ms, Speed {1:0.00} KB/s", time.TotalMilliseconds, (double)((double)Size / time.TotalMilliseconds))); } return(status); }