本帖最后由 longger 于 2024-1-12 11:01 编辑
记一次开发踩坑
事情的起因是,我们从一家芯片厂家获取了一套代码,这套代码是厂商为推广他们的芯片提供的。这套代码要应用到我们的产品中还需要大量的修改,在我理清了这套代码逻辑后开始了修改之路。经过一顿操作,消灭了各种错误警告之后也算基本完成了。不出意外意外还是发生了,有问题!
然后到了各种排查调试的阶段,像这种编译器查不到的问题最难搞定,尤其是这套代码还是很复杂的。我排查了每一处修改,在我看来都没问题,翻来覆去查了两天。我觉得可能是某个运算逻辑被我改乱了,但是死活找不到在哪。经过苦苦挣扎我选择重新再来一次。
然后有一个函数引起了我的注意。
int32_t hall_rotor_location_interpolation(int32_t); 函数的声明↑ int32_t hall_rotor_location_interpolation(int32_t phase_pre) { float phase_diff = 0; uint16_t phase_diff_set = 10; int32_t phase_temp; phase_diff = (float)NUMBER_OF_PAIRS * hall.speed * 360 / (60 * frequency_now) * 100; if ((MC_STATE_RUNNING == state) && (hall.speed < 500)) { phase_diff = phase_diff_set; } if (DIRECTION_CW == direction) { phase_temp -= (phase_diff); } else { phase_temp += (phase_diff); } if (phase_temp > 36000) { phase_temp -= 36000; } else if (phase_temp < 0) { phase_temp += 36000; } return (phase_temp); } 函数的定义↑ 在第一修改时我发现这个函数的形参 phase_pre 并没有被使用,于是选删除了。 当我又一次看这个函数时发现了不对,这个函数没有使用 传入参数, 而是主要在使用局部变量 int32_t phase_temp; 这个变量并没有被赋予初始值,然而在后续的逻辑代码中却直接使用了这个变量,从逻辑代码中不难看出这肯定是存在问题的,因为phase_temp的值是不确定的。于是我想 这个局部变量初始值应该是传入参数的值,即int32_t phase_temp = phase_pre 于是我做了这样的修改问题也就解决了。
但是这个函数我却看不懂了,为什么局部变量初始值会等于形参的值呢?从代码上看二者没有任何联系。 hall.phase = hall_rotor_location_interpolation(hall.phase); 这是函数的调用↑ keil调试结果 我们从keil的调试结果里可以看到他们的值确实是相同的。 在这里向大佬请教一下这是什么原理。我尝试模仿但都不存在这个现象。 观察这个函数,可以看出应该这样写 int32_t phase_temp = phase_pre; 或者直接使用phase_pre 。如果说原理上作者这样的写法是可以的,那就很难不让人认为这是作者故意在挖坑。故意复杂化代码,让使用者掉尽头发,这种行为实属可恶。 如果C语言语法上不允许这样做,作者也无意这样做,只是忘了让phase_temp = phase_pre 。程序又巧合的能运行起来,这确实很搞人心态,程序开始玄学了起来。
|