Получение «Ошибка шины» при доступе к UART2 через карту памяти (функция mmap) - PullRequest
0 голосов
/ 03 июля 2019

Я работаю на встроенной плате Linux.

Согласно нашему требованию, необходимо получить доступ к UART2 через карту памяти вместо файла последовательных символов (/ dev / ttymxc1). Когда я получаю доступ к UART1 через функцию mmap (), тогда она работает нормально. Но когда я пытаюсь получить доступ к UART2 через функцию mmap (), появляется сообщение «Ошибка шины». Я не могу понять, что происходит, потому что UART1 работает, а UART2 не работает. Пожалуйста, найдите мой исходный код и предложите мне что-нибудь не так здесь.

#include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <time.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <string.h>

 typedef unsigned int            uint32_t;

 #define READ_REG32(reg)         ( *((volatile uint32_t *) (reg)) )
 #define WRITE_REG32(value,reg)  ( *((volatile uint32_t *) (reg)) = value )

 #define ALLOC_SIZE              (1024)  
 //#define UART1_BASE        0x02020000
 #define UART2_BASE        0x021E8000

 /* Register definitions */
 #define URXD  0x0  /* Receiver Register */
 #define UTXD  0x40 /* Transmitter Register */
 #define UCR1  0x80 /* Control Register 1 */
 #define UCR2  0x84 /* Control Register 2 */
 #define UCR3  0x88 /* Control Register 3 */
 #define UCR4  0x8c /* Control Register 4 */
 #define UFCR  0x90 /* FIFO Control Register */
 #define USR1  0x94 /* Status Register 1 */
 #define USR2  0x98 /* Status Register 2 */
 #define UESC  0x9c /* Escape Character Register */
 #define UTIM  0xa0 /* Escape Timer Register */
 #define UBIR  0xa4 /* BRM Incremental Register */
 #define UBMR  0xa8 /* BRM Modulator Register */
 #define UBRC  0xac /* Baud Rate Count Register */
 #define UTS   0xb4 /* UART Test Register (mx31) */

 /* UART Control Register Bit Fields.*/
 #define  URXD_CHARRDY    (1<<15)
 #define  URXD_ERR        (1<<14)
 #define  URXD_OVRRUN     (1<<13)
 #define  URXD_FRMERR     (1<<12)
 #define  URXD_BRK        (1<<11)
 #define  URXD_PRERR      (1<<10)
 #define  URXD_RX_DATA    (0xFF)
 #define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
 #define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
 #define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
 #define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
 #define  UCR1_RRDYEN     (1<<9)     /* Recv ready interrupt enable */
 #define  UCR1_RDMAEN     (1<<8)     /* Recv ready DMA enable */
 #define  UCR1_IREN       (1<<7)     /* Infrared interface enable */
 #define  UCR1_TXMPTYEN   (1<<6)     /* Transimitter empty interrupt enable */
 #define  UCR1_RTSDEN     (1<<5)     /* RTS delta interrupt enable */
 #define  UCR1_SNDBRK     (1<<4)     /* Send break */
 #define  UCR1_TDMAEN     (1<<3)     /* Transmitter ready DMA enable */
 #define  UCR1_UARTCLKEN  (1<<2)     /* UART clock enabled */
 #define  UCR1_DOZE       (1<<1)     /* Doze */
 #define  UCR1_UARTEN     (1<<0)     /* UART enabled */

 #define  UTS_FRCPERR     (1<<13) /* Force parity error */
 #define  UTS_LOOP        (1<<12) /* Loop tx and rx */
 #define  UTS_TXEMPTY     (1<<6)     /* TxFIFO empty */
 #define  UTS_RXEMPTY     (1<<5)     /* RxFIFO empty */
 #define  UTS_TXFULL     (1<<4)     /* TxFIFO full */
 #define  UTS_RXFULL     (1<<3)     /* RxFIFO full */
 #define  UTS_SOFTRST     (1<<0)     /* Software reset */

 void uart_putc(void *base, int ch)
 {
     WRITE_REG32(ch, base + UTXD);
     /* Wait until sent */
     while (!(READ_REG32(base + UTS) & UTS_TXEMPTY));
 }

 static void write_on_uart()  
 {  
         int fd=0;
         void *map_base;

         fd = open("/dev/mem", O_RDWR | O_SYNC);  

         if (fd) {  
             printf("Success to open /dev/mem fd=%08x\n", fd);  
         }  
         else {  
             printf("Fail to open /dev/mem fd=%08x\n", fd);    
         }  

         map_base = mmap(0, ALLOC_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, UART2_BASE);

         if ((int)map_base == -1)
         {
            printf("Fail to create a base address \n");
            return;
          }

          printf("map_base: %p\n", map_base);

         for (int i = 0 ; i < 10; i++)
         uart_putc(map_base,'S');

         close(fd);
         munmap(map_base, ALLOC_SIZE);

 }

 int main(int argc, char **argv)
 {
          write_on_uart();
          return 0;
 }

Получение ошибки:

/ dev / mem открыта. [4243.747456] Необработанная ошибка: внешнее прерывание при нелинейном извлечении (0x1008) в 0x76fdd000 [4243.756248] pgd = 950c4000 [4243.759060] [76fdd000] * pgd = 94736835, * pte = 021e8703, * ppte = 021e8e33

Память сопоставлена ​​по адресу 0x76fdd000. Ошибка шины (ядро сброшено)

...