LINUX.ORG.RU

История изменений

Исправление 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(). Пропорционально ли оно скорости?