![](/img/trans.png)
[英]How to properly convert a C ioctl call to a python fcntl.ioctl call?
[英]Error converting a C ioctl/mmap call to Python?
我想将 Linux 驱动程序与 Python 一起使用,并且我正在转换我的 C 程序。
我的 C 程序运行良好,但在 Python 中出现错误: IOError: [Errno 14] Bad address
我在用着:
Python 2.7.13(默认,2018 年 6 月 11 日,22:51:25)[GCC 7.2.0] on linux2
我的操作系统是 Petalinux。
这是 C 程序
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#define DUMMY_IOC_MAGIC 'V'
#define DUMMY_START_TX_CYCLIC _IO(DUMMY_IOC_MAGIC, 0)
#define DUMMY_START_TX _IO(DUMMY_IOC_MAGIC, 1)
int main()
{
int fd, j, ret;
int32_t *map_vptr;
size_t number_of_samples = 64;
size_t size_sample = 4;
//////////////////////////////////////////////////////////////////////////////
printf("Init tx.\n");
fd = open("/dev/playback", O_RDWR | O_SYNC);
if (fd < 0) {
printf("Error opening device\n");
return -1;
}
else{
printf("Device is open...\n");
}
//////////////////////////////////////////////////////////////////////////////
map_vptr = (int32_t*) mmap(0, size_sample * number_of_samples, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map_vptr == MAP_FAILED) {
close(fd);
printf("Error mmapping the file\n");
return -1;
}
printf("Mapped.\n");
//////////////////////////////////////////////////////////////////////////////
int32_t *dst_ptr = map_vptr;
int32_t counter = 0;
for (j = 0; j < number_of_samples; ++j) {
dst_ptr[j] = counter;
counter = counter + 2;
}
//////////////////////////////////////////////////////////////////////////////
// start TX transactions
uint32_t tx_total_len = size_sample * number_of_samples;
ret = ioctl(fd, DUMMY_START_TX, &tx_total_len);
if (ret < 0)
{
printf("ioctl() failed, errno=%d\n", errno);
return -1;
}
printf("End tx.\n");
return 0;
}
这是 Python 程序
import mmap, os, fcntl
#define DUMMY_START_TX _IO('V', 1)
DUMMY_IOC_MAGIC = 'V'
DUMMY_START_TX = ord(DUMMY_IOC_MAGIC) << (4*2) | 1
NUMBER_OF_SAMPLES = 64;
SIZE_SAMPLE = 4
################################################################################
# Open device
print("Init tx.");
fd = os.open("/dev/playback", os.O_RDWR | os.O_SYNC)
if (fd < 0):
print("Error opening device")
exit(-1);
else:
print("Device is open...")
################################################################################
map_vptr = mmap.mmap(length = SIZE_SAMPLE*NUMBER_OF_SAMPLES, prot = mmap.PROT_READ | mmap.PROT_WRITE,
flags = mmap.MAP_SHARED, fileno = fd, offset = 0)
print("Mapped.");
################################################################################
for i in range(0,NUMBER_OF_SAMPLES):
map_vptr.write_byte(chr(i))
################################################################################
# start TX transactions
tx_total_len = SIZE_SAMPLE * NUMBER_OF_SAMPLES
ret = fcntl.ioctl(fd, DUMMY_START_TX, tx_total_len);
fd.close()
print("End tx.");
output 是:
Init tx.
Device is open...
Mapped.
Traceback (most recent call last):
File "tx_server.py", line 28, in <module>
ret = fcntl.ioctl(fd, DUMMY_START_TX, tx_total_len);
IOError: [Errno 14] Bad address
来自Python 文档:
fcntl.fcntl(fd, op[, arg])
参数
arg
是可选的,默认为 integer 值0
。 如果存在,它可以是 integer 值或字符串。 With the argument missing or an integer value, the return value of this function is the integer return value of the Cfcntl()
call. 当参数是字符串时,它表示二进制结构,例如由struct.pack()
创建。 二进制数据被复制到缓冲区,其地址被传递给 Cfcntl()
调用。 调用成功后的返回值为缓冲区的内容,转换为字符串object。
以上对fcntl.ioctl()
也有效。 在您的情况下,您应该使用struct.pack()
来传递值,而不是直接传递 integer ,如下所示:
import struct
# ...
tx_total_len = SIZE_SAMPLE * NUMBER_OF_SAMPLES
ptr = struct.pack('I', tx_total_len)
# I == unsigned int of 4 bytes (uint32_t)
ret = fcntl.ioctl(fd, DUMMY_START_TX, ptr)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.