2013-08-12 56 views
0

我是linux設備驅動程序中的新成員。我想寫一個C/C++代碼來執行從樹莓派到USB閃存驅動器的文件傳輸。我對起點有困難,所以我嘗試使用libusb獲取來自signal11的HID設備示例代碼,並且代碼可以正常工作,以便使用其設備ID檢測我的光學鼠標。然後,我試圖獲得USB閃存驅動器供應商ID不知何故,它給了我非常有線的號碼。最後,我想出了一個非常愚蠢的嘗試,通過編寫一個bash腳本將cp文件寫入到usb閃存驅動器中,並在C++中激活腳本並且它可以工作,但是我覺得這不是一個正確的方法。然後我開始使用SCSI協議,我很難理解它是如何工作的。任何指導方針都是值得讚賞的。USB Mass Storage linux

int scsi_get_serial(int fd, void *buf, size_t buf_len) { 
// we shall retrieve page 0x80 as per http://en.wikipedia.org/wiki/SCSI_Inquiry_Command 
unsigned char inq_cmd[] = {INQUIRY, 1, 0x80, 0, buf_len, 0}; 
unsigned char sense[32]; 
struct sg_io_hdr io_hdr; 
     int result; 

memset(&io_hdr, 0, sizeof (io_hdr)); 
io_hdr.interface_id = 'S'; 
io_hdr.cmdp = inq_cmd; 
io_hdr.cmd_len = sizeof (inq_cmd); 
io_hdr.dxferp = buf; 
io_hdr.dxfer_len = buf_len; 
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; 
io_hdr.sbp = sense; 
io_hdr.mx_sb_len = sizeof (sense); 
io_hdr.timeout = 5000; 

result = ioctl(fd, SG_IO, &io_hdr); 
if (result < 0) 
    return result; 

if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) 
    return 1; 

return 0; 
} 

int main(int argc, char** argv) { 
//char *dev = "/dev/sda"; 
char *dev = "/dev/sg2"; 
char scsi_serial[255]; 
int rc; 
int fd; 

fd = open(dev, O_RDONLY | O_NONBLOCK); 
if (fd < 0) { 
    perror(dev); 
} 

memset(scsi_serial, 0, sizeof (scsi_serial)); 
rc = scsi_get_serial(fd, scsi_serial, 255); 
// scsi_serial[3] is the length of the serial number 
// scsi_serial[4] is serial number (raw, NOT null terminated) 
if (rc < 0) { 
    printf("FAIL, rc=%d, errno=%d\n", rc, errno); 
} else 
if (rc == 1) { 
    printf("FAIL, rc=%d, drive doesn't report serial number\n", rc); 
} else { 
    if (!scsi_serial[3]) { 
     printf("Failed to retrieve serial for %s\n", dev); 
     return -1; 
    } 
    printf("Serial Number: %.*s\n", (size_t) scsi_serial[3], (char *) & scsi_serial[4]); 
} 
close(fd); 

return (EXIT_SUCCESS); 
} 

我得到這個序列號:00/1F

然後我嘗試用C test.sh

cp /home/Desktop/stl4.pdf /media/mini_flash 

和運行系統( 「./ test.sh」)寫這篇++

+0

我們需要你的代碼的相關部分,而「奇異數」,你從了裝置。此外,'lspci'的輸出將確實幫助我們確定你有什麼與返回的內容。 –

+0

你沒有說清楚。首先,你說你檢索「供應商ID」,那麼你說你得到「序列號」00/1F。這兩個屬性只有勉強相關(單個供應商的產品串行不應該回收序列號,三倍的VID/PID/SN是唯一的) – MSalters

+0

我迷路了,很難理解這個概念。我會盡量讓自己更清楚一點。任何推薦的參考? – WWJ

回答

3

這個問題似乎是矛盾的,起初你說你想用一個內核驅動拷貝一個文件,這似乎很奇怪。然後你說你使用libusb,這是一個用戶空間庫。然後你說你試着用cp執行一個shell腳本。 也許你想要的只是一個代碼片段,它複製一個文件形成一個用戶空間 C/C++程序?嘗試one of these snippets

詳細地說,如果你想要做的是cp /home/Desktop/stl4.pdf /media/mini_flash一個C++等價,那麼這就夠了:

ifstream in("/home/Desktop/stl4.pdf",ios::binary); 
ofstream out("/media/mini_flash/stl4.pdf",ios::binary); 
out<<in.rdbuf(); 
in.close(); 
out.close(); 
+0

雅對不起,我的主要目的只是將文件從用戶空間複製到USB閃存驅動器,但我只是嘗試任何事情,並最終以一個凌亂的方式。感謝這個鏈接,它解釋了我真正需要的東西。 – WWJ