|
Исходники UART with PDC для Atmel ARM, Состряпал от нифиг делать :) |
|
|
|
Aug 10 2005, 13:56
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Кому нужны готовые, либо как примеры работы с UART через PDC (т.е. ПДП) смело в юз. Помучился с ними пару дней. Работает уже пару недель. Без ошибок. Приемник работает посимвольно, и приемник и передатчик работают через прерывания, у каждого свой кольцевой буфер. Функции передачи не ждут, если данные помещаются в кольцевой буфер. Если надо ждать конца передачи - есть фунция. Поддерживается работа в многопоточной среде. Можно легко интегрировать в операционную систему (если переписать функции работы с сигналами). Кристалл у меня AT91SAM7S64 и AT91RM9200, но, думаю, любой Atmel подойдет. В общем, кому интересно, смело смотрим. Public domain. О как! Тока запостил, сразу ошибку нашел! Исправил. Как расценить сей шаг всевышнего даже не знаю, но что не случается, все к лучшему
|
|
|
|
|
Aug 10 2005, 17:44
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(xoms @ Aug 10 2005, 20:24) Ну уже можно скачивать или подождать. Да, вполне можно. Ошибка была в ветке алгоритма, которую недавно дописал и не тестировал. Проявилась бы при передаче функции PutStr строки длинее, чем внутренний буфер, когда он пуст. Конечно же возможны и другие ошибки. Но перекачал уже мегов 100 по X modem да и в консоли постоянно работаю - все ОК.
|
|
|
|
|
Aug 11 2005, 14:56
|
Участник

Группа: Новичок
Сообщений: 18
Регистрация: 23-06-05
Пользователь №: 6 264

|
Для Linux драйвер с использованием PDC (AT91RM9200) лежит на www.ipbx.ru/rm9200
|
|
|
|
|
Dec 20 2007, 07:24
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Глянул на исходники PDC от Linux (древние, правда). Там функция вывода, перед тем как поместить новые данные в буфер и настроить указатели, выключает(!) передатчик. Т.е. если в этот момент произойдет более высокоуровневое прерывание - передатчик будет выключен и данные передаваться не будут. Если же запрещаются все прерывания, значит в течение всего времени копирования выходных данных в буфер нет возможности прерваться на более привелигированную операцию (не помню, запрещаются ли прерывания, но у обоих вариантов есть минусы). К тому же какова цена выключения и включения передатчика? Это просто кажущаяся простота смены значения одного бита, за которой, на самом деле идет много всяких переключений, а это лишняя трата энергии, что иногда немаловажно.
В моем драйвере применяется более сложный алгоритм, который позволяет передатчику продолжать работать в момент копирования буфера, прерывания при этом разрешены. Единственное, что на момент копирования маскируется прерывание самого передатчика.
|
|
|
|
|
Dec 20 2007, 18:23
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(aaarrr @ Dec 20 2007, 17:57)   А какова цена побайтного копирования данных из приемника в прерывании? Я уж не говорю о том, что это потенциальная причина потери данных при даже не очень длительном (174uS @ 115200) запрещении прерываний. ??? Не понял. В каком месте там теряются данные? В приемнике? Да, приемник работает не через PDC. Но я не вижу там проблем. Не помню детально работу с UART у SAM. Но по идее потеря произойдет только если не уcпеть считать предыдущей принятый байт. Байты приходят через каждые 2864 такта. Прерывания от UART маскируются для копирования порции данных в выходрой буфер. Если в этот момент поступит байт, обработан он не будет. Сразу же. А только после того, как memcpy скопирует данные, прерывание демаскируются и тут же срабатывает. Размер буфера передатчика всего 128 байт, так что байт не потеряется. Хотя, конечно надо бы и приемник сделать через PDC. И у вас есть пример. З.Ы. А то что UART вообще выключается, пока копируется буфер, это как повлияет на возможность потери? Что за 174uS?
|
|
|
|
|
Dec 20 2007, 18:35
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Andrey Sudnov @ Dec 20 2007, 21:23)  Хотя, конечно надо бы и приемник сделать через PDC. И у вас есть пример. Надо. У меня и приемник есть, зачем мне пример  Цитата(Andrey Sudnov @ Dec 20 2007, 21:23)  З.Ы. А то что UART вообще выключается, пока копируется буфер, это как повлияет на возможность потери? Никак, если все уже передано. Цитата(Andrey Sudnov @ Dec 20 2007, 21:23)  Что за 174uS? Это время передачи двух байт на скорости 115200. Очень маленькое время, особенно если процессор занят другими задачами.
|
|
|
|
|
Dec 20 2007, 18:49
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(aaarrr @ Dec 20 2007, 23:35)  Никак, если все уже передано. Т.е. прием и передача идут сразу из пользовательских буферов. Которые, например, локальные. Ню-ню. Цитата Это время передачи двух байт на скорости 115200. Очень маленькое время, особенно если процессор занят другими задачами. К чему это? Продолжительнорсть маскировки прерывания не превышает копирования 128 байт функцией memcpy. Это сколько, не помню, 128 тактов (1 копирование за 4-е такта)? Для того чтобы принятый байт потерялся, необходимо чтобы MC был занят более привелигированной задачей (ну там время считал) указаное вами время поделить на 2, т.е. 2871 такт (я указал 2864  Это значит ваще каюк пришел реал-тайму.
|
|
|
|
|
Dec 20 2007, 18:57
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Andrey Sudnov @ Dec 20 2007, 21:49)  Т.е. прием и передача идут сразу из пользовательских буферов. Которые, например, локальные. Ню-ню. Я не говорю, что запрещать правильно и хорошо. Просто это не приведет к катастрофическим последствиям. Цитата(Andrey Sudnov @ Dec 20 2007, 21:49)  Для того чтобы принятый байт потерялся, необходимо чтобы MC был занят более привелигированной задачей (ну там время считал) указаное вами время поделить на 2, т.е. 2871 такт (я указал 2864  Это значит ваще каюк пришел реал-тайму. Во-первых, ничего делить не надо - для переполнения нужно два символа. А во-вторых, почему бы процессору не отвлечься на такое время? Реал-тайм реал-тайму рознь
|
|
|
|
|
Dec 20 2007, 19:16
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(aaarrr @ Dec 20 2007, 23:57)  Я не говорю, что запрещать правильно и хорошо. Просто это не приведет к катастрофическим последствиям. Ну вот выключили мы UART. И отвлеклись. Причем не на 2 байта, а всего на один стартовый бит. Потом включили. Нееет, все нормально, никаких катострофических последствий. Цитата Во-первых, ничего делить не надо - для переполнения нужно два символа. А во-вторых, почему бы процессору не отвлечься на такое время? Реал-тайм реал-тайму рознь  Принимаю, вроде так. Ну дак значит времени на оброботку есть еще больше. Я утверждаю, что даже с посимвольным вводом, ситуация, когда потеряется символ - невозможна. Точнее это произойдет только в том случае, если прерывания будут запрещены в течение 5742 такта, а это невозможно. Если же это возможно, значит возможны и другие катастрофы. Вспомнил насчет копироавния и внутренних буферов. Они нужны для того чтобы вызвать PutStr и сразу же вернуться из нее. При этом буфер, который указывали PutStr можно использовать по новому. Единственное но. Длина не должна превышать свободный размер внутреннего буфера, иначе PutStr будет ждать его освобождения. Размер буфера 128 байт. Для некоторых применеий может быть мало. Но тут нет идеально варианта, в любом случае в чем-то выигрываем, в чем то проигрываем. В случае если PDC будет работать прям из переданного буфера, функция PutStr вынуждена ждать завершение передачи, иначе данные могут быть испорчены программой, после возврата из нее. Как вариант - все время передавать из разных мест. Да, в некоторых случаех надо делать так, но это гораздо сложнее, чем вызвать PutStr и забыть.
|
|
|
|
|
Dec 20 2007, 19:28
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Andrey Sudnov @ Dec 20 2007, 22:16)  Ну вот выключили мы UART. И отвлеклись. Причем не на 2 байта, а всего на один стартовый бит. Потом включили. Нееет, все нормально, никаких катострофических последствий. Ваши слова: Цитата(Andrey Sudnov @ Dec 20 2007, 10:24)  выключает(!) передатчик и причем здесь прием? Цитата(Andrey Sudnov @ Dec 20 2007, 22:16)  Я утверждаю, что даже с посимвольным вводом, ситуация, когда потеряется символ - невозможна. Точнее это произойдет только в том случае, если прерывания будут запрещены в течение 5742 такта, а это невозможно. Если же это возможно, значит возможны и другие катастрофы. Если в системе крутится один драйвер UART, то невозможно. Но обычно крутится еще много чего другого безо всяких катастроф.
|
|
|
|
|
Dec 20 2007, 20:31
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(aaarrr @ Dec 21 2007, 00:28)  и причем здесь прием? Не помню что там выключается. Я рассматривал исходя из передачи, поэтому так написал. Имел ввиду весь UART. Ведь если при передаче выключается передатчик, то при преме должен выключаться приемник. Ведь так? К тому же передача из произвольных буферов я еще представляю, а прием в произвольные - это как? Вызвали GetData, передав указатель, вернулись, что-то делаем, потом каким-то образом узнаем что данные получены. Ну, буфер заполнен. Новые данные принимать некуда. Надо подставлять новый. А в этот момент бабац, и пресловутое запрещение прерываний. А мы ведь в пользовательском коде, ваще самые некотируемые. Нее. Так не правильно. Цитата Если в системе крутится один драйвер UART, то невозможно. Но обычно крутится еще много чего другого безо всяких катастроф. Обработчик прерываний не должен выполнять никакой длительной работы работы внутри себя. Это даже по Windows (далеко не реал-тайм) - закон! Если же в программе допускаются такие задержки, то ни при каком способе работы с UART нельзя гарантировать, что не произойдет потери принятого байта. Ведь задержка может произойти между переключениями буферов в пользовательском коде (а такое переключение более длительное, чем метод, используемый у меня). Цитата(Dron_Gus @ Dec 21 2007, 00:51)  Если Вы не против, подкину еще одну тему для обсуждения. Есть такое замечательное устройство GSM-модем SIM508. Так вот он при приеме пакета данных сообщает об этом следующим образом "+IPD<размер>:". Есть идея обработки обычных сообщений через обычные прерывания. Т.е. посимвольно. Ибо неизвестно, когда же закончится входящее сообщение. А парсить его на предмет <CR><LF> расточительно. Зато принимать пакеты заранее известной длинны оч. удобно через PDC. Есть вопрос: теоретически возможна ли потеря символов при переключении режимов работы. Что-то я в документации ничего толкового не нашел по этому вопросу... Переключаться между режимами может быть и можно, но не правильно. Думаю, в данном случае надо всегда работать через PDC. После "+IPD<размер>:" есть таймаут или сразу данные идут? В любом случае, настраиваем таймаут (ну там, возможны другие команды, URC), указываем буфер, ждем когда он заполнится (полностью или нет, не важно). По любому парсим начиная с начала. Если нашли "+IPD<размер>:", остальную часть буфера рассматриваем как данные. Три варианта: 1) после данных есть еще строковые ответы, 2) данные кончаются в конце буфера, 3) не все данные влезли в буфер. Во третьем случае указываем еще буфер, но после заполнения помним, что там данные вначале. А потом могут быть строки. Алгоритм не тривиален. Если его делать влоб - не получиться. Но могу псевдокодом расписать, как делать. Кстати, что насчет URC? У некоторых телефонов возможны такие фишки: AT+CMGL=0 (запрос списка новых входящих SMS) +CMGL: 1,0,,24 (ответ: индекс, статус,,длина) 0791xxxxxxxxxxF1040B919720380422F6 (это PDU - закодированная SMS) +CMTI: "ME",39 (хопа, пришло URC - уведомление - о новом сообщении) 00006001701041130005C8329BFD06 (продолжение PDU) Как такое обрабатывать?
|
|
|
|
|
Dec 20 2007, 22:03
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Dron_Gus @ Dec 20 2007, 22:51)  Если Вы не против, подкину еще одну тему для обсуждения. Есть такое замечательное устройство GSM-модем SIM508. Так вот он при приеме пакета данных сообщает об этом следующим образом "+IPD<размер>:". Есть идея обработки обычных сообщений через обычные прерывания. Т.е. посимвольно. Ибо неизвестно, когда же закончится входящее сообщение. А парсить его на предмет <CR><LF> расточительно. Зато принимать пакеты заранее известной длинны оч. удобно через PDC. Есть вопрос: теоретически возможна ли потеря символов при переключении режимов работы. Что-то я в документации ничего толкового не нашел по этому вопросу... В свое время я извращался подобным образом на AT91x40xxx. У них PDC был без двойной буферизации, так что приходилось останавливать прием до окончания буфера и быстренько подключать следующий. ИМХО, можно, но лучше так не делать. Парсить <CR><LF> будет значительно проще. Цитата(Andrey Sudnov @ Dec 20 2007, 23:31)  Ведь если при передаче выключается передатчик, то при преме должен выключаться приемник. Ведь так? Почему это? Цитата(Andrey Sudnov @ Dec 20 2007, 23:31)  К тому же передача из произвольных буферов я еще представляю, а прием в произвольные - это как? Что Вы понимаете под термином "произвольный буфер"? Цитата(Andrey Sudnov @ Dec 20 2007, 23:31)  Обработчик прерываний не должен выполнять никакой длительной работы работы внутри себя. Это даже по Windows (далеко не реал-тайм) - закон! Если же в программе допускаются такие задержки, то ни при каком способе работы с UART нельзя гарантировать, что не произойдет потери принятого байта. Ведь задержка может произойти между переключениями буферов в пользовательском коде (а такое переключение более длительное, чем метод, используемый у меня). Да кто же спорит? Просто в одном случае допустима задержка в 2 символа, а во втором - в 1 буфер PDC, размер которого можно регулировать. А ОС, пользовательский код и прочее к делу не относится.
|
|
|
|
|
Dec 20 2007, 22:53
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(aaarrr @ Dec 21 2007, 03:03)  ИМХО, можно, но лучше так не делать. Парсить <CR><LF> будет значительно проще. Т.е. делать по моему? Я вспомнил! Сделал побайтно из-за того, что так проще принимать строки. Цитата Почему это? Что Вы понимаете под термином "произвольный буфер"? Совсем забыл как работает этот PDU. Сейчас глянул. Без отключения приемника не обойтись, так как установить адрес на следующий буфер и счетчик надо одновременно! Это если адрес буфера будет все время разный, "произвольный", для обработчика прерываний, неизвестный ему заранее. Если использовать один и тот же буфер или пару, то без выключения приемника обойтись можно. Плюс с PDC появляется проблема с приемом строк произвольной длины. Как ее организовать? Ловить прерывание по таймауту, копировать (!) буфер от значения до текущего адреса? Или PDC переходит на следующий буфер по таймауту? Опишите пожалуйста парой слов Ваш алгоритм, так сказать путь данных от UART до пользовательского буфера. Куда указывает адрес и следующий адрес в PDC (в течение всего цикла)?
|
|
|
|
|
Dec 20 2007, 22:55
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861

|
2 Andrey Sudnov. Да уж алгоритм не тривиален. Пауз никаких нет. Иногда модем пакеты выплевывает за раз, иногда бьет на куски и каждый обрамляет <CR><LF>..<CR><LF>. Это еще больше затрудняет разгребание "влоб". Сейчас использую Ваш фифо с некоторыми добавлениями, типа подсчета принятых строк и т.д. Никак не могу понять - на больших обьемах где-то выпадает символ. Overrun я победил, остались свои косяки. 2 aaarrr, убедили.  Завтра волю в кулак и буду переписывать. Тут только что осознал, что можно запоминать позицию до котрой в прошлый раз парсил и в след раз начинать с нее. Осталось посчитать, как часто надо проверять буфер на наличие новых строк. З.Ы. ненавижу "равноправные" интерфейсы. Другое дело SPI, пока не спросили слэйв молчит.
--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
|
|
|
|
|
Dec 21 2007, 00:36
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Andrey Sudnov @ Dec 21 2007, 01:53)  Т.е. делать по моему? Я вспомнил! Сделал побайтно из-за того, что так проще принимать строки. Нет, делать побайтно я не советовал. Цитата(Andrey Sudnov @ Dec 21 2007, 01:53)  Совсем забыл как работает этот PDU. Сейчас глянул. Без отключения приемника не обойтись, так как установить адрес на следующий буфер и счетчик надо одновременно! Это если адрес буфера будет все время разный, "произвольный", для обработчика прерываний, неизвестный ему заранее. Если использовать один и тот же буфер или пару, то без выключения приемника обойтись можно. Объясните мне, какой смысл писать адрес и счетчик в разное время? Понял Ваше определение "произвольного" буфера. ИМХО, те буферы, с которыми работает PDC должны быть однозначно фиксированными - задача PDC и буферизации состоит прежде всего в разгрузке процессора и обеспечении надежного приема, а дальнейшая судьба данных - дело пользовательского приложения, и обработчик прерывания заботиться о ней не должен. Цитата(Andrey Sudnov @ Dec 21 2007, 01:53)  Плюс с PDC появляется проблема с приемом строк произвольной длины. Как ее организовать? Ловить прерывание по таймауту, копировать (!) буфер от значения до текущего адреса? Или PDC переходит на следующий буфер по таймауту? Опишите пожалуйста парой слов Ваш алгоритм, так сказать путь данных от UART до пользовательского буфера. Куда указывает адрес и следующий адрес в PDC (в течение всего цикла)? Попробую, парой слов не обойдется, правда.  Итак: 1. Заводим два одинаковых буфера. 2. Прописываем в PDC_RPR и PDC_RCR адрес и длину первого буфера, в PDC_RNPR и PDC_RNCR - второго. 3. При поступлении прерывания ENDRX копируем данные из буфера PDC в пользовательский (у меня это обычно FIFO, если принимается поток, или набор фиксированных буферов, если обмен идет в пакетном режиме). Адрес и длину освободившегося буфера записываем в PDC_RNPR и PDC_RNCR. Наличие места в FIFO или свободного буфера на этом этапе - целиком проблема пользовательского приложения. 4. По TIMEOUT все несколько сложнее: 4.1 Запрещаем - увы - прерывания 4.2 Выключаем PDC 4.3 Запоминаем PDC_RCR 4.4 Если PDC_RNCR != 0, то ставим PDC_RPR = PDC_RNPR, PDC_RCR = PDC_RNCR, PDC_RNCR = 0, в противном случае игнорируем п.4.6 4.5 Включаем PDC и прерывания 4.6 Копируем данные и прописываем PDC_RNPR и PDC_RNCR аналогично п.3 Время запрета PDC и прерываний получается очень малым.
|
|
|
|
|
Dec 21 2007, 05:06
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(aaarrr @ Dec 21 2007, 05:36)  Итак: 1. Заводим два одинаковых буфера. 2. Прописываем в PDC_RPR и PDC_RCR адрес и длину первого буфера, в PDC_RNPR и PDC_RNCR - второго. 3. При поступлении прерывания ENDRX копируем данные из буфера PDC в пользовательский (у меня это обычно FIFO, если принимается поток, или набор фиксированных буферов, если обмен идет в пакетном режиме). Адрес и длину освободившегося буфера записываем в PDC_RNPR и PDC_RNCR. Наличие места в FIFO или свободного буфера на этом этапе - целиком проблема пользовательского приложения. 4. По TIMEOUT все несколько сложнее: 4.1 Запрещаем - увы - прерывания 4.2 Выключаем PDC 4.3 Запоминаем PDC_RCR 4.4 Если PDC_RNCR != 0, то ставим PDC_RPR = PDC_RNPR, PDC_RCR = PDC_RNCR, PDC_RNCR = 0, в противном случае игнорируем п.4.6 4.5 Включаем PDC и прерывания 4.6 Копируем данные и прописываем PDC_RNPR и PDC_RNCR аналогично п.3 Время запрета PDC и прерываний получается очень малым. В пункте 3 копируем внутри обработчика прерываний? Мне кажетсе, при приеме необходимости выключать PDC нет (точно PDC? А не UART? А если была задержка перед обработкой прерывания по TIMEOUT и в тот момент, когда выключили PDC как раз поступил новый байт, ну а раз PDC выключен - запомнили и выдали новый запрос на прерывание, но уже без PDC?). Почему необходимо начинать прием в следующий буфер вместо хвоста текущего? Вот это выключение в пункте 4.2, которое мне совсем не нравится, при передаче необходимо, так как устанавливать адрес и счетчик надо вместе, а вызов PutStr может произойти в любой момент. При приеме момент смены указателя и значения только один - в прерывании ENDRX, когда вероятность того, что произойдет переключение буферов в PDC очень мала (не успеет просто так много данных поступить). Цитата(Dron_Gus @ Dec 21 2007, 03:55)  2 Andrey Sudnov. Да уж алгоритм не тривиален. Пауз никаких нет. Иногда модем пакеты выплевывает за раз, иногда бьет на куски и каждый обрамляет <CR><LF>..<CR><LF>. Это еще больше затрудняет разгребание "влоб". Сейчас использую Ваш фифо с некоторыми добавлениями, типа подсчета принятых строк и т.д. Никак не могу понять - на больших обьемах где-то выпадает символ. Overrun я победил, остались свои косяки. Символ пропадает в передатчике или приемнике? Вы так спокойно об этом говорите! Ни в коем случае ничего не должно пропадать! Если есть ошибка у меня, а это возможно, о ней надо сообщить, чтобы исправиить ну или отказаться от моего исходника - не исключаю и такой вариант.
|
|
|
|
|
Dec 21 2007, 08:43
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(vet @ Dec 21 2007, 11:58)  а что за беда от выключения PDC? ну выключили, переставили буферы, снова включили - перенос данных продолжился с того же места. у меня PDC обычно включен в обе стороны, активны прерывания AT91C_US_RXBUFF | AT91C_US_TXBUFE | AT91C_US_TIMEOUT. Копирования массивов нет, кольцевые буферы заполняются/разгребаются непосредственно функциями putchar/getchar, которые, впрочем, тоже приостанавливают PDC на десяток-другой машинных команд, проблем от этого не испытывал. Допустим PDC выключен. В этот момент приходит новый символ. Устанавливается RXRDY, но так как он замаскирован - прерывания не происходит. Закончили работу с буферами, включили PDC. Скорее всего Вы правы - символ, который уже принят, уйдет в буфер. Это было бы логично. Надо конечно проверить для верности. Я признаю, что мой драйвер чрезмерно усложнен из-за того что не выключает PDC. В этом нет смысла, поэтому лучше его использовать только в качестве обучающего (ну там все-таки есть некоторые трюки).
|
|
|
|
|
Dec 7 2015, 04:57
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Взрыв из прошлого  Кому интересен subj, у мну есть что добавить. Первое. Это актуально на новом железе Atmel(поменялся ли интерфейс UART и PDC)? Второе. Появились ли какие новые реализации работы через PDC хорошие?(та, что была в linux kernel времен 2.6 - мне не нравится) Третье. Теоретически возможно написать поблочный, а не посимвольный алгоритм для приемника, который будет работать в паре с предложенным алгоритмом передатчика БЕЗ ОТКЛЮЧЕНИЯ КОНТРОЛЛЕРОВ UART/PDC(читайте первый и седьмой пост, а также последние несколько). Этот алгоритм сложнее, чем алгоритм для передатчика(а он сам не прост, по сравнению с linux версией). И он возможен, так как настройку PDC МОЖНО начинать с установки второй пары указатель-счетчик(которая Next)! Аппаратно значения переносятся сразу в первую пару(текущую) и сразу же начинается прием в этот буфер. Т.е. возможна такая настройка буферов: 1) проверяем свободен ли Next 2) Настраиваем Next 3) переходим к 1. Какбэ не очевидный момент, но выявленный экспериментально на AT91SAM7S64. В SDK от Atmel же происходит сначала проверка и заполнение первой пары, и только если она не свободна - заполнение пары Next. ЭТО ДЕЛАЕТ НЕВОЗМОЖНЫМ АТОМАРНУЮ УСТАНОВКУ ОБОИХ ПАР И ПРИХОДИТСЯ ОТКЛЮЧАТЬ КОНТРОЛЛЕР. Да, перенос происходит в момент установки регистра счетчика. Публиковать пока не буду, но кому интересно, готовый исходник пришлю, так как надо тестить.
|
|
|
|
|
Dec 7 2015, 17:28
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Согласен насчет того, что можно принимать через один буфер. Сложности с атомарностью и прерываниями начинаются при работе с двумя буферами. Зачем нужны два буфера? Они позволяют на HIGHLOAD обрабатывать входящие данные прямо в тех же буферах, которые заполнялись PDC, БЕЗ КОПИРОВАНИЯ! Насколько все это нужно, каждый решает в меру своей испорченности  Можно сделать как-то эдак хитроватисто, но надо проверять. А зн велком.
|
|
|
|
|
Dec 8 2015, 14:34
|
Частый гость
 
Группа: Свой
Сообщений: 82
Регистрация: 15-03-05
Пользователь №: 3 361

|
Цитата(MrAlex @ Dec 8 2015, 13:31)  "Правда в том, что никакой ложки нет." Ложки нет, ложкодержатели есть  Выкладывай что ли свой вариант, а то не очень понятно, что значит "теребить". Ну или в subj укажи, что можно упростить по твоему. Только когда он делался, я еще не знал про next. В версию алгоритма с приемником около 100 строк добавляется
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|