Linux的芯片驱动firmware自动升级之一:功能说明

来源:互联网 发布:淘宝店铺显示的销量 编辑:程序博客网 时间:2024/06/03 02:38
在驱动开发过程中,我们有时会碰到这种应用:比如说某款芯片的固件不是固定的,是可以后期升级的。那么在每次系统开机时,需要做个检测,如果检测到提供了新的固件,那么在第一次开机时就升级固件。之后由于保存了新的固件版本号可供检测,就不用再开机升级了。

        以一款I2C的触摸屏芯片为例,假设供应商提供的新固件文件名是Us3x06eb_use.it,将该文件放在触摸屏驱动.c的同目录下,那么需要做的就是在触摸屏的Probe函数里面加入对应的版本号检测处理,并决定是否升级。如果需要升级,将目标固件通过I2C写入即可。

[cpp] view plaincopyprint?
  1. typedef enum 
  2.        ERR_OK, 
  3.        ERR_MODE, 
  4.        ERR_READID, 
  5.        ERR_ERASE, 
  6.        ERR_STATUS, 
  7.        ERR_ECC, 
  8.        ERR_DL_ERASE_FAIL, 
  9.        ERR_DL_PROGRAM_FAIL, 
  10.        ERR_DL_VERIFY_FAIL 
  11. }E_UPGRADE_ERR_TYPE; 
  12.  
  13. #define    FTS_PACKET_LENGTH        2    //一次写两个字节,作为一个PACKET 
  14.  
  15. static unsigned char CTPM_FW[] =           //载入目标固件 
  16.       #include "Us3x06eb_use.it" 
  17. }; 
  18.  
  19. static int fts_i2c_txdata(u8 *txdata,int length)   //一次通过I2C传输多字节数据 
  20.        int ret; 
  21.        struct i2c_msg msg; 
  22.        msg.addr = i2c_client->addr; 
  23.        msg.flags = 0; 
  24.        msg.len = length; 
  25.        msg.buf = txdata; 
  26.        ret = i2c_transfer(i2c_client->adapter, &msg, 1); 
  27.  
  28.        if(ret < 0) 
  29.        { 
  30.              pr_err("%s i2c write error: %d\n", __func__, ret); 
  31.        } 
  32.  
  33.        return ret; 
  34.  
  35. static bool i2c_write_interface(u8 *pbt_buf,int dw_lenth)    //通过I2C写多个数据 
  36.        int ret; 
  37.        ret = i2c_master_send(i2c_client, pbt_buf, dw_lenth); 
  38.        if(ret <= 0) 
  39.        { 
  40.              printk("[TSP]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret); 
  41.              return FTS_FALSE; 
  42.        } 
  43.  
  44.        return FTS_TRUE; 
  45.  
  46. static bool i2c_read_interface(u8 *pbt_buf,int dw_lenth)   //通过I2C读多个数据 
  47.        int ret; 
  48.        ret = i2c_master_recv(i2c_client, pbt_buf, dw_lenth); 
  49.        if(ret <= 0) 
  50.        { 
  51.               printk("[TSP]i2c_read_interface error\n"); 
  52.               return FTS_FALSE; 
  53.        } 
  54.  
  55.        return FTS_TRUE; 
  56.  
  57. static bool fts_register_write(u8 reg_name, u8 *tx_buf)    //往寄存器写单字节数据 
  58.        u8 write_cmd[2] = {0}; 
  59.        write_cmd[0] = reg_name; 
  60.        write_cmd[1] = *tx_buf; 
  61.        return i2c_write_interface(write_cmd, 2); 
  62.  
  63. static bool fts_register_read(u8 reg_name, u8 *rx_buf,int rx_length)    //从寄存器读多个数据 
  64.        u8 read_cmd[2] = {0}; 
  65.        u8 cmd_len  = 0; 
  66.        read_cmd[0] = reg_name; 
  67.        cmd_len = 1; 
  68.  
  69.        /*send register addr*/ 
  70.        if(!i2c_write_interface(&read_cmd[0], cmd_len)) 
  71.        { 
  72.               return FTS_FALSE; 
  73.        } 
  74.  
  75.        if(!i2c_read_interface(rx_buf, rx_length)) 
  76.        { 
  77.               return FTS_FALSE; 
  78.        } 
  79.  
  80.        return FTS_TRUE; 


      E_UPGRADE_ERR_TYPE  fts_ctpm_fw_upgrade(u8 *pbt_buf, int dw_lenth)   //编程烧录细节不阐述,实例会在本博客的续篇中列出

{

       //将数据划分成相应的PACKET,一次通过I2C写入芯片中。有几个问题需要注意:(1)要注意分包的衔接,数据长度未必恰好能划分成整数个包,那么最后一个包要单独

       //处理;(2)数据校验,比如说芯片带自动异或校验的话,一方面我们在发送的过程中要及时进行数据校验运算,另一方面在数据发送完毕后,可以把这个校验值跟校验

       //寄存器的值进行比较,从而判断当前传输是否有效。

}

[cpp] view plaincopyprint?
  1. int fts_ctpm_fw_upgrade_with_i_file(void
  2.        u8     *pbt_buf = 0x0; 
  3.        int ret; 
  4.        pbt_buf = CTPM_FW; 
  5.        ret =  fts_ctpm_fw_upgrade(pbt_buf, sizeof(CTPM_FW));    //升级特定文件 
  6.        return ret; 
  7.  
  8. static int __devinit tpd_probe(struct i2c_client *client,const struct i2c_device_id *id)//TP的probe函数 
  9.  
  10.  
  11.         ............. 
  12.  
  13.         {  
  14.                u8 reg_val=0; 
  15.                mdelay(50); 
  16.                fts_register_read(0xA6,®_val,1);     //读出当前版本号 
  17.                  if(reg_val<TP_LIB_VERSION)   //如果当前版本号小于待升级版本号,进行升级 
  18.                 { 
  19.                        printk("TP firmware version OK, start upgrade\n");  
  20.                        fts_ctpm_fw_upgrade_with_i_file();    
  21.               } 
  22.        } 
  23.  
  24.         ............. 
  25.