CAPL实现UDS下载框架

最近在做CAPL实现UDS下载,本下载框架可实现配置修改,提高效率。核心代码如下。

includes
{
    #pragma library (".\Exec32\MMSound.dll")
    #pragma library (".\Exec32\osek_tp.dll")
}

variables
{
    long physHandle;
    long cantpHandle;

    char rspEvent[18] = "Diag Receved!";
    byte rspData[100];
    dword rspLen = 0;
    
    const dword physTx = 0x705;
    const dword funcTx = 0x7DF;
    const dword respRx = 0x785;
    
    const byte repeatSend = 1;
    const byte cantpPadding = 0xAA;


    struct fileInfo
    {
        long fileHandle;
        char filePath[512];
        dword maxAddr;
        dword minAddr;
        dword segNum;
        dword segAddr[20];
        dword segLen[20];
        dword segOffset[20];
        byte segData[1 * 1024 * 1024];
    };
    
    struct reqPDU
    {
        byte addrMode;
        long prevFunc;
        char pduInfo[50];
        char reqDataString[80];
        char rspDataString[80];
        long postFunc;
    };

    struct fileInfo file;
    
    enum funcDef
    {
        REQUEST_SEED_POST = 0,
        SEND_KEY_PREV,
        TRANS_DATA_DRIVER_PREV,
        CHECK_DRIVER_PREV,
        REQUEST_DOWN_APP_POST,
        TRANS_DATA_APP_PREV,
        CHECK_APP_PREV  
    };
    
    struct reqPDU reqPduList[20] = 
    {
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "To ExtSession...",
            reqDataString = "10 03 ",
            rspDataString = "50 ",
            postFunc = 0
        },
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "DTCSetting=off...",
            reqDataString = "85 02 ",
            rspDataString = "C5 "
        },
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "DisableCommunicat...",
            reqDataString = "28 01 01 ",
            rspDataString = "68 ",
            postFunc = 0
        },
        {
            addrMode = 'P',
            prevFunc = 0,
            pduInfo = "To ProgrammingSession...",
            reqDataString = "10 02 ",
            rspDataString = "50 ",
            postFunc = 0
        },
        {
            addrMode = 'P',
            prevFunc = 0,
            pduInfo = "RequestSeed...",
            reqDataString = "27 11 ",
            rspDataString = "67 ",
            postFunc = REQUEST_SEED_POST
        },
        {

            addrMode = 'P',
            prevFunc = SEND_KEY_PREV,
            pduInfo = "SendKey...",
            reqDataString = "27 12 00 00 00 00 ",
            rspDataString = "67 ",
            postFunc = 0
        },
        {
            addrMode = 'P',
            prevFunc = 0,
            pduInfo = "RequestDownloadFlashDriver...",
            reqDataString = "34 00 44 00 00 04 00 00 00 00 40 ",
            rspDataString = "74 "
        },
        {
            addrMode = 'P',
            prevFunc = TRANS_DATA_DRIVER_PREV,
            pduInfo = "TransferData...",
            reqDataString = "36 01 FF FF ",
            rspDataString = "76 ",
            postFunc = 0
        },
        {
            addrMode = 'P',
            prevFunc = 0,
            pduInfo = "TransferExit...",
            reqDataString = "37 ",
            rspDataString = "77 ",
            postFunc = 0
        },
        {
            addrMode = 'P',
            prevFunc = CHECK_DRIVER_PREV,
            pduInfo = "CheckRoutine...",
            reqDataString = "31 01 02 02 00 00 00 00",
            rspDataString = "71 ",
            postFunc = 0
        },
        {
            addrMode = 'P',
            prevFunc = 0,
            pduInfo = "EraseMemory...",
            reqDataString = "31 01 FF 00 44 00 3E 80 00 00 01 70 00 ",
            rspDataString = "71 "
        },
        {
            addrMode = 'P',
            prevFunc = 0,
            pduInfo = "HardReset...",
            reqDataString = "11 01 ",
            rspDataString = "51 ",
            postFunc = 0
        },
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "To ExtSession...",
            reqDataString = "10 03 ",
            rspDataString = "",
            postFunc = 0
        },
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "EnableCommunicat...",
            reqDataString = "28 00 01 ",
            rspDataString = "",
            postFunc = 0
        },
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "DTCSetting=on...",
            reqDataString = "85 01 ",
            rspDataString = "",
            postFunc = 0
        },
        {
            addrMode = 'F',
            prevFunc = 0,
            pduInfo = "To DefSession...",
            reqDataString = "10 01 ",
            rspDataString = "",
            postFunc = 0
        }
    };
    
    byte driverdata[100] = 
	{
		
	};
    
    
}

dword crc32(byte data[], dword len)
{
	return crc ;
}

int userMemCmp(byte cs[], byte ct[], dword count)
{
    dword i;
    int ret;
    
    ret = 0;
    for(i = 0; i < count; i++)
        if((ret = cs[i]-ct[i]) != 0)
            break;
        
    return ret;    
}

void DownAppProcess(void)
{
    byte i;
    long result, replyOk;
    char info[80];
    byte reqData[1024+16];
    dword reqLen, sendLen;
    byte seedArray[4], keyArray[4];
    dword crc;
    dword maxSize;
    dword seqNo, offset;
    dword expertLen;
    byte expertData[20];
    
    @Pannel::ProgressBarPos = 0;
    
    maxSize = 1024;
    seqNo = 0;
    crc = 0;
    offset = 0;
    expertLen = 0;
    
    cantpHandle = CanTpCreateConnection(0);    // 0 = Normal mode
    CanTpSetTxIdentifier(cantpHandle, physTx);  // Tx CAN-ID
    CanTpSetRxIdentifier(cantpHandle, respRx);  // Rx CAN-ID
    CanTpSetPadding(cantpHandle, cantpPadding);

    
    for(i = 0; i < 25; i++)
    {
        strncpy(info, reqPduList[i].pduInfo, elCount(reqPduList[i].pduInfo));
        strncat(info, "start", elCount(info)-1);
        write(info);
        
        reqLen = str2data(reqPduList[i].reqDataString, reqData);
        
        // prev data process
        switch(reqPduList[i].prevFunc)
        {
            case SEND_KEY_PREV:
                getKey(0x11, seedArray, keyArray);

    			reqData[2] = keyArray[0];
    			reqData[3] = keyArray[1];
    			reqData[4] = keyArray[2];
    			reqData[5] = keyArray[3];
    			reqLen = 6;
                break;
            case TRANS_DATA_DRIVER_PREV:
    			
                reqLen = elCount(driverdata);
                break;
            case CHECK_DRIVER_PREV:		
    			crc = crc32(driverdata, elCount(driverdata));
    			//string2byte(cmd, cmddata, &cmdlen);
    			reqData[0] = 0x31;
    			reqData[1] = 0x01;
    			reqData[2] = 0x02;
    			reqData[3] = 0x02;
    			reqData[4] = crc>>24;
    			reqData[5] = crc>>16;
    			reqData[6] = crc>>8;
    			reqData[7] = crc;
    			reqLen = 8;
                break;
            case TRANS_DATA_APP_PREV:
    			reqLen = file.maxAddr-file.minAddr+1;
                break;
            case CHECK_APP_PREV:		
    			crc = crc32(file.segData, (file.maxAddr-file.minAddr+1));
                
    			reqData[0] = 0x31;
    			reqData[1] = 0x01;
    			reqData[2] = 0x02;
    			reqData[3] = 0x02;
    			reqData[4] = crc>>24;
    			reqData[5] = crc>>16;
    			reqData[6] = crc>>8;
    			reqData[7] = crc;
    			reqLen = 8;
                break;
            default:
                break;
        }
        
        seqNo = 1;
        while(reqLen > 0)
        {
            if(reqLen >= maxSize)
            {
                sendLen = maxSize;
            }
            else
            {
                sendLen = reqLen;
            }
            
            if(reqPduList[i].prevFunc == TRANS_DATA_DRIVER_PREV)
            {
                reqData[0] = 0x36;
    			reqData[1] = 0x01;
    			memcpy_off(reqData, 2, driverdata, 0, elCount(driverdata));
                result = CanTpTransmit(reqPduList[i].addrMode, reqData, sendLen+2, 500, 5000);
                if(repeatSend == 1 && result == 0) // timeout repeat send
                {
                    testwaitfortimeout(50);
                    result = CanTpTransmit(reqPduList[i].addrMode, reqData, sendLen+2, 500, 5000);
                }
            }
            else if(reqPduList[i].prevFunc == TRANS_DATA_APP_PREV)
            {
                reqData[0] = 0x36;
			    reqData[1] = seqNo++;
                memcpy_off(reqData, 2, file.segData, offset, sendLen);
                result = CanTpTransmit(reqPduList[i].addrMode, reqData, sendLen+2, 500, 5000);
                if(repeatSend == 1 && result == 0)
                {
                    testwaitfortimeout(50);
                    result = CanTpTransmit(reqPduList[i].addrMode, reqData, sendLen+2, 500, 5000);
                }
                offset += sendLen;
            }
            else
            {
                result = CanTpTransmit(reqPduList[i].addrMode, reqData, sendLen, 500, 5000);
                if(repeatSend == 1 && result == 0) // timeout repeat send
                {
                    testwaitfortimeout(50);
                    result = CanTpTransmit(reqPduList[i].addrMode, reqData, sendLen, 500, 5000);
                }
            }
            if(@Pannel::ProgressBarPos < 150)
            {
                @Pannel::ProgressBarPos = @Pannel::ProgressBarPos+1;
            }
            
            expertLen = str2data(reqPduList[i].rspDataString, expertData);
            if((rspLen >= expertLen) && userMemCmp(expertData, rspData, expertLen) == 0)
            {
            }
            else
            {
                //strncpy(info, reqPduList[i].pduInfo, elCount(reqPduList[i].pduInfo));
                //strncat(info, "-------------err--------------", elCount(info)-1);
                //write(info);
                write("-------------err--------------");
                SysSetVariableString(sysvar::Pannel::Info, "-------------ERROR--------------");
                //mmsndPlay("track03.mp3", 5000);
                {
                    char SoundFilesPath[256];
                    int kStringLen  = 256;
                    
                    getAbsFilePath("", SoundFilesPath, kStringLen);
                    mmsndSetMediaPath(SoundFilesPath);
                    mmsndPlay("track03.mp3", 0);
                }
                        
                return;   
            }
            
            reqLen -= sendLen;
        }
        
        // post data process
        switch(reqPduList[i].prevFunc)
        {
            case REQUEST_SEED_POST:
                seedArray[0] = rspData[2];
    			seedArray[1] = rspData[3];
    			seedArray[2] = rspData[4];
    			seedArray[3] = rspData[5];
                break;
            case REQUEST_DOWN_APP_POST:
                maxSize = (rspData[2] << 8) + rspData[3] - 2;
                break;
            default:
                break;
        }
        
        strncpy(info, reqPduList[i].pduInfo, elCount(reqPduList[i].pduInfo));
        strncat(info, "end", elCount(info)-1);
        write(info);
        
        testwaitfortimeout(500);
    }
    
    @Pannel::ProgressBarPos = 150;
    SysSetVariableString(sysvar::Pannel::Info, "-------------SUCCESS--------------");
}



void CanTp_ReceptionInd(long connHandle, byte data[])
{
    //write("Recv handle %d, data %x", connHandle, data[0]);
    memcpy(rspData, data, elCount(data));
    rspLen = elCount(data);

    TestSupplyTextEvent(rspEvent);
}

CanTp_ErrorInd( long connHandle, long error)
{

}

long CanTpTransmit(byte addrMode, byte reqData[], dword reqLen, long timeOut, long timeOutPending)
{
    byte data[20], data2[20];
    long ret, result, pending;

    rspLen = 0;
    
    if(addrMode == 'P')
    {
        CanTpSetTxIdentifier(cantpHandle, physTx);
    }
    else
    {
        CanTpSetTxIdentifier(cantpHandle, funcTx);
    }
    testWaitForTimeout(20);
    
    CanTpSendData(cantpHandle, reqData, reqLen);

    pending = 0;
    do
    {
        result = testWaitForTextEvent(rspEvent, timeOut);
        if(result == 0) // Resume due to timeout
        {
            ret = result;
            rspLen = 0;
            break;
        }
        else // Resume due to event occurred
        {
            if(rspLen == 3 && rspData[0] == 0x7F && rspData[1] == reqData[0] && rspData[2] == 0x78)
            {
                timeOut = timeOutPending;
                rspLen = 0;
                continue;
            }
            else
            {
                ret = result;
                break;
            }
        }
    }while(1);

    return ret;
}

 

  • 6
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
CAPL 是矢量公司开发的一种脚本语言,主要用于 CAN 和 LIN 网络的测试和仿真。在实现 UDS 刷写时,可以通过 CAPL 脚本与 UDS 协议栈进行交互,实现数据的收发和处理。以下是一个简单的 CAPL 脚本示例,用于发送 UDS 诊断请求并接收响应: ```c variables { message UDS_Request; // UDS 诊断请求消息 message UDS_Response; // UDS 诊断响应消息 dword address = 0x12345678; // 要刷写的地址 dword data = 0x11223344; // 要写入的数据 } on start { // 初始化 CAN 通道 setCanChannel(1); setBaudrate(500000); setCanBusOutputControl(1); // 初始化 UDS 协议栈 UDS_Init(); } on timer event { // 构造 UDS 诊断请求消息 UDS_Request.ID = 0x7E8; UDS_Request.Data(0) = 0x22; // 诊断服务 ID UDS_Request.Data(1) = address >> 24; // 地址高位 UDS_Request.Data(2) = address >> 16; // 地址次高位 UDS_Request.Data(3) = address >> 8; // 地址次低位 UDS_Request.Data(4) = address; // 地址低位 UDS_Request.Data(5) = data >> 24; // 数据高位 UDS_Request.Data(6) = data >> 16; // 数据次高位 UDS_Request.Data(7) = data >> 8; // 数据次低位 UDS_Request.Data(8) = data; // 数据低位 UDS_Request.len = 9; // 发送 UDS 诊断请求消息 output(Uds_Request); // 等待 UDS 诊断响应消息 while(!Uds_Response.valid) delay(10); // 处理 UDS 诊断响应消息 if(Uds_Response.Data(0) == 0x62) // 诊断响应 ID { if(Uds_Response.Data(1) == 0x22) // 诊断服务 ID { if(Uds_Response.Data(2) == 0x00) // 响应报文子函数 ID { // UDS 诊断请求成功,可以进行下一步操作 // ... } else { // UDS 诊断请求失败,处理错误码 // ... } } else { // UDS 诊断请求失败,处理错误码 // ... } } } ``` 该示例中,通过定时器事件周期性发送 UDS 诊断请求消息,并等待 UDS 诊断响应消息。在接收到响应消息后,根据响应数据判断 UDS 诊断请求是否成功,如果成功则可以进行下一步操作,否则需要处理错误码。需要注意的是,该示例仅用于演示 UDS 刷写的基本流程,实际应用中需要根据具体需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值