上位機調用CAN接口卡發送數據時,受上位機系統調度耗時的影響,實際CAN卡發送時會有時間上的誤差,是否有CAN卡可以將發送定時放到設備中來完成,從而規避掉上位機的調度影響呢?本文將為大家具體分析。使用CAN接口卡是CAN通訊領域無法避開的話題,它提供各種的接口類型,兼容多種上位機系統,簡單易用的二次開發接口函數庫。此外,windows平臺還提供了專業的應用層協議庫(DBC解析庫、UDS庫等),比起用ARM直接開發CAN(FD),用戶使用接口卡二次開發,可以直接調用高層協議函數庫,可以極大的節省應用層協議棧的開發成本。用戶只需關注自己的業務邏輯即可,大大的縮短項目開發周期。如此方便的用法也產生了一個問題,接口卡必須依賴于上位機的調用,不管windows還是linux系統,非實時系統就涉及到一個延時問題——系統調度的延時。例如當上位機執行到transmit發送函數,到系統執行這個動作,驅動將buffer下發給CAN接口卡的時間。系統調度時間是不可控的,取決于多方因素:程序開發的語言,電腦的性能,CPU當前的占用率等,一般都為毫秒級誤差。因此,當用戶需要軟件定時來發送報文時,無法保證很低的時間誤差。
問
是否有辦法規避上位機調度的延時?
答
方法是有的。USBCANFD提供了兩種方法,一定程度上規避上位機調度的時延問題:
硬件定時發送;
隊列發送。
硬件定時發送
USBCANFD 支持每通道最大 100條定時發送列表,只需將待發送數據及周期設置到設備并使能,設備將自動進行發送。相比于 PC 端的發送,定時發送精度高,周期準。在設備進行定時發送任務時,PC 端仍可調用數據發送接口進行數據發送。軟件實現方法,在ZCAN_StartCAN之后,繼續通過setvalue方式將定時發送結構體下載到設備中:
ZCAN_AUTO_TRANSMIT_OBJ auto_can; //從CAN定時發送結構體生成實例ZCANFD_AUTO_TRANSMIT_OBJ auto_canfd; //從CANFD定時發送結構體生成實例memset(&auto_can, 0, sizeof(auto_can));auto_can.index = 0; // 定時列表索引0auto_can.enable = 1; // 使能此索引,每條可單獨設置auto_can.interval = 100; // 定時發送間隔100msget_can_frame(auto_can.obj, 0); // 構造CAN報文prop->SetValue("1/auto_send", (const char*)&auto_can); // 設置定時發送memset(&auto_can, 0, sizeof(auto_can));auto_can.index = 1; // 定時列表索引1auto_can.enable = 1; // 使能此索引,每條可單獨設置auto_can.interval = 200; // 定時發送間隔200msget_can_frame(auto_can.obj, 1); // 構造CAN報文prop->SetValue("1/auto_send", (const char*)&auto_can); // 設置定時發送memset(&auto_canfd, 0, sizeof(auto_canfd));auto_canfd.index = 2; // 定時列表索引2auto_canfd.enable = 1; // 使能此索引,每條可單獨設置auto_canfd.interval = 500; // 定時發送間隔500msget_canfd_frame(auto_canfd.obj, 2); // 構造CANFD報文prop->SetValue("1/auto_send_canfd", (const char*)&auto_canfd); // 設置定時發送prop->SetValue("1/apply_auto_send", "0"); // 使能定時發送Sleep(5000); // 等待發送5sprop->SetValue("1/clear_auto_send", "0"); // 清除定時發送
優點:1.周期穩定,精度100us;2.可修改報文內容隨時覆蓋;3.可根據需求單獨對某條定時報文進行禁用操作。缺點:1.數據不是自動變化的,如涉及到內容變化,需要再次設置定時;2.不適用于非周期性的報文。
隊列發送
通過隊列發送,用戶可以提前準備好多幀報文,設定報文之間的間隔,將準備好的報文發送給設備,設備按照預定義的幀間隔進行精準發送,通過此方式可提高發送幀之間的幀間隔精度。與定時發送相比,隊列發送每幀只發送一次,需由用戶不斷準備報文并批量發送到設備。USBCANFD-200U先通過SetValue將設備的發送模式切換成隊列發送模式。隊列發送緩存大小為100幀,隊列發送過程中,可以通過GetValue查詢當前隊列緩存的剩余空間。隊列發送有兩種方法實現:
一種是合并發送ZCAN_TransmitData——對應發送結構體ZCANDataObj;
另一種是單通道發送ZCAN_Transmit和ZCAN_TransmitFD——對應發送結構體ZCAN_Transmit_Data和ZCAN_TransmitFD_Data。
兩者都是發送結構體中使能隊列發送標志位,并且填入隊列發送報文間隔,再通過對應發送函數,發給設備合并發送ZCAN_TranmitData的代碼實現:
Prop->Setvalue(“0/set_send_mode”, “1”); //USBCANFD需要切換發送模式,CANFDNET無需此步驟…void get_can_frame_queue(ZCANDataObj& data, int ch, canid_t id, bool is_fd, UINT delay){memset(&data, 0, sizeof(data)); //初始化data結構體data.dataType = ZCAN_DT_ZCAN_CAN_CANFD_DATA;data.chnl = ch; //通道號ZCANCANFDData & can_data = data.data.zcanCANFDData;can_data.frame.can_id = MAKE_CAN_ID(id, 0, 0, 0); // CAN ID + STD/EXT + DATA/RMTcan_data.frame.len = is_fd ? 64 : 8; // 數據長度 8/64can_data.flag.unionVal.transmitType = 0; // 正常發送can_data.flag.unionVal.txEchoRequest = 1; // 設置發送回顯can_data.flag.unionVal.frameType = is_fd ? 1 : 0; // CAN or CANFDcan_data.flag.unionVal.txDelay = ZCAN_TX_DELAY_UNIT_MS; // 隊列延時單位毫秒can_data.timeStamp = delay; // 隊列延時時間,最大值 65535for (int i = 0; i < can_data.frame.len; ++i) { ? ? ? ? ? ? ? ? // 填充 CAN 報文 DATAcan_data.frame.data[i] = i;}…Ret = ZCAN.TransmitData(device_handle, data ,len);
第二種方法ZCAN_Transmit的代碼實現:
Prop->Setvalue(“0/set_send_mode”, “1”); //USBCANFD需要切換發送模式,CANFDNET無需此步驟…ZCAN_Transmit_Data can_data[10]={};ZCAN_TransmitFD_Data canfd_data[10]={};memset(& can_data, 0, sizeof(can_data)); //初始化data結構體memset(& canfd_data, 0, sizeof(canfd_data)); //初始化data結構體…can_data[0].frame.can_id =0x100;can_data[0].frame.__pad =0x80; //使能CAN幀隊列發送can_data[0].frame.__res0 =0x64; // 低位,設置100mscan_data[0].frame.__res1 =0x00; // 高位…canfd_data[0].frame.can_id =0x200;canfd_data[0].frame.flags=0x80; //使能非加速CANFD隊列發送,0x81使能加速CANFD隊列發送canfd_data[0].frame.__res0 =0x64; // 低位,設置100mscanfd_data[0].frame.__res1 =0x00; // 高位…ret = ZCAN.Transmit(channel_handle, can_data, 10);ret_fd = ZCAN.TransmitFD(channel_handle, canfd_data, 10);
隊列發送的優缺點:
- 優點:定時間隔準確,最小精度為100us;
- 缺點:設備分配的緩存大小有限,實際使用中需要結合getvalue去查緩存剩余空間,避免發送幀丟失。
以上兩種方法分別適用不同場景,根據實際應用需求,靈活使用,可以很大程度規避上位機調度帶來的時延問題,對用戶的通訊起到更穩定和精準的控制。
【版權聲明】本文為ZLG開發者社區用戶原創內容,未經授權不得轉載。歡迎更多用戶到社區交流互動、創作博文,一經采用,可獲得百元京東E卡。
地址:https://developer.zlg.cn(長按復制到PC端打開)
-
接口
+關注
關注
33文章
8639瀏覽量
151385 -
CAN
+關注
關注
57文章
2756瀏覽量
463899
發布評論請先 登錄
相關推薦
評論