|
|
  |
LPC177x UART, использовать FIFO для передачи |
|
|
|
Sep 28 2013, 05:05
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(Terminator @ Sep 28 2013, 08:52)  это всё конечно красиво, но попробуйте сделать вывод в отладочный порт из разных задач. Останавливать задачу ради вывода отладки нельзя, что влезло в буфер, то влезло. Заводить отдельную задачу для слежения за заполненостью буфера, очень не хочется. Запрещать прерывания перед каждым обращением в uart тоже (тут я конечно несколько лукавлю, т.к. при складывании в буфер прерывания всё равно запрещаются). так в чем проблема то? запрет прерывания надо делать только когда вы кладете данные в буфер, чтобы случайно не возникло прерывание и часть буфер не улетела в уарт, пока вы заполняете хвост. И чтобы по прерыванию вы в середине работы функции добавления данных не попали в другую функцию которая также может добавить данные. в остальном проблем нет. Я же писал функции работают идентично, просто вместо вашей проверки на запрет прерывания и его разрешение, у нас делает проверка на пустоту буфера и его запуск на передачу. Дальше у всех циклический буфер в который кладутся остатки сообщения.
|
|
|
|
|
Sep 30 2013, 02:59
|

Местный
  
Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382

|
Цитата(jcxz @ Sep 28 2013, 18:34)  Возможно товарищи по каким-то причинам (религиозным?) очень хотят писать в FIFO именно из ISR. Непреодолимое желание сиё понять трудно... Но, коли так уж хочется, после разрешения empty-tx IRQ можно программно возбудить прерывание при помощи NVIC. Чем плохо писать в FIFO из ISR? Это позволяет (не в случае с LPC конечно) в коде записать в буфер данные и разрешить прерывание. Всё остальное делается в прерывании. Пинать NVIC не пробовал. При случае попробую. Хотя это чревато лишними вызовами прерываний.
|
|
|
|
|
Sep 30 2013, 07:01
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
Цитата(jcxz @ Sep 28 2013, 15:34)  Возможно товарищи по каким-то причинам (религиозным?) очень хотят писать в FIFO именно из ISR. Непреодолимое желание сиё понять трудно... Но, коли так уж хочется, после разрешения empty-tx IRQ можно программно возбудить прерывание при помощи NVIC. про первичное наполнение FIFO из ISR это можно охарактеризовать как странность восприятия мира но "докладка" в процессе передачи - вполне обыденное действие. К примеру на RTOS: задача utx_task принимает от других задач task0, taskN то что нужно передать. тогда есть два варианта разруливания: #1 utx_task заполняет FIFO и размещает в глобальной переменной ptr и len чего еще не успело передать и ожидает события завершения ВСЕЙ передачи в прерывании после опустошения FIFO передачи проверяется len и если != 0 то в ISR досылаем в FIFO иначе выставляем признак события чтобы разбудить utx_task задачу для повторения всех циклов #2 utx_task заполняет FIFO и ожидает события завершения передачи FIFO в прерывании после опустошения FIFO выставляем признак события чтобы разбудить utx_task задачу для повторения заполнения FIFO и так по кругу вроде одинаковый результат, но сдается мне что во втором случае будет чаще дергатся шедуллер Цитата(Terminator @ Sep 28 2013, 08:52)  это всё конечно красиво, но попробуйте сделать вывод в отладочный порт из разных задач. Останавливать задачу ради вывода отладки нельзя, что влезло в буфер, то влезло. Заводить отдельную задачу для слежения за заполненостью буфера, очень не хочется. Запрещать прерывания перед каждым обращением в uart тоже (тут я конечно несколько лукавлю, т.к. при складывании в буфер прерывания всё равно запрещаются). тут только отдельная задача, которая: 1. для синхронной отправки ( блокирующая задача ) - выставляет семафор/событие для блокировки текущей задачи 2. для ассинхронной отправки ( неблокирующая задача ) отправка буфера из кучи - сохраняет в своей очереди ptr и len что передать, и по завершению FREE 3. для ассинхронной отправки ( неблокирующая задача ) отправка из стека - свой MALLOC и MEMCPY и предыдущий вариант 2 4. для ассинхронной отправки ( неблокирующая задача ) отправка из const и CODEMEM/FLASH - вариант 2 без FREE
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Sep 30 2013, 20:39
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
По поводу докладывания FIFO 16-тью элементами. Цитата из UM10360 (LPC17xx user manual) Цитата 4.14 UARTn FIFO Level register (U0FIFOLVL - 0x4000 C058, U2FIFOLVL - 0x4009 8058, U3FIFOLVL - 0x4009 C058)
UnFIFOLVL register is a read-only register that allows software to read the current FIFO level status. Both the transmit and receive FIFO levels are present in this register. Так что можно докладывать не заходя в прерывание. Точнее, не дожидаясь полного освобождения Tx FIFO. Жаль, во многих других процах нет этого регистра.
Сообщение отредактировал GetSmart - Sep 30 2013, 20:43
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Oct 1 2013, 03:09
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Terminator @ Sep 30 2013, 16:34)  Отправка выглядела примерно так: уарт не занят, разрешаем прерывание tx_empty, пихаем в фифо первый(или заполняем всё fifo) байт посылки, остальное в очередь которую проверит isr. Если уарт занят, то пихаем всё в очередь. В моём случае заморочка была в том что прерывание tx_empty бывало, что не срабатывало. Что-то вы криво делали - у меня стабильно работает всегда. Например - после разрешения tx_empty и перед пиханием в буфер, вы не забывали запрещать прерывания?  К тому же - по вашему алгоритму придётся запрет прерывания продлить до конца пихания в очередь всех данных. Логичнее делать по-другому: В задаче пишем всё в очередь (с разрешёнными прерываниями). После писания - проверим разрешено-ли прерывание UART (ну или программного флага, если в ISR не запрещаем IRQ TX_EMPTY при опустошении, а просто игнорим его), если запрещено - запрещаем прерывания CPU, вызываем функцию переписывающую из очереди в TX FIFO (эту же функцию вызываем из ISR при TX_EMPTY). Внутри этой функции, если в очереди имеется хотя-бы один байт - она разрешает прерывания TX_EMPTY (ставит программный флаг), заполняет FIFO из очереди. Если на входе в функцию очередь пуста, она запрещает TX_EMPTY (сбрасывает программный флаг). Если всё реализуете аккуратно, в том числе очередь - реерентерабельную для перекрывающихся чтений/записей, то всё будет работать как часы.
|
|
|
|
|
Oct 1 2013, 10:02
|
Участник

Группа: Свой
Сообщений: 69
Регистрация: 22-10-04
Пользователь №: 956

|
Цитата(GetSmart @ Oct 1 2013, 00:39)  По поводу докладывания FIFO 16-тью элементами. Цитата из UM10360 (LPC17xx user manual)
Так что можно докладывать не заходя в прерывание. Точнее, не дожидаясь полного освобождения Tx FIFO.
Жаль, во многих других процах нет этого регистра. UM10360, rev2, 20100819 Modifications: • UART0/1/2/3: FIFOLVL register removed.
|
|
|
|
|
Jan 30 2015, 10:08
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
Цитата(Golikov A. @ Jan 30 2015, 14:46)  отсутствием FIFO, например.... тем что нельзя пихнуть 16 байт и делать свои дела пока их выдавливает, а надо постоянно отвлекаться и по байту класть. А если у вас ModBus с условием определения конца по паузе между байтами посылки? Да, но так ли это заметно, если процессор работает на частоте под 100 MГц. Ему переложить из регистра в регистр что из fifo, что вручную велика ли разница?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|