Я строю модуль ядра UART с API RTDM. Для таблицы данных AUART я работал с главой 30 следующей ссылки: Ссылка на таблицу данных
Драйвер очень базовый c, ему нужно только отправить буфер, который передается ему в пространстве пользователя с функцией write
. Это работает так:
- В функции
open
, активируйте UART с помощью UARTEN
бита регистра управления UART - В
write
функции, я активирую преобразователь с помощью бита TXE регистра управления UART - Затем начните отправку символов с:
static void rt_mxs_auart_tx_chars(struct rt_mxs_auart_ctx *ctx)
{
int ch;
pr_info("Start transmitting\n");
while (ctx->out_npend > 0 &&
!(mxs_read(ctx->port, REG_STAT) & AUART_STAT_TXFF)) {
ch = ctx->out_buf[ctx->out_head++];
mxs_write(ch, ctx->port, REG_DATA);
ctx->out_head &= (OUT_BUFFER_SIZE - 1);
ctx->out_npend--;
}
if (mxs_read(ctx->port, REG_STAT) & AUART_STAT_TXFF){
pr_info("We've stopped transmitting because FIFO is full, remains: %d to be sent (bytes pending)\n", ctx->out_npend);
}
if(ctx->out_npend > 0 ) {
mxs_set(AUART_INTR_TXIEN, ctx->port, REG_INTR);
pr_info("%d bytes pending, setting AUART_INTR_TXIEN\n", ctx->out_npend);
}
else {
mxs_clr(AUART_INTR_TXIEN, ctx->port, REG_INTR);
pr_info("%d bytes pending, clearing AUART_INTR_TXIEN\n", ctx->out_npend);
}
}
TXIEN
соответствует Transmit Interrupt Enable
, а AUART_STAT_TXFF
означает, что FIFO передачи заполнен. Вот структура ctx:
struct rt_mxs_auart_ctx {
struct rtser_config config; /* current device configuration */
rtdm_irq_t irq_handle; /* device IRQ handle */
rtdm_lock_t lock; /* lock to protect context struct */
int in_head; /* RX ring buffer, head pointer */
int in_tail; /* RX ring buffer, tail pointer */
size_t in_npend; /* pending bytes in RX ring */
int in_nwait; /* bytes the user waits for */
rtdm_event_t in_event; /* raised to unblock reader */
char in_buf[IN_BUFFER_SIZE]; /* RX ring buffer */
volatile unsigned long in_lock; /* single-reader lock */
uint64_t *in_history; /* RX timestamp buffer */
int out_head; /* TX ring buffer, head pointer */
int out_tail; /* TX ring buffer, tail pointer */
size_t out_npend; /* pending bytes in TX ring */
rtdm_event_t out_event; /* raised to unblock writer */
char out_buf[OUT_BUFFER_SIZE]; /* TX ring buffer */
rtdm_mutex_t out_lock; /* single-writer mutex */
uint64_t last_timestamp; /* timestamp of last event */
int ioc_events; /* recorded events */
rtdm_event_t ioc_event; /* raised to unblock event waiter */
volatile unsigned long ioc_event_lock; /* single-waiter lock */
int ier_status; /* IER cache */
int mcr_status; /* MCR cache */
int status; /* cache for LSR + soft-states */
int saved_errors; /* error cache for RTIOC_GET_STATUS */
/*
* The port structure holds all the information about the UART
* port like base address, and so on.
*/
struct rt_mxs_auart_port *port;
};
В моем обработчике прерываний я делаю это:
if (istat & AUART_INTR_TXIS){
pr_info("Transmit Interrupt Status enabled\n");
rt_mxs_auart_tx_chars(ctx);
istat &= ~AUART_INTR_TXIS;
ret = RTDM_IRQ_HANDLED;
}
, что означает, что если флаг состояния прерывания активен, мы отправляем данные снова с тем же function rt_mxs_auart_tx_chars
Моя проблема в том, что я не получаю конца моего сообщения. Например, если я пытаюсь отправить «Это ... это мое второе сообщение» (29 символов), я получаю только «Это ... это мой набор c» (17 символов). Журнал выглядит следующим образом:
Calling open function
Calling write function
Enabling Transmitter
Start transmitting
We've stopped transmitting because FIFO is full, remains: 12 to be sent (bytes pending)
12 bytes pending, setting AUART_INTR_TXIEN
IRQ handler called
Transmit Interrupt Status enabled
Start transmitting
We've stopped transmitting because FIFO is full, remains: 4 to be sent (bytes pending)
4 bytes pending, setting AUART_INTR_TXIEN
Receive Interrupt Status or Receive Timeout Interrupt Status enabled
IRQ handler called
Transmit Interrupt Status enabled
Start transmitting
0 bytes pending, clearing AUART_INTR_TXIEN
Disabling Transmitter
Как вы думаете, я могу это исправить?