设备是扫描仪。我知道uart5是在dtsi文件中设置的,并且在用户空间中它在/ dev / ttymxc4下列出。从用户空间,我知道我可以通过
fd = open("/dev/ttymxc5", O_RDWR|O_NOCTTY|O_NONBLOCK);
if (fd < 0)
{
fprintf (stderr,"Open error on %s: %s\n", SCANNER_UART, strerror(errno));
return nullptr;
}
然后使用termios设置所有设置,例如波特率,使用write调用等写入数据。
我想在sysfs下抽象很多命令。我已经这样设置了“ uart驱动程序”:
result = uart_register_driver(&scanner_reg);
if (result)
return result;
result = uart_add_one_port(&scanner_reg, &scanner_port);
if (result)
uart_unregister_driver(&scanner_reg);
我正在使用gpio线打开系统和其他一些东西。但是,在原理图中,我看不到这些东西的gpio线。
UART5_CTS_HOST_SCAN_3_3V
UART5_RTS_HOST_SCAN_3_3V
UART5_RxD_HOST_SCAN_3_3V
UART5_TxD_HOST_SCAN_3_3V
我只是不确定如何从设备打开/写入/读取数据。我知道关于sys_open和类似的调用,但是我知道它们不是执行此操作的“正确”方法;我不想遍历用户空间。
所以,总而言之,我该怎么办
谢谢!请帮忙!对于uart来说,它是新事物,我过去曾经处理过i2c,而且看起来似乎不太复杂。
答案 0 :(得分:0)
这就是我所做的。我从内核而不是任何内核本机方法访问uart文件。这是作弊,但有效。所以,
#define SCANNER_UART "/dev/ttymxc4"
...
static int scanner_open(struct inode *inode, struct file *file)
struct termios term;
...
scanner_file = filp_open(SCANNER_UART, O_RDWR|O_NOCTTY|O_NONBLOCK, 0);
...
if (serial_tty_ioctl(scanner_file, TCGETS, (unsigned long)&term) < 0)
{
pr_err("%s: Failed to get termios\n", __FUNCTION__);
return -1;
}
term.c_cflag = B9600 | CLOCAL | CREAD; // 115200 if change, must configure scanner
/* No parity (8N1) */
term.c_cflag &= ~PARENB;
term.c_cflag &= ~CSTOPB;
term.c_cflag &= ~CSIZE;
term.c_cflag |= CS8;
term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
term.c_oflag &= ~OPOST;
term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
term.c_cc[VTIME] = 5; // 0.5 seconds read timeout
term.c_cc[VMIN] = 0; // read does not block
if (serial_tty_ioctl(scanner_file, TCSETS, (unsigned long)&term) < 0)
{
pr_err("%s: Failed to set termios\n", __FUNCTION__);
return -1;
}
...
static const struct file_operations scanner_fops = {
.owner = THIS_MODULE,
.write = scanner_write,
.read = scanner_read,
.open = scanner_open,
.release = scanner_close,
.llseek = no_llseek,
};
struct miscdevice scanner_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "scanner",
.fops = &scanner_fops,
};
...
ret = misc_register(&scanner_device);
if (ret) {
pr_err("can't misc_register :(\n");
return ret;
}
然后,我使用Sysfs向用户提供功能。这是正确的方法吗?可能不是,但这是出于我的目的。它实际上是在将用户空间的实现方式转移到内核。