armcc.exe V5.06 (750)请告诉我为什么一旦val16溢出并变得比start_count小,标记为有故障的代码就不能工作。循环不再退出。
HAL_GetTick()返回uint32_t (或int)
unsigned short start_count;
unsigned short val16;
unsigned short result;
start_count = HAL_GetTick();
//This does not work
do
{
val16 = HAL_GetTick();
result = val16 - start_count;
}
while ((val16 - start_count) < 100); //this part does not work correctly
//when val16 overflows
//This works! same code logic
do
{
val16 = HAL_GetTick();
result = val16 - start_count;
}
while (result < 100);`
发布于 2021-02-19 08:07:24
首先,不要在没有特殊需要的情况下使用较短的类型,因为这通常会增加32位RISC目标的额外开销。
第一个while不起作用,因为算术是使用int完成的,而不是无符号的短值,从而产生意外的结果:)。这里有一个演示程序:
unsigned HAL_GetTick(void)
{
static unsigned tick = 65535 - 5;
return tick++;
}
int main(void)
{
unsigned short val16;
unsigned short result;
unsigned short start_count;
start_count = HAL_GetTick();
//This does not work
do
{
val16 = HAL_GetTick();
result = val16 - start_count;
printf("%d %d\n", (val16 - start_count) < 100, (val16 - start_count));
}
while ((val16 - start_count) < 100); //this part does not work correctly
//when val16 overflows
//This works! same code logic
do
{
val16 = HAL_GetTick();
result = val16 - start_count;
}
while (result < 100);
}第二个循环使用无符号短类型,并且在计算result时不会隐式转换该类型。
现在,使用ARM Cortex内核的非本机整数的问题。
示例程序:
volatile uint32_t tick;
uint32_t HAL_GetTick(void)
{
return tick;
}
void foo(void)
{
unsigned short val16;
unsigned short result;
unsigned short start_count;
start_count = HAL_GetTick();
//This works! same code logic
do
{
val16 = HAL_GetTick();
result = val16 - start_count;
}
while (result < 100);
}
void bar(void)
{
uint32_t val16;
uint32_t result;
uint32_t start_count;
start_count = HAL_GetTick();
//This works! same code logic
do
{
val16 = HAL_GetTick();
result = val16 - start_count;
}
while (result < 100);
}以及生成的代码:
foo:
ldr r1, .L9
ldr r2, [r1]
lsl r2, r2, #16
lsr r2, r2, #16
.L6:
ldr r3, [r1]
sub r3, r3, r2
lsl r3, r3, #16
lsr r3, r3, #16
cmp r3, #99
bls .L6
bx lr
.L9:
.word tick
bar:
ldr r2, .L15
ldr r1, [r2]
.L12:
ldr r3, [r2]
sub r3, r3, r1
cmp r3, #99
bls .L12
bx lr
.L15:
.word tick正如您所看到的,使用16位整数的版本比使用32位本机大小整数的版本效率要低。
https://stackoverflow.com/questions/66269808
复制相似问题