【发布时间】:2021-03-06 05:41:10
【问题描述】:
这可能是在黑暗中拍摄,但这种行为让我很难过。
我正在为嵌入式电机控制器编写控制 gui,通过 CAN 与 PC 通信(使用 kvaser light leaf 2)。根据 Kvaser Can King 的说法,该总线为 1M bit/s,并且使用了大约 29% 的总线。问题是当我向嵌入式设备发送特定数据的请求时,在显示在我的 gui 上之前会有大约 10 到 15 秒的长时间延迟。延迟开始很小,如果我在启动时请求数据,它只有大约 1 秒。如果我让它静置几分钟
我写的第一个 gui 是在 python 中使用 tkinter。我发现性能是微不足道的:这意味着在我开始遇到延迟问题之前,我可以对 CAN 消息进行少量处理。我认为这是因为 python 是一种解释性语言,也许它跟不上速度太慢了。所以我用 C# 写了一个新的 gui,因为它是一种编译语言,应该运行得更快。但我遇到了同样的问题。用不同的主机、不同的嵌入式开发板和不同的 kvaser 尝试过,同样的问题。
有人知道会发生什么吗?
所以我的 python 线程方法如下所示:
def can_thread():
global finished
global can_log_name
global temp_log_name
global yoko_log_name
global time_last
global logging
global start_time
global TU1_active
global TU2_active
global TV1_active
global TV2_active
global TW1_active
global TW2_active
global Tcool_active
global state_dic
global printlog
global yoko_cmd
global can_timeout
global missed_messages
finished = None
start_time = time()
time_last_1Hz = time()
time_last_4Hz = time()
while not finished:
time_now = time()
elapsed_time_1Hz = time_now - time_last_1Hz
elapsed_time_4Hz = time_now - time_last_4Hz
finished = get_can_message()
if elapsed_time_1Hz > 1:
if logging == True:
if not temp_log_name == None:
tempText = str(text_time)+ "," + \
TU1_temp["text"] + "," + \
TU2_temp["text"] + "," + \
TV1_temp["text"] + "," + \
TV2_temp["text"] + "," + \
TW1_temp["text"] + "," + \
TW2_temp["text"] + "," + \
ULPF_current["text"] + "," + \
VLPF_current["text"] + "," + \
WLPF_current["text"] + "," + \
Tcool_temp["text"]
f = open(temp_log_name, "a")
f.write(tempText + "\n")
f.close
if not yoko_log_name == None:
f = open(yoko_log_name, "a")
f.write(str(text_time)+ "," + yoko_cmd)
f.close
time_last_1Hz = time_now
if elapsed_time_4Hz > 0.25:
while incoming_message_queue.qsize() > 0:
frame = incoming_message_queue.get()
if frame.id == broadcast_frame_id + get_id():
broadcast_frame(frame)
None
elif frame.id == UTA2_frame_id + get_id():
UTA2_frame(frame)
None
elif frame.id == volt_cur_pow_frame_id + get_id():
volt_curr_pwr_frame(frame)
None
elif frame.id == state_faults_frame_id + get_id():
state_faults_frame(frame)
None
else:
None
if missed_messages > 2:
can_inidicator_lbl["bg"] = "red"
can_inidicator_lbl["text"] = "CAN Timeout"
else:
can_inidicator_lbl["bg"] = "green"
can_inidicator_lbl["text"] = "CAN Traffic detected"
elapsed_time_4Hz = time_now
while outgoing_message_queue.qsize() > 0:
msg = outgoing_message_queue.get()
cn.ch.write(msg)
我的 C# Thread 方法如下所示:
private void CanThread()
{
while(m_OkToRunThread)
{
try
{
var result = m_CanMessage.ReadCanBusWithWait(m_canHandle, CAN_TIMEOUT);
if(result == Canlib.canStatus.canOK)
{
m_canTimeoutCount = 0;
m_canTimedOut = false;
CanMessageEventArgs e = new CanMessageEventArgs();
e.Message = m_CanMessage;
e.CanTimeOut = m_canTimedOut;
OnMessageReceived(e);
}
else if(result == Canlib.canStatus.canERR_NOMSG)
{
m_canTimeoutCount++;
if(m_canTimeoutCount > ALLOWED_TIMED_OUT_MESSAGES)
{
m_canTimedOut = true;
CanMessageEventArgs e = new CanMessageEventArgs();
e.Message = m_CanMessage;
e.CanTimeOut = m_canTimedOut;
OnMessageReceived(e);
}
}
else
{
m_OkToRunThread = false;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
//m_OkToRunThread = false;
}
}
}
【问题讨论】:
-
请创建一个 minimal 示例来演示问题!
-
第一篇文章已编辑以显示线程方法
-
您如何知道您的 CAN 总线设置为 1Mbps?你在上面放了一个范围吗?那将是相当有启发性的。您应该能够看到序列之间是否存在较长的延迟,或者是否真的是比特流变慢了。
-
您是否遇到错误? CAN 本来就不是高性能的,但它可以在重试的低质量连接中存活下来。
-
10-15 秒的延迟不太可能与 CAN 总线有关。我宁愿怀疑你的线程实现中存在死锁或饥饿。