【发布时间】:2019-06-24 10:09:30
【问题描述】:
我定义了一组全局指针来对我需要在中断中访问的数组进行一些预计算:
uint8_t *spiTxBuffers;
然后在我的 main() 中保留空间并将一些内容写入数组:
// reserve space for arrays
spiTxBuffers = (uint8_t *) calloc(max_serial*buffer_size, sizeof(uint8_t));
// precomputing arrays
uint8_t switching_config[number_cells];
for (int i=0; i <= max_serial; i++) {
decide_config(i, switching_config, number_cells);
fill_buffer(switching_config, spiTxBuffers + i * buffer_size, number_cells);
}
在使用调试器检查后,数组似乎已正确填充。
现在,当我从中断访问 spiTxBuffers 时,数组似乎充满了垃圾,随机值随每次中断触发而变化。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM2) //check if the interrupt comes from TIM2
{
uint8_t *pResult;
pResult = (uint8_t *) calloc(buffer_size, sizeof(uint8_t));
// bunch of code...
number_of_serial = round(sinus / avg_voltage);
// make sure were not assuming more serial then we have
pResult = spiTxBuffers + (number_of_serial*buffer_size);
//spi transmit...
}
}
当我在中断内定义和计算数组时,一切正常,但我只想计算一次该数组。在中断中使用数组时如何弄乱数组的任何想法?该代码在 C 语言的 STM32F4 上运行。
编辑: 在我的 normale while 循环中运行测试访问会产生相同的结果:
test = spiTxBuffers[2];
test 每个周期都有不同的值。 完全禁用中断不会改变这种效果。
禁用 DMA ADC 可以解决问题,我认为 ADC 目标的阵列太小。
【问题讨论】:
-
中断是否可以在不同的内存空间(段)中运行?您可以在中断后检查
main()中的数组。如果没问题,说明内存段有问题。 -
中断例程中的calloc - 这是“大型计算机”程序员在尝试进行uC编码时犯的最严重的错误之一。忘掉它。试着完全忘记 malloc 和朋友。
-
@PaulOgilvie 它是 STM32 uC - 没有内存段。
-
@P__J__ 对于 spiTXBuffers 我主要使用 calloc。 pResult 指针是另一回事:) 你还有什么推荐的?我已经尝试将 spiTXBuffers 初始化为全局空间中的“普通”数组。
-
在大多数情况下,在中断中调用
calloc()显然不是最佳的(甚至是不合理的)。假设堆分配器总是足够快以在中断内运行是错误的,这不是一个好主意。但除此之外,您还通过分配给pResult几行来泄漏指向堆内存的指针。这是一个错误。