c mmap 长写入 mmaped 区域
c mmap write long to mmaped-area
我想写一个 python-c-extension,它应该将整数列表写入 ram-area 因为我的第一个 python 版本有点慢(30 毫秒).
在 python 中,这与以下代码完美配合:
with open("/dev/mem", "r+b") as f: # open file
ddr_mem = mmap.mmap(f.fileno(), PRU_ICSS_LEN, offset=PRU_ICSS) # map pru shared-ram
while offset < ramSize:
ddr_mem[(sharedRam+offset):(sharedRam+offset+4)] = struct.pack('i', self.data[self.i])
offset += 4
self.i += 1
因为列表中只有长整数值(4 字节),对于列表中的每个新值,偏移量将增加 4。
由于 mmap 区域有 12 kB 大,因此可以将 3072 个值写入其中,因为 12288 Byte / 4 Byte = 3072 还是我错了?
现在在我的 c 扩展中,我对这段代码进行了相同的尝试:
if(ddrMem == NULL) {
//printf("\nopen: shared-ram...");
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd < 0) {
printf("Failed to open /dev/mem (%s)\n", strerror(errno));
return NULL;
}
/* map the DDR memory */
ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, PRU_ICSS + OFFSET_DDR + 0xE000); //TODO: weird offset - 0xE000
if (ddrMem == NULL) {
printf("Failed to map the device (%s)\n", strerror(errno));
close(mem_fd);
return NULL;
}
for (i = 0; i < d_len; i++) {
PyObject* temp = PySequence_Fast_GET_ITEM(seq, i);
elem = PyInt_AsLong(temp);
*((long*) DDR_regaddr+offset) = elem; // write to shared ram
offset = offset + 4;
if(offset >= (ramSize)){
offset = 0;
}
但是现在只有在ram-area中的每四个地址会得到一个新值。如果我将偏移量增加一个,它就可以工作,但是我可以写入两倍的数据 --> 6144 个元素。
有什么诀窍?我做错了什么?这些计算是否正确?我不确定我的想法是否正确。
您的偏移量不正确,因为您正在执行指针运算,它已经说明了所讨论的 long 的大小。
尝试将指针递增 1 而不是 4。
long *ptr = 0xff;
long *ptrOffset = ptr + 1; // Will access the next 'long' space in memory
long *ptrOffset2 = ptr + 4; // Will access the fourth next 'long' space in memory
此外,long 的大小实际上取决于体系结构和编译器。假设是4字节就不安全了。
好的抱歉..:(
错误的内存映射!
-> 错过了偏移量 0xF000
但非常感谢@kevr - 这也很有帮助:)
我想写一个 python-c-extension,它应该将整数列表写入 ram-area 因为我的第一个 python 版本有点慢(30 毫秒).
在 python 中,这与以下代码完美配合:
with open("/dev/mem", "r+b") as f: # open file
ddr_mem = mmap.mmap(f.fileno(), PRU_ICSS_LEN, offset=PRU_ICSS) # map pru shared-ram
while offset < ramSize:
ddr_mem[(sharedRam+offset):(sharedRam+offset+4)] = struct.pack('i', self.data[self.i])
offset += 4
self.i += 1
因为列表中只有长整数值(4 字节),对于列表中的每个新值,偏移量将增加 4。
由于 mmap 区域有 12 kB 大,因此可以将 3072 个值写入其中,因为 12288 Byte / 4 Byte = 3072 还是我错了?
现在在我的 c 扩展中,我对这段代码进行了相同的尝试:
if(ddrMem == NULL) {
//printf("\nopen: shared-ram...");
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd < 0) {
printf("Failed to open /dev/mem (%s)\n", strerror(errno));
return NULL;
}
/* map the DDR memory */
ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, PRU_ICSS + OFFSET_DDR + 0xE000); //TODO: weird offset - 0xE000
if (ddrMem == NULL) {
printf("Failed to map the device (%s)\n", strerror(errno));
close(mem_fd);
return NULL;
}
for (i = 0; i < d_len; i++) {
PyObject* temp = PySequence_Fast_GET_ITEM(seq, i);
elem = PyInt_AsLong(temp);
*((long*) DDR_regaddr+offset) = elem; // write to shared ram
offset = offset + 4;
if(offset >= (ramSize)){
offset = 0;
}
但是现在只有在ram-area中的每四个地址会得到一个新值。如果我将偏移量增加一个,它就可以工作,但是我可以写入两倍的数据 --> 6144 个元素。
有什么诀窍?我做错了什么?这些计算是否正确?我不确定我的想法是否正确。
您的偏移量不正确,因为您正在执行指针运算,它已经说明了所讨论的 long 的大小。
尝试将指针递增 1 而不是 4。
long *ptr = 0xff;
long *ptrOffset = ptr + 1; // Will access the next 'long' space in memory
long *ptrOffset2 = ptr + 4; // Will access the fourth next 'long' space in memory
此外,long 的大小实际上取决于体系结构和编译器。假设是4字节就不安全了。
好的抱歉..:(
错误的内存映射!
-> 错过了偏移量 0xF000
但非常感谢@kevr - 这也很有帮助:)