acvarif 0 1 октября, 2012 Опубликовано 1 октября, 2012 · Жалоба Дамп - в ниосе window->show view->memory, выбираете адрес начала дескрипторов Спасибо. С дампом понял. Поскольку возникает ошибка размещения дескрипторов придется возвратиться назад. Кажется я не до конца понял про формирование дескрипторов. У меня в функции размещения (взято из примера alteraviki) имеется // количество буферов #define NUMBER_OF_BUFFERS 4 // длина одного буфера #define BUFFER_LENGTH 1152 // Каждый дескриптор имеет размер в 32 бита #define ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE (0x20) void * temp_ptr_2; // выделение памяти под дескрипторы = 6 * 32 = 192 бита temp_ptr_2 = malloc((number_of_buffers + 2) * ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE); // инициализация указателя *receive_descriptors_copy - указывает на адрес начала памяти выделенной под дескрипторы *receive_descriptors_copy = (alt_sgdma_descriptor *)temp_ptr_2; // инициализация указателя *receive_descriptors - ??? while((((alt_u32)temp_ptr_2) % ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE) != 0) { temp_ptr_2++; // slide the pointer until 32 byte boundary is found } *receive_descriptors = (alt_sgdma_descriptor *)temp_ptr_2; // очистка бита OWNED_BY_HW receive_descriptors[number_of_buffers]->control = 0; Подскажите пожалуйста почему память под дескрипторы выделяется на 2 больше чем количество буферов. Не пойму в какое место будет указывать указатель *receive_descriptors? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 1 октября, 2012 Опубликовано 1 октября, 2012 · Жалоба Написано же : slide the pointer until 32 byte boundary is found. Тут выравнивается начало дескриптора по 32-БАЙТНОЙ границе. Видимо SGDMA так надо, об этом в доке написано что так надо выравнивать. Насчет выделяется больше чем надо - не задумывался, наверно как раз запас на выравнивание по границе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 2 октября, 2012 Опубликовано 2 октября, 2012 · Жалоба Тут выравнивается начало дескриптора по 32-БАЙТНОЙ границе. Видимо SGDMA так надо, об этом в доке написано что так надо выравнивать. Насчет выделяется больше чем надо - не задумывался, наверно как раз запас на выравнивание по границе...Понял. Спасибо. В отладчике после размещения дампы памяти дескрипторов Как-то странно что 2_ые дескрипторы имеют один и тот же адрес. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 3 октября, 2012 Опубликовано 3 октября, 2012 · Жалоба Все работает. С одним буфером. С двумя буферами не работает. После заполнения одного буфера Запускается так: if (!(IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_0_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK)) IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_0_BASE, ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK); alt_avalon_sgdma_do_async_transfer(receive_DMA, &receive_descriptors1[0]); После заполнения первого буфера возникает прерывание в котором делается так: while (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_0_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK); // Enable SGDMA "parking" mode if (!(IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_0_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK)) IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_0_BASE, ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK); alt_avalon_sgdma_do_async_transfer(receive_DMA, &receive_descriptors2[0]); ..... выдача данных из receive_descriptors1 по Ethernet Тоесть в прерывании запускается прием данных по receive_descriptors2 и начинается выдача накопленных данных по receive_descriptors1 Вроде все должно работать как задумано. Но реально после входа в прерывание и вызова функции alt_avalon_sgdma_do_async_transfer(receive_DMA, &receive_descriptors1[0]); буфер не переключается. Посоветуйте пожалуйста куда копать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 3 октября, 2012 Опубликовано 3 октября, 2012 · Жалоба Честно говоря, не помню из-за чего, 2 года назад было, но сделал у себя так: unsigned char adc_dma_restart(alt_video_display *display) { // while (IORD_ALTERA_AVALON_SGDMA_STATUS(display->sgdma->base) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK); /* Enable SGDMA "parking" mode */ if (!(IORD_ALTERA_AVALON_SGDMA_STATUS(display->sgdma->base) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK)) IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_0_BASE, ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK); /* Now start the SGDMA */ return( alt_avalon_sgdma_do_async_transfer( display->sgdma, display->buffer_ptrs[display->buffer_being_displayed]->desc_base)); } Т.е. while закомментил, заменил на условие. Помню, вроде бывало он циклился на while Перезапускаю в прерывании так: adc_dma->buffer_being_displayed=dmaindex&0x3;//след. буфер и старт транзакции dmaindex++; adc_dma_restart(adc_dma); Вроде все просто без изысков. Работает стабильно, не виснет долго-долго (дольше суток не проверял). 4 буфера, как видно. А на какой конкретно строчке циклится? Не на while ли? В пошаговом режиме проверте. Уберите для этого оптимизацию кода (в свойствах проекта Nios II Application properties, Optimization level), тогда дебажить будет строго по порядку строчек. Попробуйте еще вывести в сигнал тап сигналы DMA и проследите, залетает ли в DMA последний байт пакета, меняется ли после последнего байта сигнал ready(софт при этом в пошаговом режиме). Ну а дальше по обстоятельствам... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 4 октября, 2012 Опубликовано 4 октября, 2012 (изменено) · Жалоба Спасибо. Примерно так и сделал. Вроде работает. Но с дескрипторами (создаю 2 разных дескриптора с одинаковым количеством буферов) всеравно в каких-то ситуациях выскакивает непонятка. Подумал может оперировать разными дескрипторами (указателями на разные дескрипторы) некорректно. Тоесть типа alt_sgdma_descriptor *receive_descriptors1, *receive_descriptors_copy1; alt_sgdma_descriptor *receive_descriptors2, *receive_descriptors_copy2; Можно-ли создать один указатель на дескрипторы (типа alt_sgdma_descriptor *receive_descriptors, *receive_descriptors_copy) (например 2000 буферов(точнее 2000 дескрипторов) по 1152 байта каждый) и разделить это все (условно) на 2 буфера. Потом переключать в прерывании буфера? У меня сомнения по поводу 2000. В регистре control имеются биты MAX_DESC_PROCESSED которые определяют количество заполненных буферов после которых будет сгенерировано прерывание. При инициализации у меня MAX_DESC_PROCESSED = 0х00. Имеею-ли биты MAX_DESC_PROCESSED отношение к моим предполагаемым 2000 буферов? Хотя наверное это все не прокатит. Как в таком случае сформируется прерывание по заполнению цепочки? Только в конце цепочки. А в этом уже нет смысла. Изменено 4 октября, 2012 пользователем Acvarif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 4 октября, 2012 Опубликовано 4 октября, 2012 · Жалоба Max_desc_proccessed - это если вам надо прерывание не в конце цепочки, а после какого-то дескриптора, для этого IE_MAX_desc_processed должен быть установлен, иначе фиолетово что там лежит. Не, схема которую вы предлагаете мутная какая-то. Разберитесь с проблемой раз и навсегда и все. "Запомни лучше день потерять, потом за 5 минут долететь" (С). Для начала определите софт не стартует транзакцию или хард не поставляет данные. Это сигналтапом. И потом, не обратил внимания, щас еще раз перечитал. Не должно быть двух указателей дескрипторов, указывающих на одно место. Т.е. быть то может но ненормально это. Должна отдельная память выделяться. Посмотрите, после транзакции обновляется слово Actual bytes trasferred? Правильное там значение лежит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 5 октября, 2012 Опубликовано 5 октября, 2012 · Жалоба Max_desc_proccessed - это если вам надо прерывание не в конце цепочки, а после какого-то дескриптора, для этого IE_MAX_desc_processed должен быть установлен, иначе фиолетово что там лежит. Не, схема которую вы предлагаете мутная какая-то. Разберитесь с проблемой раз и навсегда и все. "Запомни лучше день потерять, потом за 5 минут долететь" (С). Для начала определите софт не стартует транзакцию или хард не поставляет данные. Это сигналтапом. И потом, не обратил внимания, щас еще раз перечитал. Не должно быть двух указателей дескрипторов, указывающих на одно место. Т.е. быть то может но ненормально это. Должна отдельная память выделяться. Посмотрите, после транзакции обновляется слово Actual bytes trasferred? Правильное там значение лежит? Спасибо. Понятно. Начал все с того же - с дескрипторов. После первой транзакции (2 прерывания по заполнению 2_х цепочек дескрипторов (по 8 в каждой цепочке)) (1152 байта каждый дескриптор) Напрягает receive_descriptors_copy1 Не допираю откуда там цифра bytes_to_transfer 10112 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 5 октября, 2012 Опубликовано 5 октября, 2012 · Жалоба Спасибо. Понятно. Начал все с того же - с дескрипторов. После первой транзакции (2 прерывания по заполнению 2_х цепочек дескрипторов (по 8 в каждой цепочке)) (1152 байта каждый дескриптор) Напрягает receive_descriptors_copy1 Не допираю откуда там цифра bytes_to_transfer 10112 Похоже не заполнен он у вас (не сформирован корректно) - write adr = 0x0. Не должно быть. По шагам формирование проверьте. Если дескриптор этот запускается, то точно зависнет, в 0 писать не правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 9 октября, 2012 Опубликовано 9 октября, 2012 (изменено) · Жалоба Похоже не заполнен он у вас (не сформирован корректно) - write adr = 0x0. Не должно быть. По шагам формирование проверьте. Если дескриптор этот запускается, то точно зависнет, в 0 писать не правильно. С дескрипторами так толком и не понял почему у одной из пар одинаковые адреса и после одного прохода write adr = 0x0. Но, вобщем и целом механизм вроде работает. Спасибо. Немного не понятно по поводу бита PARK в регистре управления. If the PARK bit is set to 1, the core does not clear the OWNED_BY_HW bit, thus allowing the same descriptor to be processed repeatedly without software intervention. You also need to set the last descriptor in the list to point to the first one. Почему в прерываниях приходится каждый раз подтверждать 1? Иначе все зависает. По поводу You also need to set the last descriptor in the list to point to the first one. Насколько это обязательно? У меня дескрипторы формируются так: for(buffer_counter = 0; buffer_counter < number_of_buffers; buffer_counter++) { temp_length = buffer_length; receive_ptr = (alt_u32 *)malloc(temp_length); receive_ptr_copy = (alt_u8 *)receive_ptr; for(contents_counter = 0; contents_counter < temp_length; contents_counter++) { receive_ptr_copy[contents_counter] = 0; } alt_avalon_sgdma_construct_stream_to_mem_desc( &receive_descriptors[buffer_counter], // descriptor &receive_descriptors[buffer_counter+1], // next descriptor receive_ptr, // write buffer location (alt_u16)temp_length, // length of the buffer 0); // writes are not to a fixed location } Подскажите пожалуйста как в этом коде завернуть последний дескриптор на первое место? Изменено 9 октября, 2012 пользователем Acvarif Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 9 октября, 2012 Опубликовано 9 октября, 2012 · Жалоба С дескрипторами так толком и не понял почему у одной из пар одинаковые адреса и после одного прохода write adr = 0x0. Так делов то - если ситуация повторяется, вытащите в сигнал тап write adress и write data у SGDMA для дескрипторов (или у памяти адрес и данные) и триггер на адрес где лежит ваш write_adr, в который ноль пишется - сразу увидите, кто, зачем и после чего пишет туда ноль. Подскажите пожалуйста как в этом коде завернуть последний дескриптор на первое место? Эээ... А это то вам зачем? Вы же сами буферы меняете и новый дескриптор запускаете после выполнения транзакций. Это как я понял тот случай, когда дма используется, например, для дисплея - там да, чтоб не отвлекать процессор после отображения каждого кадра - завернуть конец на начало и не хай эти дескрипторы крутятся бесконечно, без вмешательства ПО. Один раз запустил - дисплей кажет, меняем только содержимое буферов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosu-art 0 19 ноября, 2012 Опубликовано 19 ноября, 2012 · Жалоба У меня тоже есть вопросики :rolleyes: Имею 2 буфера по 8к. весь поток ~64Mбайт(mem to streem). Можно ли зациклить дескрипторы друг на друга? что бы не приходилось лишний раз вызывать alt_avalon_sgdma_do_async_transfer? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 20 ноября, 2012 Опубликовано 20 ноября, 2012 · Жалоба У меня тоже есть вопросики :rolleyes: Имею 2 буфера по 8к. весь поток ~64Mбайт(mem to streem). Можно ли зациклить дескрипторы друг на друга? что бы не приходилось лишний раз вызывать alt_avalon_sgdma_do_async_transfer? А чего нет - то? Можно сделать указатель next последнего дескриптора на первый у второго буфера, а у последнего дескриптора первого буфера на первый второго. И вызывать только прерывания, для индикации смены буферов. А конкретно вопрос-то какой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosu-art 0 20 ноября, 2012 Опубликовано 20 ноября, 2012 · Жалоба Т.е. последовательность такая?: 1. Создаю дескрипторы зацикленные друг на друга. 2. Выставляю бит PARK 3. вызываю alt_avalon_sgdma_do_async_transfer и забываю, что у меня есть SGDMA :rolleyes: Поток контролируется логикой, прерывание выставляется если будут какие либо ошибки, либо переполнения. И почему один дескриптор может описать передачу максимум 0xFF00 байт? этот момент я не понял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 21 ноября, 2012 Опубликовано 21 ноября, 2012 · Жалоба Т.е. последовательность такая?: 1. Создаю дескрипторы зацикленные друг на друга. 2. Выставляю бит PARK 3. вызываю alt_avalon_sgdma_do_async_transfer и забываю, что у меня есть SGDMA :rolleyes: Поток контролируется логикой, прерывание выставляется если будут какие либо ошибки, либо переполнения. И почему один дескриптор может описать передачу максимум 0xFF00 байт? этот момент я не понял. Все вроде верно, не забудьте что бит OWEND_BY_HW во всех дескрипторах должен быть в 1. Повторюсь, что для индикации текущего буфера можно включить прерывания через нцать дескрипторов (видел где-то там такую возможность). Почему максимум 0xff00? Да ХЗ, не задумывался, может с большими разрядностями счетчиков (а там похоже 16) скорость просаживается, или еще какие проблемы. Вобщем, раз написано так- так и делал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться