我正在嵌入式Linux板上工作。
根据我们的要求,需要通过内存映射而不是串行字符文件(/ dev / ttymxc1)访问UART2。当我通过mmap()函数访问UART1时,它工作正常。但是,当我尝试通过mmap()函数访问UART2时,出现“总线错误”。我无法理解发生了什么,因为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]未处理的错误:在0x76fdd000处的非linefetch(0x1008)上发生外部异常终止 [4243.756248] pgd = 950c4000 [4243.759060] [76fdd000] * pgd = 94736835,* pte = 021e8703,* ppte = 021e8e33
映射到地址0x76fdd000的内存。 总线错误(核心已转储)