CY68013的固件可以保存在主机上,当其被USB总线识别出来之后,可以通过驱动程序动态的加载USB固件,Linux内核中已经提供了完善的机制来加载设备的固件。

将需要加载的固件存放到/lib/firmware文件夹中,然后调用request_firmware函数,其中name为固件的名称(不需要路径)当固件成功加载到内核中会保存在struct firmware结构体中,size是固件的大小,data是固件中的内容(注意:固件内容是否正确以及固件如何解析需要在内核中完成)。当固件发送到设备之后,就可以调用release_firmware函数释放固件。

struct firmware {

size_t size;

u8 *data;

};

固件加载函数:

int request_firmware(const struct firmware **fw, char*name, struct device *device);

固件释放函数:

void release_firmware(struct firmware *fw);

当调用request_firmware函数成功获取CY68013的固件之后,在内核中需要对固件进行验证,检查加载到内核中的时候是有效的固件,然后将固件下载到USB设备中。

根据CY68013技术手册TRM上的说明下载固件到USB设备中需要按一下的步骤操作: 首先通过控制端点EP0,发送控制消息使8051核进入复位状态(CPUCS = 1);

然后根据HEX文件中的记录,通过EP0端点发送的控制消息下载数据到指定的地址;

待所有的HEX数据都下载完毕,再使8051恢复运行状态(CPUCS = 0);

如果新下载的固件中设置了USBCS中的RENUM位,则在8051核恢复运行状态之后会模拟USB设备断开与主机的连接,然后在连接主机重新进行设备的枚举。这时新下载的固件需要处理设备枚举中主机的各种请求。

按照CY68013 TRM上的说明,下载固件需要使用一下的请求:

则在USB的设备驱动中,需要通过USB core提供的API 进行操作,API的原型如下:

104 /**

105 * usb_control_msg - Builds a control urb, sends it off and waits for completion

106 * @dev: pointer to the usb device to send the message to

107 * @pipe: endpoint "pipe" to send the message to

108 * @request: USB message request value

109 * @requesttype: USB message request type value

110 * @value: USB message value

111 * @index: USB message index value

112 * @data: pointer to the data to send

113 * @size: length in bytes of the data to send

114 * @timeout: time in msecs to wait for the message to complete before timing

115 * out (if 0 the wait is forever)

116 *

117 * Context: !in_interrupt ()

118 *

119 * This function sends a simple control message to a specified endpoint and

120 * waits for the message to complete, or timeout.

121 *

122 * If successful, it returns the number of bytes transferred, otherwise a

123 * negative error number.

124 *

125 * Don't use this function from within an interrupt context, like a bottom half

126 * handler. If you need an asynchronous message, or need to send a message

127 * from within interrupt context, use usb_submit_urb().

128 * If a thread in your driver uses this call, make sure your disconnect()

129 * method can wait for it to complete. Since you don't have a handle on the

130 * URB used, you can't cancel the request.

131 */

132 int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,

133 __u8 requesttype, __u16 value, __u16 index, void *data,

134 __u16 size, int timeout)

usb_control_msg参数中的pipe必须通过usb_sndctrlpipe函数进行处理之后才能使用,request对应表3-8中的bRequest, requesttype对应表3-8中的bmRequest, value则是要下载到USB设备RAM中的起始地址(例如CPUCS寄存器的地址为0XE600),index按照表的说明始终为0, data则是要下载的数据,而size指明数据的大小,timeout则指明超时的时间,通常以HZ为参考处理。

一下是驱动程序中的相关代码,将usb_control_msg封装为3个函数,分别用来完成固件下载的3个步骤:

3 #define CY68013_VENDOR_REQ  0xa0        /* Cypress vendor bRequest */

4 #define CY68013_REQ_T_OUT   0x40        /* Cypress firmware download bmRequest */

5 #define CY68013_REG_CPUCS   0xE600      /* CY68013 CPUCS register address it control 8051                                               core reset and out of reset */

6 #define CY68013_RUN_CMD     0x00        /* Write this value to cy68013 CPUCS register                                                   make 8051 core run */

7 #define CY68013_RESET_CMD   0x01        /* Write this value to cy68013 CPUCS register mak                                               e 8051 core reset */

35 /* Make CY68013 out of reset */

36 static int cy68013_run(struct kref *kref)

37 {

38     unsigned char run = CY68013_RUN_CMD;

39

40     /* Write 0x0(run) to CPUCS  bit0 make cy68013 out of reset */

41     return cy68013_control_msg(kref, CY68013_REG_CPUCS, (void *)&run, sizeof(run));

42 }

43

44 /* Make CY68013 into reset */

45 static int cy68013_reset(struct kref *kref)

46 {

47     unsigned char reset = CY68013_RESET_CMD;

48

49     /* Write 0x1 to CPUCS bit0 make cy68013 into reset*/

50     return cy68013_control_msg(kref, CY68013_REG_CPUCS, (void *)&reset, sizeof(reset));

51 }579 /* Download data specify data to cy68013, data size speicied by size, download address specify by addr */

580 static int cy68013_control_msg(struct kref *kref, __u16 addr, void *data, __u16 size)

581 {

582 int retval = 0;

583

584 /* According usb_device pointer get struct usb_cy68013 data structure pointer */

585 struct usb_cy68013 *cyusb = to_cy68013_dev(kref);

586

587 /* Make sure only once can send contol message to device */

588 mutex_lock(&cyusb->io_mutex);

589

590 /* Check current usb is connect to bus */

591 if (!cyusb->interface){

592 mutex_unlock(&cyusb->io_mutex);

593 return -ENODEV;

594 }

595

596 /* Send control message to cy68013 */

597 retval = usb_control_msg(cyusb->udev, usb_sndctrlpipe(cyusb->udev, 0), CY68013_VENDOR_REQ, CY68013_REQ_T_OUT, addr, 0, data, size, HZ);

598

599 mutex_unlock(&cyusb->io_mutex);

600

601 return retval < 0 ? retval : 0;

602 }

usb升级linux固件,Linux USB驱动(4)---CY68013固件加载驱动相关推荐

  1. windows10驱动 x64--- 3环代码加载驱动(二)

    windows10驱动 x64--- 3环代码加载驱动 一:了解驱动加载工具 二:应用层--3环代码示例 一:了解驱动加载工具 平时调试.sys 我们都是用的驱动加载工具:open(打开驱动文件) - ...

  2. mysql驱动为什么自动加载_为什么JDBC中加载驱动要使用反射?

    原文链接:https://www.cnblogs.com/homejim/p/8076481.html 在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加 ...

  3. Linux系统开机自动加载驱动module

    Linux系统的驱动默认存放目录为: /lib/modules/$(uname -r)/kernel/drivers,因此如果希望系统可以启动时自动加载驱动必须首先把驱动放到该目录下面,执行完此步操作 ...

  4. linux dd来加载驱动,linux 加载raid驱动

    Centos5.5安装 上步完成后将U盘插到服务器上,插入光盘开始安装,在进入到安装界面的时候按F2 (Centos版本6是按ESC键就会出现boot:) CentOS安装RAID卡驱动总结 首先先介 ...

  5. u盘安装linux找不到驱动,利用U盘加载控制器驱动来安装Linux系统的方法

    一般我们在安装服务器过程中需要加载一些scsi卡或raid卡驱动,以便操作系统可以检测到硬盘. 常规的安装方式是要用到软驱,其实我们也是可以通过U盘来进行加载的. 装Linux控制器驱动往往都是*.d ...

  6. Linux驱动3:驱动模块加载与卸载

    目录 一.环境配置 1.开发板环境 2.uboot环境 ①设置bootargs ②设置bootcmd 二.加载驱动与卸载驱动 1.加载命令选择 2.创建目录环境以及驱动文件复制 3.加载驱动 提示①& ...

  7. Linux查看网卡加载驱动,linux网卡驱动分析之驱动加载

    通过insmod或者modprobe命令加载驱动,这两个命令为应用程序,在应用程序里调用了一个系统调用: extern long init_module(void *, unsigned long, ...

  8. Linux下的ELF文件、链接、加载与库(含大量图文解析及例程)

    Linux下的ELF文件.链接.加载与库 链接是将将各种代码和数据片段收集并组合为一个单一文件的过程,这个文件可以被加载到内存并执行.链接可以执行与编译时,也就是在源代码被翻译成机器代码时:也可以执行 ...

  9. Linux编译mplayer播放badapple及编译fbv加载图片(基于V3S预告板子要开源了)

    Linux编译mplayer播放badapple及编译fbv加载图片(基于V3S预告板子要开源了) 1.编译前准备: 1.linux5.10内核 2.2018.02bulidroot 3.v3s板子 ...

  10. Windows Driver开发_TraceEvents调试以及加载驱动的方法

    在最新版的WDK框架里,我们新建了Windows Driver KMDF模型之后默认使用的TraceEvents来打印输出的,这套输出机制叫WPP,我们可以在DriverEntry函数里看到它的初始化 ...

最新文章

  1. 巧用宏定义进行调试 (转)
  2. R语言可视化dataframe数据、并自定义设置坐标轴各个标签使用不同的色彩
  3. rocketMq指定broker ip地址,适合解决云主机部署问题
  4. AI:2020年6月22日北京智源大会演讲分享之10:40-11:30 Zoubin教授《Probabilistic Machine Learning and AI》
  5. 专门用来显示大量数据的视图:AdapterView(1)
  6. java 事件监听器是组件_JavaWeb的三大组件之事件监听组件(Listener)
  7. 解决‘tf.ResizeNearestNeighbor‘ op is neither a custom op nor a flex op
  8. 再见了微服务,DDD已成气候!
  9. On the Difference Between Orthogonal Matching Pursuit and Orthogonal Least Squares
  10. IOC和DI是什么?
  11. pat1100. Mars Numbers (20)
  12. BottomupSort算法 c++代码实现
  13. 蒙层禁止页面滚动的方案
  14. 一个简单的网页抓取工具
  15. 在线旅游网站技术讲解
  16. JS方式获取浏览器版本
  17. 【二分答案】SDUT-4072 小绿的脱单梦
  18. 微信小程序 - 音乐播放器源码
  19. C#中的函数(也叫方法)
  20. html+css制作扑克牌/小胡桃展开特教

热门文章

  1. 2017.4.22 进制转换 思考记录
  2. 【英语学习】【WOTD】stratagem 释义/词源/示例
  3. java中字节码_聊聊Java的字节码
  4. struts2漏洞_Apache Struts2057远程代码执行漏洞复现
  5. 域名抢注php程序_“丁真”被抢注,蹭热点这门生意,能成就好品牌?
  6. 写一段代码提高内存占用_记录一次生产环境中Redis内存增长异常排查全流程!...
  7. 室内温湿度监测系统解决方案
  8. “中国音乐金钟奖”落地成都 今年起将连续举办三届
  9. Docker问题:Dockerfile的From之前不能使用ARG
  10. Linux环境下为Tomcat安装APR CentOS系列