История изменений
Исправление Zubok, (текущая версия) :
после отключения дма, если вызвать поле write ещё и tcdrain, то он исправно будет ждать чего-то эти самые 30 миллисекунд.
Если DMA гарантировано отключен, а передача даже 7 байт и последующий вызов tcdrain() занимает 30 мс, то у меня версия, что он ждет очистки FIFO, который 32 байта у тебя. Примерно так и получается, если учесть, что байт на скорости 9600 передается 1 мс.
Каждый драйвер serial должен обеспечивать фунцкию tx_empty. В драйвере imx.c эту функцию обеспечивает функция imx_uart_tx_empty. В ней можно видеть, что проверяется бит TXDC в регистре USR2. Reference manual, к сожалению, на NXP по регистрации можно только получить, а мне сейчас неохота добывать этот reference где-то еще. Я не могу посмотреть, когда этот бит выставляется, однако техподдержка на форуме утверждает, что бит выставляется, когда TxFIFO *и* выходной сдвиговый регистр пуст. Просто пустой TxFIFO - это бит TXFE.
Вот функция из драйвера. Проверяется бит TXDC. Если TXDC выставился, то возвращаем TIOCSER_TEMT, то есть передачик все передал. Если для передачи используется DMA, то не сразу выходим, а проверяем и DMA. Если цикл DMA для передатчик еще не завершился, то считаем, что еще не передали. Вот поэтому с DMA ожидание больше.
/*
* Return TIOCSER_TEMT when transmitter is not busy.
*/
static unsigned int imx_uart_tx_empty(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
unsigned int ret;
ret = (imx_uart_readl(sport, USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0;
/* If the TX DMA is working, return 0. */
if (sport->dma_is_txing)
ret = 0;
return ret;
}
Меня смущает в этом предположении, что процессор будет ждать передачи 32 байт, даже если передаются 7 байт. Надо прочесть, как точно он работает в Reference manual. Попробуй увеличить скорость в два раза, запиши свои 7 байт и проверь осциллографом, как изменилось время просиживания в tcdrain(). Пропорционально ли оно скорости?
UPD. Или это таймаут, с которым работает опрос окончания передачи.
Исправление Zubok, :
после отключения дма, если вызвать поле write ещё и tcdrain, то он исправно будет ждать чего-то эти самые 30 миллисекунд.
Если DMA гарантировано отключен, а передача даже 7 байт и последующий вызов tcdrain() занимает 30 мс, то у меня версия, что он ждет очистки FIFO, который 32 байта у тебя. Примерно так и получается, если учесть, что байт на скорости 9600 передается 1 мс.
Каждый драйвер serial должен обеспечивать фунцкию tx_empty. В драйвере imx.c эту функцию обеспечивает функция imx_uart_tx_empty. В ней можно видеть, что проверяется бит TXDC в регистре USR2. Reference manual, к сожалению, на NXP по регистрации можно только получить, а мне сейчас неохота добывать этот reference где-то еще. Я не могу посмотреть, когда этот бит выставляется, однако техподдержка на форуме утверждает, что бит выставляется, когда TxFIFO *и* выходной сдвиговый регистр пуст. Просто пустой TxFIFO - это бит TXFE.
Вот функция из драйвера. Проверяется бит TXDC. Если TXDC выставился, то возвращаем TIOCSER_TEMT, то есть передачик все передал. Если для передачи используется DMA, то не сразу выходим, а проверяем и DMA. Если цикл DMA для передатчик еще не завершился, то считаем, что еще не передали. Вот поэтому с DMA ожидание больше.
/*
* Return TIOCSER_TEMT when transmitter is not busy.
*/
static unsigned int imx_uart_tx_empty(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
unsigned int ret;
ret = (imx_uart_readl(sport, USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0;
/* If the TX DMA is working, return 0. */
if (sport->dma_is_txing)
ret = 0;
return ret;
}
Меня смущает в этом предположении, что процессор будет ждать передачи 32 байт, даже если передаются 7 байт. Надо прочесть, как точно он работает в Reference manual. Попробуй увеличить скорость в два раза, запиши свои 7 байт и проверь осциллографом, как изменилось время просиживания в tcdrain(). Пропорционально ли оно скорости?
Исходная версия Zubok, :
после отключения дма, если вызвать поле write ещё и tcdrain, то он исправно будет ждать чего-то эти самые 30 миллисекунд.
Если DMA гарантировано отключен, а передача даже 7 байт и последующий вызов tcdrain() занимает 30 мс, то у меня версия, что он ждет очистки FIFO, который 32 байта у тебя. Примерно так и получается, если учесть, что байт на скорости 9600 передается 1 мс.
Каждый драйвер serial должен обеспечивать фунцкию tx_empty. В драйвере imx.c эту функцию обеспечивает функция imx_uart_tx_empty. В ней можно видеть, что проверяется бит TXDC в регистре USR2. Reference manual, к сожалению, на NXP по регистрации можно только получить, а мне сейчас неохота добывать этот reference где-то еще. Я не могу посмотреть, когда этот бит выставляется, однако техподдержка на форуме утверждает, что бит выставляется, когда TxFIFO *и* выходной сдвиговый регистр пуст. Просто пустой TxFIFO - это бит TXFE.
Вот функция из драйвера. Проверяется бит TXDC. Если TXDC выставился, то возвращаем TIOCSER_TEMT, то есть передачик все передал. Если для передачи используется DMA, то не сразу выходим, а проверяем и DMA. Если цикл DMA для передатчик еще не завершился, то считаем, что еще не передали. Вот поэтому с DMA ожидание больше.
/*
* Return TIOCSER_TEMT when transmitter is not busy.
*/
static unsigned int imx_uart_tx_empty(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
unsigned int ret;
ret = (imx_uart_readl(sport, USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0;
/* If the TX DMA is working, return 0. */
if (sport->dma_is_txing)
ret = 0;
return ret;
}
Меня смущает в этом предположении, что процессор будет ждать передачи 32 байт, даже если передаются 7 байт. Надо прочесть, как точно он работает в Reference manual. Попробуй увеличить скорость в два раза, запиши свои 7 байт и проверь осциллографом, как изменилось время просиживания в tcdrain(). Пропорционально ли оно скорости?