コード例 #1
0
ファイル: DebuggerEngine.cs プロジェクト: atikbif/Relkon6
        /// <summary>
        /// Обработка запросов на запись
        /// </summary>
        private void ProceedWriteItems(AbstractChannel channel)
        {
            for (int i = 0; i < this.writeItems.Count; i++)
            {
                RequestItem item = this.writeItems[i];
                // Определяем, сколько можно записать за один запрос
                int packetSize = channel.GetPacketSize(item.MemoryType);


                // Разбиваем буфер по запросам и записываем их в контроллер
                for (int j = 0; j < item.Data.Length; j += packetSize)
                {
                    int    c      = Math.Min(packetSize, item.Data.Length - j);
                    byte[] buffer = new byte[c];
                    Array.Copy(item.Data, j, buffer, 0, c);
                    try
                    {
                        channel.WriteToMemory(item.MemoryType, item.Address + j, buffer);
                        this.WritedRequestsCount++;
                    }
                    catch
                    {
                        this.ErrorWritedRequestsCount++;
                        item.Error = true;
                    }
                    // В случае необходимости, информируем о процессе записи
                    if (item.ProgressChangedCallback != null)
                    {
                        // Устанавливаем параметры для выполнения события
                        object[] Params = new object[4];
                        Params[0] = item.ProgressChangedCallback;
                        Params[1] = item.Sender;
                        Params[2] = (double)(j + c) / (item.Data.Length);
                        Params[3] = null;
                        // Выплняем Callback в главном потоке
                        this.asyncOp.Post(this.exProgressChangedDelegate, Params);
                    }
                }
                if (item.ProceedingCompletedCallback != null)
                {
                    // Нужно проинформировать элемент о завершении получения данных
                    // Устанавливаем параметры для выполнения события
                    object[] Params = new object[4];
                    Params[0] = item.ProceedingCompletedCallback;
                    Params[1] = item.Sender;
                    Params[2] = null;
                    Params[3] = item.Error;
                    // Выполняем Callback в главном потоке
                    this.asyncOp.Post(this.exProceedingCompleetedDelegate, Params);
                }
                this.writeItems.Remove(item);
                i--;
            }
        }
コード例 #2
0
ファイル: DebuggerEngine.cs プロジェクト: atikbif/Relkon6
            /// <summary>
            /// Добавляет новый элемент в запрос, с сохранением сортировки по адресу,
            /// ДОБАВЛЯТЬ ТОЛЬКО ТАК
            /// </summary>
            public void AddItem(RequestItem item)
            {
                if (this.Items.Contains(item))
                {
                    return;
                }
                if (item.MemoryType != this.MemoryType)
                {
                    throw new Exception("Типы областей памяти должны совпадать");
                }
                int idx = this.Items.BinarySearch(item);

                if (idx < 0)
                {
                    idx = ~idx;
                }
                this.Items.Insert(idx, item);
            }
コード例 #3
0
ファイル: DebuggerEngine.cs プロジェクト: atikbif/Relkon6
        /// <summary>
        /// Добавляет в очередь опороса отладчика элемент чтения данных данных
        /// </summary>
        /// <param name="Address">Адрес области памяти, к которой производится обращение</param>
        /// <param name="MemoryType">Тип области памяти, которой производится обращение</param>
        /// <param name="Buffer">Записываемые даные</param>
        /// <param name="Sender">Опрашиваемый объект</param>
        /// <param name="ProgressChangedCallback">Callback для получения информации о процессе опроса</param>
        /// <param name="CompleetingCallback">Callback для порлучения информации о завершении опроса</param>
        public void AddReadItem(int Address, MemoryType MemoryType, int Count, object Sender,
                                ProceedingProgressChangedDelegate ProgressChangedCallback, ProceedingCompleetedDelegate CompleetingCallback)
        {
            RequestItem item = new RequestItem()
            {
                Address                     = Address,
                Data                        = new byte[Count],
                MemoryType                  = MemoryType,
                RequestType                 = RequestType.Read,
                Sender                      = Sender,
                ProgressChangedCallback     = ProgressChangedCallback,
                ProceedingCompletedCallback = CompleetingCallback
            };

            this.lockingMemoryType = MemoryType;
            this.lockingAddress    = Address;
            this.lockingLength     = Count;
            this.lockingActive     = true;
            this.AddReadItem(item);
            this.lockingActive = false;
        }
コード例 #4
0
ファイル: DebuggerEngine.cs プロジェクト: atikbif/Relkon6
        /// <summary>
        /// Добавляет в очередь опороса отладчика объект записи данных
        /// </summary>
        private void AddReadItem(RequestItem item)
        {
            if (this.maxRequestSize == -1)
            {
                if (this.Parameters.ProcessorType == ProcessorType.AT89C51ED2)
                {
                    this.maxRequestSize = 8;
                }
                else
                {
                    // Максимальный размер запроса неизвестен
                    this.readItems.Add(item);
                    return;
                }
            }
            ReadRequest request = new ReadRequest(item.Address, item.MemoryType, item.Size, this.GetRequestMinBytesToRead(), this.GetRequestMaxBytesToRead(item.MemoryType));

            request.AddItem(item);
            // Получаем список запросов, в который надо добавить элемент
            List <ReadRequest> requests = this.requestsByMemory[item.MemoryType] as List <ReadRequest>;

            if (requests == null)
            {
                requests = new List <ReadRequest>();
                this.requestsByMemory.Add(item.MemoryType, requests);
            }
            // Получаем индекс запроса, адрес которого больше или равен адресу добавляемого элемента
            int idx = requests.BinarySearch(request);

            if (idx < 0)
            {
                idx = ~idx;
            }
            // Добавляем элемент в очередь запросов
            if (requests.Count == 0)
            {
                requests.Add(request);
            }
            else if (idx < requests.Count && requests[idx].Address == item.Address)
            {
                // Адрес idx-запроса совпадает с адресом переменной
                requests[idx].AddItem(item);
                if (item.EndByteOffset > requests[idx].EndByteOffset)
                {
                    requests[idx].ChangeBytesToRead(requests[idx].BytesToRead + Math.Min(item.EndByteOffset - requests[idx].EndByteOffset, requests[idx].GrowUpBytesCount));
                }
            }
            else if (idx == 0)
            {
                // Адрес запроса наименьший из всех опрашиваемых
                requests.Insert(idx, request);
            }
            else if (requests[idx - 1].EndByteOffset + Math.Min(7, requests[idx - 1].GrowUpBytesCount) >= item.Address)
            {
                // По краеней мере часть элемента опрашивается текущим запросом
                requests[--idx].AddItem(item);
                if (item.EndByteOffset > requests[idx].EndByteOffset)
                {
                    requests[idx].ChangeBytesToRead(requests[idx].BytesToRead + Math.Min(item.EndByteOffset - requests[idx].EndByteOffset, requests[idx].GrowUpBytesCount));
                }
            }
            else
            {
                // Элемент находитя между запросами и не может быт опрошен левым даже частично
                requests.Insert(idx, request);
            }
            // Опрос элемента начинается запросом с индексом idx
            int  c    = idx;
            bool exit = true;

            do
            {
                // Убираем накладывающиеся друг на друга вопросы
                for (int i = c + 1; i < requests.Count && requests[i].Address <= requests[c].EndByteOffset + 1 + Math.Min(7, requests[c].GrowUpBytesCount); i++)
                {
                    if (requests[c].Address + requests[c].BytesToRead + requests[c].GrowUpBytesCount - 1 >= requests[i].EndByteOffset)
                    {
                        // Запрос целиком поглощается текущим => элементы переносим в текущий, а сам запрос удаляем из списка
                        requests[c].AddItems(requests[i].Items);
                        // Изменяем размер запроса
                        if (requests[c].GrowUpBytesCount > 0)
                        {
                            requests[c].ChangeBytesToRead(requests[i].EndByteOffset + 1 - requests[c].Address);
                        }
                        requests.RemoveAt(i--);
                    }
                    else
                    {
                        // Запрос накладывается на текущий частично => урезаем или смещаем его, элементы переносим в текущий
                        for (int k = i; k < requests.Count && requests[k - 1].EndByteOffset >= requests[k].Address; k++)
                        {
                            int newAddress = requests[k - 1].Address + requests[k - 1].BytesToRead + requests[k - 1].GrowUpBytesCount;
                            for (int j = 0; j < requests[k].Items.Count && requests[k].Items[j].Address < newAddress; j++)
                            {
                                requests[k - 1].AddItem(requests[k].Items[j]);
                                if (requests[k].Items[j].EndByteOffset < newAddress)
                                {
                                    requests[k].Items.RemoveAt(j--);
                                }
                            }
                            if (requests[k].Items.Count == 0)
                            {
                                requests.RemoveAt(k--);
                            }
                            else
                            {
                                requests[k].ChangeAddress(newAddress);
                            }
                        }
                    }
                }
                // Вычисляем условие выхода
                bool ItemCoveredByRequests = (item.EndByteOffset <= requests[c].EndByteOffset);
                if (!ItemCoveredByRequests)
                {
                    // Элемент не покрывается запросами
                    c++;
                    if (c >= requests.Count || requests[c].Address > requests[c - 1].EndByteOffset + 1)
                    {
                        // Зпросов больше нет, либо между ними ести "дыра"
                        requests.Insert(c, new ReadRequest(requests[c - 1].EndByteOffset + 1, item.MemoryType, item.EndByteOffset - requests[c - 1].EndByteOffset, this.GetRequestMinBytesToRead(), this.GetRequestMaxBytesToRead(item.MemoryType)));
                    }
                    requests[c].AddItem(item);
                }
                exit = ItemCoveredByRequests;
            }while (!exit);
        }
コード例 #5
0
ファイル: DebuggerEngine.cs プロジェクト: atikbif/Relkon6
        /// <summary>
        /// Удаляет опрашиваемый элемент из очереди запрсов отладчика
        /// </summary>
        /// <param name="Address">Адрес удаляемого элемента</param>
        /// <param name="MemoryType">Тип памяти, с которым работает удаляемый элемент</param>
        /// <param name="Sender">Идентификатор удаляемого элемента</param>
        public void RemoveReadItem(int Address, MemoryType MemoryType, object Sender)
        {
            // Ищем удаляемый элемент
            List <ReadRequest> requests = this.requestsByMemory[MemoryType] as List <ReadRequest>;

            if (requests == null)
            {
                List <RequestItem> read_items = this.readItems;
                if (read_items == null)
                {
                    return;
                }
                //Удаление элемента из списка, если размер считывания не известен
                RequestItem removed_item = read_items.Find(new Predicate <RequestItem>(x => x.Address == Address && x.Sender.Equals(Sender)));
                // Элемент не найден
                if (removed_item == null)
                {
                    return;
                }
                read_items.Remove(removed_item);
                return;
            }
            int idx = requests.BinarySearch(new ReadRequest(Address, MemoryType, 0, 0, 0));

            if (idx < 0)
            {
                idx = ~idx - 1;
            }
            if (idx < 0)
            {
                return;
            }
            RequestItem RemovedItem = requests[idx].Items.Find(new Predicate <RequestItem>(x => x.Address == Address && x.Sender.Equals(Sender)));

            if (RemovedItem == null)
            {
                // Элемент не найден
                return;
            }
            // Получаем все запросы, в которых используется элемент
            List <ReadRequest> RequestsWithRemovedItem = requests.FindAll(new Predicate <ReadRequest>(x => (x.EndByteOffset >= RemovedItem.Address && x.EndByteOffset <= RemovedItem.EndByteOffset) ||
                                                                                                      (x.Address >= RemovedItem.Address && x.EndByteOffset >= RemovedItem.EndByteOffset) ||
                                                                                                      (x.Address <= RemovedItem.Address && x.EndByteOffset >= RemovedItem.EndByteOffset)));

            this.lockingAddress    = RequestsWithRemovedItem[0].Address;
            this.lockingMemoryType = MemoryType;
            this.lockingLength     = RequestsWithRemovedItem[RequestsWithRemovedItem.Count - 1].EndByteOffset + 1 - this.lockingAddress;
            this.lockingActive     = true;
            // Удаляем эти запросы из списка запросов
            foreach (ReadRequest request in RequestsWithRemovedItem)
            {
                requests.Remove(request);
            }
            // Получаем список оставшихся элементов
            List <RequestItem> items = new List <RequestItem>();

            foreach (ReadRequest request in RequestsWithRemovedItem)
            {
                foreach (RequestItem item in request.Items)
                {
                    if (item != RemovedItem && !items.Contains(item))
                    {
                        items.Add(item);
                    }
                }
            }
            // Добавляем оставшиеся элементы обратно в список запросов
            foreach (RequestItem item in items)
            {
                this.AddReadItem(item);
            }
            this.lockingActive = false;
        }