如何通过缓慢的can总线进行printf风格的调试—在远程工具上使用常量字符串,而不是在嵌入式系统上

如何通过缓慢的can总线进行printf风格的调试—在远程工具上使用常量字符串,而不是在嵌入式系统上,c,embedded,printf,C,Embedded,Printf,目前,在我的嵌入式系统(用C编码)上,我有很多调试辅助打印语句,这些语句是在远程工具连接到系统时执行的,该系统可以向PC显示消息。这些语句有助于了解一般系统状态,但由于消息通过缓慢的can总线传输,我相信他们可能会堵塞管道,并在试图记录任何有用数据时造成其他问题 其基本要点是: 它类似于printf,但最终以一种特殊的消息格式从嵌入式系统通过CAN总线发送到工具。为此,我可以使用特殊调试消息替换此通用打印消息,这些消息将向其发送唯一ID,后跟变量参数(即argc/argv)。我想知道这样做是否正

目前,在我的嵌入式系统(用C编码)上,我有很多调试辅助打印语句,这些语句是在远程工具连接到系统时执行的,该系统可以向PC显示消息。这些语句有助于了解一般系统状态,但由于消息通过缓慢的can总线传输,我相信他们可能会堵塞管道,并在试图记录任何有用数据时造成其他问题

其基本要点是:

它类似于printf,但最终以一种特殊的消息格式从嵌入式系统通过CAN总线发送到工具。为此,我可以使用特殊调试消息替换此通用打印消息,这些消息将向其发送唯一ID,后跟变量参数(即argc/argv)。我想知道这样做是否正确,或者我是否错过了一颗神奇的子弹,或者我没有想到的其他事情

因此,我发现了这个问题,从我的目的出发,这个问题很好:

但是我没有把它做得像printf一样简单的限制。我可以在远程工具端维护一个字符串表(因为它是Windows可执行文件,因此不受代码大小限制)。我是该代码的唯一负责人,我更愿意在调试时尝试减轻代码大小和CAN总线通信量

因此,我目前的想法是:

printf("[%d] User command: answer call\n", (int)job);
这就变成

debug(dbgUSER_COMMAND_ANSWER_CALL, job);
dbgUSER\u命令\u应答\u调用
是可能的调试消息枚举的一部分

而远端有类似的东西

switch(messagetype)
{
case dbgUSER_COMMAND_ANSWER_CALL:
    /* retrieve an integer from the data portion of the message and put it into a variable */
    printf("[%d] User command: answer call\n", (int)avariable);
}
这是相对简单的,如果我所有的信息都是同样的格式,那就太棒了。然而,棘手的是,我的一些语句必须打印非常量字符串(例如,设备名称)

那么,我应该使调试消息的内容是1)消息类型,2)第一个参数的长度,3)参数,4)下一个参数的长度,5)参数,等等吗

还是我忽略了一些更明显或更容易的事情


谢谢

我假设您使用CAN,因为这是您已经与设备建立的连接。关于您的诊断需求,您还没有提供足够的信息,但我可以举一个例子说明我们在我工作的地方所做的工作。我们使用一个定制的构建工具来梳理我们的源代码,构建一个字符串表。我们的代码使用如下内容:

        log( LOGH(T0722T),                        //"Position"
             LOG_DOT_HEX_VALUE(i),
             LOG_TEXT(T0178T),                    //"Id"
             LOG_DOT_VALUE(uniqueId % 10000),
             0 );
这将记录一些数据,这些数据可以解码为:

H位置0.00B Id.0235

我们允许使用T0000T为我们的工具查找(或生成)唯一编号。该工具使用编译器的TXXT编号和包含有序字符串列表的文件构建枚举。每个生成生成生成一个与枚举编号匹配的字符串表。该系统还与用于生成国际化字符串的数据库系统相关联,但这与您的问题并不相关

每个元素都是短的(16位)。我们允许12位用于值,高4位用于类型和标志信息。编码数据是字符串id;它是一个信号(高/低)还是仅仅是一个事件;它是一种价值;它是十进制、十六进制、base64url;连接的(与前面的项目)或分开的

我们将数据记录在一个大的环形缓冲区中,以便在需要时进行查询。这允许系统在不受干扰的情况下运行,但如果发现问题,可以提取数据。当然,持续发送数据是可能的,如果需要的话,我建议将任何一条消息限制为一个CAN有效负载(假设您只使用一个ID,则为8个字节)。如果正确编码(假设接收方创建了时间戳),我上面提供的消息将适合一条CAN消息


我们确实能够包含任意数据(ASCII或十六进制),但我从不使用它。这通常是对原木中宝贵空间的浪费。在嵌入式环境中,日志记录始终是一种平衡。

您所有的CAN调试消息都使用相同的CAN标识符吗?@Sam:我想我们永远不会知道,我忘了问这个问题,感到非常尴尬。我道歉。正如经常发生的那样,我被工作、学校和家庭中发生的一切所淹没。所有消息都有相同的ID,是的。我认为我们主要是把这个想法放在次要位置,因为在软件开发过程中需要双重维护(如果消息必须在一边更新,那么它也必须在另一边更新)。使用直接打印ASCII的嵌入式代码,另一端的工具不需要真正了解这些消息。
        log( LOGH(T0722T),                        //"Position"
             LOG_DOT_HEX_VALUE(i),
             LOG_TEXT(T0178T),                    //"Id"
             LOG_DOT_VALUE(uniqueId % 10000),
             0 );