我的团队正试图控制德州仪器OMAP l138的频率。默认频率是300 MHz,我们希望以“完整”的形式将其设置为372 MHz :我们不仅希望将默认值更改为所需的值(或者至少在启动时对其进行配置),而且还希望能够在运行时更改该值。
在网上搜索如何做到这一点,我们发现了一篇文章,其中一种方法是通过"echo“命令:
echo 372000 /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed我们用这个命令做了一些测试,它运行得很好,但有一个问题:有时对这个echo命令的第一次调用会导致错误消息“在内核中除以零”:

在我的个人测试中,这个错误总是出现在对echo命令的第一次调用中。所有后来的调用都工作正常,没有错误。然后,如果我重置我的处理器并再次调用该命令,同样的问题也会发生:第一次调用导致这个错误,之后的调用没有任何问题。
所以我的问题是:是什么导致了这个问题?我该怎么解决它呢?(显然“总是输入两次”的答案不算数!)
(也可以提一下其他实时控制OMAP 1138频率的方法!)
发布于 2015-01-27 09:30:20
在我看来,你在davinci_spi_cpufreq_transition()函数中有被零除的功能。在这个函数中的某个地方(或者在davinci_spi_cpufreq_transition)中调用的某个函数中),有一个错误的除法操作,它试图除以某个变量,这个变量(在你的例子中)的值是0。这显然是错误情况,应该在代码中正确处理,但实际上并非如此。
很难说到底是哪段代码导致了这种情况,因为我不知道你使用的是哪个内核。如果你能提供到你的内核库的链接,这将会容易得多。虽然我在上游内核中找不到davinci_spi_cpufreq_transition,但我发现它是here。
drivers/spi/davinci_spi.c中似乎有davinci_spi_cpufreq_transition()函数。它调用davinci_spi_calc_clk_div() function。这里有2个除法运算。首先是:
prescale = ((clk_rate / hz) - 1);第二个是:
if (hz < (clk_rate / (prescale + 1)))其中一个可能会导致“被零除”错误。我建议你在下一种方法中通过修改davinci_spi_calc_clk_div()函数(只需添加标记为“+”的行)来跟踪哪一个是它:
static void davinci_spi_calc_clk_div(struct davinci_spi *davinci_spi)
{
struct davinci_spi_platform_data *pdata;
unsigned long clk_rate;
u32 hz, cs_num, prescale;
pdata = davinci_spi->pdata;
cs_num = davinci_spi->cs_num;
hz = davinci_spi->speed;
clk_rate = clk_get_rate(davinci_spi->clk);
+ printk(KERN_ERR "### hz = %u\n", hz);
prescale = ((clk_rate / hz) - 1);
if (prescale > 0xff)
prescale = 0xff;
+ printk("### prescale + 1 = %u\n", prescale + 1UL);
if (hz < (clk_rate / (prescale + 1)))
prescale++;
if (prescale < 2) {
pr_info("davinci SPI controller min. prescale value is 2\n");
prescale = 2;
}
clear_fmt_bits(davinci_spi->base, 0x0000ff00, cs_num);
set_fmt_bits(davinci_spi->base, prescale << 8, cs_num);
}我猜--它是"hz“变量,在你的例子中是0。如果是这样,您可能还需要向davinci_spi_setup_transfer()函数添加下一个调试行:
if (!hz)
hz = spi->max_speed_hz;
+ printk(KERN_ERR "### setup_transfer: setting speed to %u\n", hz);
davinci_spi->speed = hz;
davinci_spi->cs_num = spi->chip_select;完成所有这些修改后,重新构建内核,您可能会得到为什么会出现"div by zero“错误的线索。只需在内核引导日志中查找以"###“开头的行即可。如果您不知道下一步要做什么--附加这些调试行,我将尝试帮助您。
https://stackoverflow.com/questions/27783606
复制相似问题