多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > libusb的異步也有這樣的問題

libusb的異步也有這樣的問題

來源:程序員人生   發布時間:2016-11-29 08:43:01 閱讀次數:7201次

1. 最近1直在關注異步機制,不論是網絡庫asio,libuv,還是libusb庫,其實異步機制都是差不多的,都是基于回調函數、系統輪詢實現的。

2. 下面是對1款USB產品做得測試結果,Windows環境下,用libusb異步API寫的程序:


說明:用 Bus Hound 抓包,查看返回數值發現上面3個命令只有R是成功的(即有返回值),卻對應在了B命令上,致使調用了B的回調。這就是異步容易致使的問題,也就是如果不停地發送命令,其中有1條命令失敗,而超時未過,回來的結果如果沒有別的辨別,致使調用失敗指令的回調,而致使比較嚴重的后果。

#include <errno.h> #include <pthread.h> #include <semaphore.h> #include <signal.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include "libusb.h" #define EP_IN (6 | LIBUSB_ENDPOINT_IN) #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) typedef enum { SAVE_IMAGE = 0x55, UPLOAD_IMAGE = 0xAA }BULK_REQCODE; typedef enum { SAVE_IMAGE_VAL = 0x00, UPLOAD_B_VAL = 0x00, UPLOAD_G_VAL = 0x01, UPLOAD_R_VAL = 0x02 }BULK_VALUE; static struct libusb_device_handle *devh = NULL; static unsigned char imgbuf_save[8]; static unsigned char imgbuf_upload[8]; static unsigned char imgbuf_R[2048*240]; static unsigned char imgbuf_G[2048*240]; static unsigned char imgbuf_B[2048*240]; static struct libusb_transfer *img_save = NULL; static struct libusb_transfer *img_R = NULL; static struct libusb_transfer *img_G = NULL; static struct libusb_transfer *img_B = NULL; static struct libusb_transfer *img_R_upload = NULL; static struct libusb_transfer *img_G_upload = NULL; static struct libusb_transfer *img_B_upload = NULL; static int img_idx = 0; static volatile sig_atomic_t do_exit = 0; static int ii=0; static pthread_t poll_thread; static sem_t exit_sem; static void request_exit(sig_atomic_t code) { do_exit = code; sem_post(&exit_sem); } static void *poll_thread_main(void *arg) //輪詢是不是main——thread結束 { int r = 0; printf("poll thread running\n"); while (!do_exit) { struct timeval tv = { 1, 0 }; r = libusb_handle_events_timeout(NULL, &tv); //處理任何待以處理的事件 if (r < 0) { request_exit(2); break; } } printf("poll thread shutting down\n"); return NULL; } static int find_dpfp_device(void) { devh = libusb_open_device_with_vid_pid(NULL, 0x04b4, 0x8623); return devh ? 0 : -EIO; } static void LIBUSB_CALL cb_img(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "upload_img_R_over callback : " << transfer->status << std::endl; } static void LIBUSB_CALL save_img(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "save Image callback : " << transfer->status << std::endl; } static void LIBUSB_CALL upload_img_B(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "upload_img_B callback : " << transfer->status << std::endl; } static void LIBUSB_CALL upload_img_B_over(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "upload_img_B_over callback : " << transfer->status << std::endl; } static void LIBUSB_CALL upload_img_G(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "upload_img_G callback : " << transfer->status << std::endl; } static void LIBUSB_CALL upload_img_G_over(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "upload_img_G_over callback : " << transfer->status << std::endl; } static void LIBUSB_CALL upload_img_R(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { fprintf(stderr, "img transfer status %d?\n", transfer->status); request_exit(2); return; } std::cout << "upload_img_R callback : " << transfer->status << std::endl; } //由于該裝備處理多命令異步發送過來的時候,只處理最后1條 static int LIBUSB_CALL submit_trans() { int r=0; r = libusb_submit_transfer(img_save); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_save); //異步取消之條件交傳輸 printf("1"); } r = libusb_submit_transfer(img_B_upload); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_B_upload); //異步取消之條件交傳輸 printf("1"); } r = libusb_submit_transfer(img_B); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_B); //異步取消之條件交傳輸 printf("1"); } r = libusb_submit_transfer(img_G_upload); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_G_upload); //異步取消之條件交傳輸 printf("1"); } r = libusb_submit_transfer(img_G); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_G); //異步取消之條件交傳輸 printf("1"); } r = libusb_submit_transfer(img_R_upload); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_R_upload); //異步取消之條件交傳輸 printf("1"); } r = libusb_submit_transfer(img_R); //提交1個傳輸并立即返回 if (r < 0) { libusb_cancel_transfer(img_R); //異步取消之條件交傳輸 printf("1"); } return r; } static int alloc_transfers(void) { img_save = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_save) return -ENOMEM; img_R = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_R) return -ENOMEM; img_R_upload = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_R_upload) return -ENOMEM; img_G = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_G) return -ENOMEM; img_G_upload = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_G_upload) return -ENOMEM; img_B = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_B) return -ENOMEM; img_B_upload = libusb_alloc_transfer(0); //0參數表明配置1個異步傳輸 if (!img_B_upload) return -ENOMEM; imgbuf_save[0] = (u_char)(SAVE_IMAGE); imgbuf_save[1] = 0x00; imgbuf_save[2] = 0x00; imgbuf_save[3] = 0x00; imgbuf_save[4] = (uchar)((0xff00 & 0x00f0)>>8); imgbuf_save[5] = (uchar)(0x00ff & 0x00f0); imgbuf_save[6] = 0x00; imgbuf_save[7] = (u_char)(SAVE_IMAGE_VAL); libusb_fill_bulk_transfer(img_save, devh, EP_OUT, imgbuf_save, sizeof(imgbuf_save), save_img, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 imgbuf_upload[0] = (u_char)UPLOAD_IMAGE; imgbuf_upload[1] = 0x00; imgbuf_upload[2] = 0x00; imgbuf_upload[3] = 0x00; imgbuf_upload[4] = (uchar)((0xff00 & 0x00f0)>>8); imgbuf_upload[5] = (uchar)(0x00ff & 0x00f0); imgbuf_upload[6] = 0x00; imgbuf_upload[7] = (u_char)UPLOAD_B_VAL; libusb_fill_bulk_transfer(img_B_upload, devh, EP_OUT, imgbuf_upload, sizeof(imgbuf_upload), upload_img_B, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 libusb_fill_bulk_transfer(img_B, devh, EP_IN, imgbuf_B, sizeof(imgbuf_B), upload_img_B_over, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 imgbuf_upload[0] = (u_char)UPLOAD_IMAGE; imgbuf_upload[1] = 0x00; imgbuf_upload[2] = 0x00; imgbuf_upload[3] = 0x00; imgbuf_upload[4] = (uchar)((0xff00 & 0x00f0)>>8); imgbuf_upload[5] = (uchar)(0x00ff & 0x00f0); imgbuf_upload[6] = 0x00; imgbuf_upload[7] = (u_char)UPLOAD_G_VAL; libusb_fill_bulk_transfer(img_G_upload, devh, EP_OUT, imgbuf_upload, sizeof(imgbuf_upload), upload_img_G, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 libusb_fill_bulk_transfer(img_G, devh, EP_IN, imgbuf_G, sizeof(imgbuf_G), upload_img_G_over, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 imgbuf_upload[0] = (u_char)UPLOAD_IMAGE; imgbuf_upload[1] = 0x00; imgbuf_upload[2] = 0x00; imgbuf_upload[3] = 0x00; imgbuf_upload[4] = (uchar)((0xff00 & 0x00f0)>>8); imgbuf_upload[5] = (uchar)(0x00ff & 0x00f0); imgbuf_upload[6] = 0x00; imgbuf_upload[7] = (u_char)UPLOAD_R_VAL; libusb_fill_bulk_transfer(img_R_upload, devh, EP_OUT, imgbuf_upload, sizeof(imgbuf_upload), upload_img_R, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 libusb_fill_bulk_transfer(img_R, devh, EP_IN, imgbuf_R, sizeof(imgbuf_R), cb_img, NULL, 5000); //該輔助函數來填充所需的libusb_transfer批量傳輸字段 return 0; } int main(void) { libusb_init(NULL); //初始libusb庫 int r = find_dpfp_device(); if(r!=0) { printf("%s\n", "not found dev" ); return 0; } r = libusb_claim_interface(devh, 0); //聲明裝備接口 if (r < 0) { fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r)); goto out; } std::cout << "claimed interface" << std::endl; r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL); //子線程poll_thread_main用來處理USB事件 if (r) goto out; r = alloc_transfers(); //配置1個異步bulk傳輸和1個中斷傳輸,先alloc然后fill_XX_transfer if (r < 0) { request_exit(1); pthread_join(poll_thread, NULL); //函數pthread_join用來等待1個線程的結束 goto out; } r = submit_trans(); //submit1個傳輸 if (r < 0) { request_exit(1); pthread_join(poll_thread, NULL); //失敗等待線程結束 goto out; } while (!do_exit) sem_wait(&exit_sem); //等待退出信號量 printf("shutting down...\n"); pthread_join(poll_thread, NULL); out_release: libusb_release_interface(devh, 0); out: libusb_close(devh); libusb_exit(NULL); sem_destroy(&exit_sem); return r >= 0 ? r : -r; }


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 一级女人毛片人一女人 | 羞羞影院免费观看网址在线 | 成年人在线观看视频免费 | 综合网小说图片区 | 久久久www成人免费精品 | 国产欧美二区三区 | 国产v片成人影院在线观看 国产v片在线观看 | 一级毛片高清免费播放 | 亚洲第一天堂无码专区 | 欧美日韩v | 日本一级毛片免费 | free欧美xxxxvideo| freexxx性欧美极品另类 | 国产二区精品 | 国产精品v欧美精品v日本精 | 国产亚洲精品久久久久久小说 | 伊人久久亚洲精品一区 | 噜噜噜噜私人影院老湿在线观看 | 国产精品成人一区二区1 | 欧美一级性视频 | 亚洲三级自拍 | 久操精品在线观看 | 欧美最新一区二区三区四区 | 精品无人区一区二区三 | 亚洲欧美日韩在线观看看另类 | 国产精品一区二区三区免费 | 最近中文字幕高清1 | 亚洲精品在线播放 | 欧美一级高清片免费一级 | 久久高清一级毛片 | 午夜影院免费入口 | 黄站在线 | 999yy成年在线视频免费看 | 三级黄在线播放 | 亚洲天堂在线观看视频 | 亚洲日比视频 | 亚洲区免费 | 九色精品在线 | 亚洲免费精品 | 一级毛片在线完整观看 | 美女牲交毛片一级视频 |