历史上的今天

今天是:2024年10月13日(星期日)

正在发生

2018年10月13日 | STM32在Ubuntu上编写USB上位机程序实现

发布者:龙爱泉也 来源: eefocus关键字:STM32  Ubuntu  USB  上位机 手机看文章 扫描二维码
随时随地手机看文章

libusb 介绍


libusb是开源的C库,使用该库是的用户可以在应用程序中直接访问 USB 设备,无需为 USB 设备编写内核驱动。libusb支持多个平台 (linux, window, ios),所以可以很方便地将应用程序移植到其他平台。


linux libusb 安装


从网上下载libusb的源码,下载地址:http://www.libusb.org/, 下载后编译安装。


# tar jxvf libusb-1.0.20.tar.bz2


# cd libusb-1.0.20

# ./configure

# make

# sudo make install

ubuntu下可以通过以下命令快速安装。


sudo apt-get isntall libusb*

安装后,libusb的头文件被安装在/usr/local/include/libusb-1.0 ,链接库被安装在/usr/loacal/lib目录下。


usb bulk 传输例程


这个例程演示如何使用 libusb 库,编写 USB bulk xfer 上位机demo,可以正常接收和发送数据。注意,修改程序中的 VID 和 PID 的值和你 device 板子上所定义的一致,传输数据块的大小不要超过 device 定义的最大传输长度。



#include "stdio.h"

#include "string.h"

#include "stdlib.h"

#include "unistd.h"


#include "libusb.h"


#define VID 0x8888

#define PID 0x0088


#define edp2in 0x82

#define edp2out 0x02


int main(void)

{

    libusb_device **devs, *dev;

    int ret, i;

    ssize_t cnt;

    usb_pro_t usb_pro;

    struct libusb_device_handle *handle = NULL;

    libusb_context *ctx = NULL;


    ret = libusb_init(&ctx);

    if (ret < 0)

        return -1;


    libusb_set_debug(ctx, 3);


    cnt = libusb_get_device_list(NULL, &devs);

    if (cnt < 0) {

        printf("no usb dev on bus\r\n");

        return  -1;

    }


    i = 0;

    while((dev = devs[i++]) != NULL) {


        ret = libusb_get_device_descriptor(dev,&desc);

        if (ret < 0) {

            printf("failed to get device descriptor");

            goto error;

        }


        if ((desc.idVendor == VID) && (desc.idProduct == PID)) {

            printf("bLength: 0xx\r\n", desc.bLength);

            printf("bDescriptorType: 0xx\r\n", desc.bDescriptorType);

            printf("bcdUSB: 0xx\r\n", desc.bcdUSB);

            printf("bDeviceClass: 0xx\r\n", desc.bDeviceClass);

            printf("bDeviceSubClass: 0xx\r\n", desc.bDeviceSubClass);

            printf("bDeviceProtocol: 0xx\r\n", desc.bDeviceProtocol);

            printf("bMaxPacketSize0: 0xx\r\n", desc.bMaxPacketSize0);

            printf("vendor id: 0xx\r\n", desc.idVendor);

            printf("product id: 0xx\r\n", desc.idProduct);

            printf("bcdDevice: 0xx\r\n", desc.bcdDevice);

            printf("iManufacturer: 0xx\r\n", desc.iManufacturer);

            printf("iProduct: 0xx\r\n", desc.iProduct);

            printf("iSerialNumber: 0xx\r\n", desc.iSerialNumber);

            printf("bNumConfigurations: 0xx\r\n", desc.bNumConfigurations);


        }


    }


    handle = libusb_open_device_with_vid_pid(ctx, VID, PID);


    if (handle == NULL) {

        printf("cant't open device\r\n");

        goto error;

    } else {

        printf("open device\r\n");

    }


    libusb_free_device_list(devs, 1);


    if (libusb_kernel_driver_active(handle, 0) ==1) {

        printf("kernel driver active, detach it \r\n");


        if (libusb_detach_kernel_driver(handle, 0) == 0) {

            printf("detached kernel driver\r\n");

        }

        else {

            goto error;

        }

    }


    ret = libusb_claim_interface(handle, 0);

    if (ret < 0) {

        printf("can't claim interface\r\n");

        goto error;

    } else {

        printf("claimed interface\r\n");

    }


    char data[64];

    int actual_len = 0;

    int didi = 1000;

    for (int i = 0; i< 1000; i++) {

        memset(data, 0, sizeof(data));

        //  receive data from device  

        //ret = libusb_bulk_transfer(handle, edp2in, data, 64, &actual_len, 0);

        //if (actual_len = 0) {

        //    printf("received nothing\r\n");

        //} else {

        //    printf("bulk transfer: %s\r\n", data);

        //}

        //usleep(200000);


        char *str = "am host";


        sprintf(data, "am host %d\r\n", i);


        ret = libusb_bulk_transfer(handle, edp2out, data, strlen(data), &actual_len, 0);


        if (actual_len != 0) {

            printf("send data: %s\r\n", data);

        }


        usleep(200000); 

    }


    libusb_close(handle);


error:


    printf("free device list\r\n");

    libusb_free_device_list(devs, 1);


    libusb_exit(NULL);


    return 0;

}

编译


编译代码可以使用 makefile 文件,也可以是使用命令行命令编译,这里给出两种编译方法。


makefile


CC = gcc


# your libusb library path, be careful your path.

LDIR = /usr/loacal/lib


# link flag

LFLAG = -lusb-1.0


# libusb hearder file path

INCLUDES = /usr/local/include/libusb-1.0


CFLAGS = -I$(INCLUDES) -std=c99


src = $(wildcard *.c)


obj = $(patsubst %.c, %.o, $(src))


.PHONY: all clean


all: main


main: $(obj)

    $(CC)   $(obj) -o main -L$(LDIR) $(LFLAG)


%.o:%.c

    $(CC) $(CFLAGS) -c $< -o $@


clean:

    @-rm -f main $(obj)

命令行编译 

命令中-I/usr/local/include/libusb-1.0 告诉编译器 libusb 的头文件所在的路径。-L/usr/local/lib/ 告诉链接器所要链接的库文件路径。-lusb-1.0 告诉编译器需要链接 libusb-1.0.so这个库。

 gcc -I/usr/local/include/libusb-1.0 -std=c99 main.c -o main -L/usr/local/lib/ -lusb-1.0

运行


编译后会在当前目录下生成一个名叫“main“的可执行文件,运行这个文件。如果打开USB设备时出错提示permission error,那么使用


# sudo ./main

运行后,HOST每隔200ms 向 device 发送一个数据包。


源码下载


我的源码已上传到http://download.csdn.net/detail/chengwenyang/9479835 ,包含STM32F4Discovery板子的 usb bulk 传输的工程文件和 使用 libusb 编写的上位机程序。


关键字:STM32  Ubuntu  USB  上位机 引用地址:STM32在Ubuntu上编写USB上位机程序实现

上一篇:进入存量市场,硬件巨头要开辟哪些新市场?
下一篇:arm-none-eabi-gcc编译STM32优化删除代码解决办法

推荐阅读

Linux对于开发者来说真的是一个非常好的系统,为开发者来说应该不陌生,通常我们在Windows下开发stm32很方便,有非常多的工具,IDE等支持,同样是操作系统,Linux开发STM32也一点不会差。Linux下开发stm32也有很多方法:1.使用makefile2.使用eclipse3.使用stm32cubemx+sw4stm324.... 有大神使用第一种,本人对makefile一知半解,拿不出手。第二种,win...
10月8日,我国首台基于泛在电力物联网的网荷互动空调开始投入试运行。 在国网江苏省电力有限公司智慧用能试验室,研发人员通过国家电网有限公司云端主站下发电网负荷调节指令,空调接受到指令后做出自动响应,设置温度从23摄氏度变为26摄氏度,空调风力随之减弱,功率监测装置显示空调实时功率相应降低。此台基于泛在电力物联网的网荷互动空调,是国网...
全球半导体解决方案供应商瑞萨电子集团宣布推出一款支持旁路模式的柔性升降压开关稳压器——ISL9122A,可提供超低静态电流(IQ),适用于为传感器、微控制器(MCU)、无线设备及其它系统组件供电。ISL9122A支持1.8V至5.5V电池供电,可延长纽扣电池、锂电池和多串联碱性电池组供电的智能物联网设备电池使用寿命。目标应用包括无线耳机、健身设备、智能手表...
1.CPU工作模式(Mode)ARM CPU有七种模式,各种模式如下图所示。注意用户模式下不可进入其他模式,用户模式是在有操作系统的时候给应用程序使用的,写应用程序的人水平千差万别,不能保证写的程序是好是坏,所以让应用程序运行在用户模式,限制应用程序的权限,防止破坏整个系统,2.状态(State) ARM架构的CPU有ARM state和Thumb state,ARM State:用的是A...

史海拾趣

问答坊 | AI 解惑

基于TMS320F2812的交流变频调速系统的设计

作者:武汉大学电气工程学院 张蔷 蒋云峰 宫鑫 李洪涛 本文在分析电压空间矢量调制基本原理的基础上,组成了以TMS320F2812为核心的单片机控制系统,实现SVPWM,对交流电机进行变频调速。关键词:TMS320F2812; 电压空间矢量调制;交流变频调速  & ...…

查看全部问答∨

如何采用FPGA协处理器实现算法加速

当今的设计工程师受到面积、功率和成本的约束,不能采用GHz级的计算机实现嵌入式设计。在嵌入式系统中,通常是由相对数量较少的算法决定最大的运算需求。使用设计自动化工具可以将这些算法快速转换到硬件协处理器中。然后,协处理器可以有效地连接 ...…

查看全部问答∨

RX8025中文资料(时钟芯片)

RX8025中文资料(时钟芯片)…

查看全部问答∨

44b0初始化程序

44b0初始化程序,44b0都用同样的初始化程序,里面还有些LIB.c程序。…

查看全部问答∨

买不起房,生不起娃,心情及其郁闷发资料!!!!!!!!!!!!!

搞个技术有啥用,后悔搞电子这一行.................... 嵌入式,linux,还有天天惦记的运动控制,go with death.............…

查看全部问答∨

LCD屏幕闪烁的很厉害?

WINCE启动时,显示EBOOT中LOGO LCD都显示很正常,可档ARM读FLASH中NK时,LCD就闪烁的非常厉害。在WINCE正常启动后,如果移动鼠标,LCD 也非常闪烁。有人遇到这种情况吗,怎么处理的?…

查看全部问答∨

lan91c96读不到ID,无片选,怎么解决

     目前,我在调试eboot,现在卡在网卡芯片lan91c96,在lan91cinit(*,*)函数里头第一件事情就是去读0x33这个标志,但我读到的数据是0      软硬件相关情况,PXA270+CE5.0,网卡芯片Lan91c96通过nCS2片 ...…

查看全部问答∨

GUI移值过程中的键盘驱动如何写

GUI一开始在vc中仿真 pc机的键盘支持得很好 现在移植到arm板子中,我用的键盘是zlg7290 I2C键盘,现在输入过程中比pc机的键盘功能相差很远,我想应该是少一层键盘驱动,麻烦问下这个驱动应该怎么写,才能达到pc机键盘的功能。…

查看全部问答∨

usb速度相关问题

1. U盘的读写速度有哪些决定因素?是不是包括1)接口:2.0 high speed vs. 2.0 full speed 2)Flash芯片读写速度。 2. USB延长线/转接线是不是有USB 2.0 high speed和USB 2.0 full speed之分?是不是会导致U盘连上后实际读写速度下降? 3. 我想比较U ...…

查看全部问答∨

问下各位,USB口的最大电流500ma需要在驱动下设置吗??

问题1、)我在自己的机器上接sp2102芯片的设备加51欧姆的负载,5.0伏特的电压被拉低到4.2伏特;正常吗??? 问题2、)5个51欧姆的并联接入,5.0伏特的电压被拉低到2.6伏特;正常吗?? 问题3、)usb协议里说枚举的时候可以申请大功率(由100ma开 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved