在 C 中,我需要在嵌入式系统中将可变数量的字符打印为十六进制以进行调试。 由于这是调试跟踪宏的一部分,因此我想避免循环或其他printf
无法处理的逻辑。 我也不想声明任何新变量来防止海森错误问题。 输出空间也是一个问题,所以我想以十六进制转储它。
uint8_t* buffer;
uint8_t length;
MakeString(*message, &buffer, &length); //Function that puts some values in buffer and sets length
我正在寻找一个可以采用缓冲区和长度来生成以下内容的 printf:
0x1A1B1C0A02
对于 {1A,1B,1C,0A,02} 的值,长度 = 5
我知道%.*s
或%*
可以处理大小变量。 有没有办法在没有 for/while 循环的情况下做到这一点?
我过去使用过类似以下内容的东西:
void
to_hex(char *output, size_t out_len, uint8_t const *input, size_t in_len)
{
static const char digits[] = "0123456789abcdef";
if (out_len < 1) {
return;
}
--out_len; /* reserve space for that NUL terminator */
while (out_len > 1 && in_len) {
*output++ = digits[(*input & 0xF0) >> 4];
*output++ = digits[*input & 0x0F];
out_len -= 2;
++input, --in_len;
}
if (in_len) {
*output++ = digits[(*input & 0xF0) >> 4];
}
*output = ' ';
}
它使用的唯一内存是静态和常量,因此通常在BSS中分配。 如果您有内存映射输出设备,则可以简化此操作并省略输出缓冲区并直接写入内存位置。 您可以对此进行更多优化,并将其隐藏在宏后面,以便在发布版本中省略它。
我工作的系统没有printf
或sprintf
实现,所以我们通常滚动自己的十六进制转储代码。
no.
我想你可以挂一些串行端口缓冲区表情中断的东西,它从缓冲区读取一个字节并在串行端口上发出两个字节......本身没有循环。
或者做一些像这样卑鄙的事情(此示例仅对长度 0 到 10 有效)
int printbuf(unsigned char*buffer,int length)
{
#define b(x) buffer[x<length?x:0]
return printf("%02h%02h%02h%02h%02h%02h%02h%02h%02h%02h%02h"+4*(10-length)
,b(0),b(1),b(2),b(3),b(4),b(5),b(6),b(7),b(8),b(9));
#undef b
}
但是Sprintf本身包含循环...