在C中,我需要在嵌入式系统中将可变数量的字符作为十六进制打印以进行调试。由于这是调试跟踪宏的一部分,我想避免printf
无法处理的循环或其他逻辑。我也不想声明任何新变量来防止Heisenbug问题。输出空间也是一个问题,所以我想以十六进制转储它。
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循环有没有办法做到这一点?
答案 0 :(得分:2)
我过去使用过以下内容:
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 = '\0';
}
它使用的唯一内存是static和const,因此它通常在BSS中分配。如果您有内存映射输出设备,则可以简化此操作并省略输出缓冲区并直接写入内存位置。您可以对此进行更多优化并将其隐藏在宏后面,以便在发布版本中省略它。
我所使用的系统没有printf
或sprintf
实现,所以我们通常会推出自己的十六进制转储代码。
答案 1 :(得分:1)
没有
我猜你可能会挂起一些串口缓冲区中断,从缓冲区中读取一个字节并在串口上发出两个字节......没有循环本身。
或做一些像这样的事情(这个例子仅对长度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本身包含循环......