繁体   English   中英

将 C ioctl/mmap 调用转换为 Python 时出错?

[英]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 C fcntl() call. 当参数是字符串时,它表示二进制结构,例如由struct.pack()创建。 二进制数据被复制到缓冲区,其地址被传递给 C fcntl()调用。 调用成功后的返回值为缓冲区的内容,转换为字符串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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM