Rockbox Development > Starting Development and Compiling
Dereferencing a pointer doesn't give what's actually at the pointer?!
(1/1)
fanta2:
I've hit an annoying snag whilst making some modifications to the usb stack; which have me stumped. I asked in IRC, but noone seemed to know what was going on, so I decided to ask here. The complete function is below:
--- Code: ---int ptp_sendobject(unsigned short command)
{
if (!session.curobjinfo.open) return -1;
usb_drv_recv(ep_out, buffer, sizeof(struct ptp_container_header));
struct ptp_container_header *header;
header = buffer;
// if (header->wType != PTP_CONTAINER_TYPE_DATA) return -2;
// Get the filesize
uint32_t *temp = buffer;
uint32_t temptwo = *temp;
uint32_t filesizeremaining = temptwo - sizeof(struct ptp_container_header);
// Start writing data to the file
int packetsize = endpoint_descriptor.wMaxPacketSize;
logf("hdrlent %d", header->iLength);
logf("hdrlenp %d", *((uint32_t*)buffer));
logf("tmptmpt %d", *temp);
logf("tmptmp2 %d", temptwo);
logf("hdrtype %d", header->wType);
logf("filesze %d", filesizeremaining);
logf("pktsize %d", packetsize);
logf("%x %x %x %x", *(buffer+0), *(buffer+1), *(buffer+2), *(buffer+3));
logf("%x %x %x %x", *(buffer+4), *(buffer+5), *(buffer+6), *(buffer+7));
logf("%x %x %x %x", *(buffer+8), *(buffer+9), *(buffer+10), *(buffer+11));
logf("%x %x %x %x", *(buffer+12), *(buffer+13), *(buffer+14), *(buffer+15));
int i = 0;
while (filesizeremaining > packetsize) {
usb_drv_recv(ep_out, buffer, packetsize);
write(session.curobjinfo.fd, buffer, packetsize);
filesizeremaining -= packetsize;
logf("got data %d", i++);
}
// Write up the remainder of the file and close up, resetting curobjinfo
usb_drv_recv(ep_out, buffer, filesizeremaining);
logf("got last data %d", i);
write(session.curobjinfo.fd, buffer, filesizeremaining);
close(session.curobjinfo.fd);
session.curobjinfo.open = false;
return 0;
}
--- End code ---
The problem segment is the following:
--- Code: --- // Get the filesize
uint32_t *temp = buffer;
uint32_t temptwo = *temp;
uint32_t filesizeremaining = temptwo - sizeof(struct ptp_container_header);
// Start writing data to the file
int packetsize = endpoint_descriptor.wMaxPacketSize;
logf("hdrlent %d", header->iLength);
logf("hdrlenp %d", *((uint32_t*)buffer));
logf("tmptmpt %d", *temp);
logf("tmptmp2 %d", temptwo);
logf("hdrtype %d", header->wType);
logf("filesze %d", filesizeremaining);
logf("pktsize %d", packetsize);
logf("%x %x %x %x", *(buffer+0), *(buffer+1), *(buffer+2), *(buffer+3));
logf("%x %x %x %x", *(buffer+4), *(buffer+5), *(buffer+6), *(buffer+7));
logf("%x %x %x %x", *(buffer+8), *(buffer+9), *(buffer+10), *(buffer+11));
logf("%x %x %x %x", *(buffer+12), *(buffer+13), *(buffer+14), *(buffer+15));
--- End code ---
According to logf, the data located at buffer is exactly what's sent over usb. I'm trying to get an unsigned int from the start of the packet, but no matter what I do and regardless of the actual value stored at buffer, if I dereference the pointer and store the result in a normal variable on the stack(?) it equals 12 (perhaps coincidentally, the previous value stored at buffer is 12). The weird thing is, if I dereference the pointer straight up as an argument to logf, it shows the correct value.
Any ideas? Thanks :)
dreamlayers:
How is the data getting into the buffer? Is it written by the CPU or by USB hardware (DMA)? Try looking at UNCACHED_ADDR(buffer).
fanta2:
Changing 'uint32_t temptwo = *temp' to 'uint32_t temptwo = *((uint32_t*)UNCACHED_ADDR(buffer));' didn't seem to do anything, unfortunately :(.
EDIT: Neither did changing uint32_t *temp = buffer to use 'UNCACHED_ADDR(buffer)' either. I imagine the usb driver is using DMA (I'm coding with a sansa e200R, so it'll be using usb_drv_arc.c for the driver I believe).
gevaerts:
The ARC controller does indeed use DMA, so you do need UNCACHED_ADDR everywhere (see usb_storage.c for an example, especially usb_storage_init_connection())
Also, you shouldn't care about the packetsize, the underlying driver handles that for you. Just call usb_drv_recv() once with whatever size buffer you can handle, not once per packet.
(Edit) One more thing, and probably your main problem : usb_drv_recv() isn't synchronous. You call it, and then you do nothing until your transfer_complete() function is called.
fanta2:
Gah, makes sense >.<. I wasn't entirely sure about whether packet size had an effect on what I could grab, and I guess usb_drv_send_nonblocking() had me confused about whether it blocks or not; thanks :).
Navigation
[0] Message Index
Go to full version