基于CANoe的ECU Bootloader刷写软件

目标:

        车辆ECU需要更新软件,通过OBD口实现,通过CAN总线实现,编程语言是CAPL。

        刷写流程基于ISO15765-3;应用层基于UDS(ISO14229)诊断协议;TP层基于ISO15765-2;数据链路层和物理层基于ISO11898

实现:

       1.图形用户界面使用CANoe自带的panel来实现,用户可以选取刷写文件,ECU的地址等信息,这些信息通过环境变量被程序访问,环境变量在CANDB++中编辑生成。


2.软件架构:

刷写工具解析s19 app,如果没有s19 app,那么可以使用HexView将HEX,BIN等app转成s19文件

依据ISO15765-3编写刷写流程代码,将app数据扔给应用层

应用层是基于UDS编写的,应用层在将数据扔给TP层

TP层将数据扔给数据链路层

数据链路层将数据扔给物理层,数据通过CAN总线被ECU接收



代码:

      工作保密原因,只贴出UDS层的代码,秘钥也删了

includes{
  
}

variables{
  char gECU[7]="Tester";

  int     useExtendedId=0;                                      //use standard Id
  long    useFC=1;                                             //use flow control
  long    bs=8;                                                //block size of FC
  long    stmin=20;                                            //set STmin to 10 ms

  dword   tester_address=0x7c1;                               //tester address
  dword   target_ecu_address=0x7c9;                           //BCM address
  char    wait_rsp_text_event[18]="response received";        //used to wait for response

  const int BUFFER_SIZE_2048=0x2048;
  const int BUFFER_SIZE_1024=0x1024;
  const int LENGTH_4=4;
  byte      rxBuffer[BUFFER_SIZE_2048];                          //receive buffer
  long      rxBufferLen=0;                                       //receive buffer length
  dword     timeout=5000;
  dword     min_request_distance=50;                            //minum distance between two request
  dword     dist_request = 10;
  char      gDebugBuffer[255];
}

/*
  read fault memory
*/
int read_fault_memory(byte _sub_func,byte _status_mask){
  byte request[3]={0x19,0x02,0x09};
  
  rxBufferLen=0;
  request[1]=_sub_func;request[2]=_status_mask;
  OSEKTL_DataReq(request,elcount(request));
  return wait_server_response(request,timeout);
}

/*
  sessionControl
*/
int session_control(byte _session_type){
  byte request[2]={0x10,0x01};
  
  request[1]=_session_type;
  OSEKTL_DataReq(request,elcount(request));
  return wait_server_response(request,timeout);
}

/*
  reset
*/
int reset(byte reset_type){
  byte request[2]={0x11,0x01};
  
  request[1]=reset_type;
  OSEKTL_DataReq(request,elcount(request));
  return wait_server_response(request,timeout);
}

/*
  securityAccess 
*/
int security_access(byte security_level,byte seed_szie,char ecu_name[]){
  //actual size of Seed & Key Arrays depends on ECU
  byte      gSeedArray[2];
  dword     gSeedArraySize   = 4;
  char      gVariant[9]    = "Variant1";
  char      gOption[7]     = "option";
  dword     gMaxKeyArraySize = 4;
  dword     gActualSize  = 0;
   
  byte      request_seed[2]={0x27,0x01};
  byte      send_key[6]={0x27,0x02,0xAA,0xAA,0xAA,0xAA};
  
  byte      const_secu_flash[4]={};           //security const number for level flash for BCM
  byte      const_secu_level1[4]={};          //security const number for level 1 for BCM
  byte      const_secu_flash_rfcm[4]={};           //security const number for level flash for BCM
  
  byte      seed[4]={0xAA,0xAA,0xAA,0xAA};                       //store the seed received from server
  byte      _key[4]={0xAA,0xAA,0xAA,0xAA};                       //store the key generated by tester
  int       i=0;
  
  request_seed[ 1 ] = security_level;send_key[ 1 ] = security_level + 0x01;
  OSEKTL_DataReq(request_seed,elcount(request_seed));       
  if(wait_server_response(request_seed,timeout)!=0){
    write("fail to retrive seed while unlocking ECU");
    return -1;
  }
  
  for(i=0;i=0)        
  {
    status=testWaitForTextEvent(wait_rsp_text_event,_tTime);
    if(status<0){
      write("service %x:fail to wait server response",request[0]);
      return -1;
    }else if(status==0){
      write("service %x:timeout while waiting for server\'s response",request[0]);
      return -1;
    }
    
    result=checkResponse(request);
    
    if(result==-3){
      write("response pending");
      flag=5;
    }
    
    if(result==-2){
      write("Warning:unexpected positive response");
      flag--;
    }
    
    if(result==-1){
      write("service %x:negative response received",request[0]);
      break;
    }
    
    if(result==0){
      //write("positive response received\n");
      break;
    }
  }

  if(result<0){  
    msgBeep(5);
    return -1;
  }
  
  return 0;
}

/*
  check response
  return 0 if positive response received
  otherwise return -1,-2,-3,0
  */
int checkResponse(byte request[]){
  if(rxBufferLen<=0){
    write("Error:empty response reveived\n");
    return -1;
  }
  else{ 
    if(rxBuffer[0]==request[0]+0x40){
      //write("positive response received\n");
      return 0;
    }else if(rxBuffer[0]!=0x7F&&rxBuffer[0]!=(rxBuffer[0]+0x40)){
      //unexpected positive response
      return -2;
    }
    else if(rxBuffer[0]==0x7F&&rxBuffer[1]==request[0]){ 
      if(rxBuffer[2]!=0x78)
      {
        //write("Error:negative response received\n");
        return -1;
      }else{
       //response pending
       return -3;
      }
    }
  }
  return 0;
}



你可能感兴趣的:(汽车电子)