将avrdude命令作为SCons目标运行

时间:2010-11-04 04:13:47

标签: scons avr avrdude

我希望能够从SCons调用avrdude作为目标。例如,运行scons erase-device应运行avrdude命令。

我试图通过创建调用avrdude并将它们添加到环境中的Builder对象来实现此目的。

# a string forming a base avrdude command that we can just add on to in the targets
avrdude_base = 'avrdude -p ' + env['MCU'] + ' -c ' + icspdevice

# target to erase everything--flash, EEPROM, and lock bits (but not fuse bits)
erase_dev = Builder(action = avrdude_base + ' -e')
env.Append(BUILDERS = {'EraseDevice' : erase_dev})
ed = env.EraseDevice()
eda = env.Alias('erase-device', ed)
env.AlwaysBuild(eda)

# target to write the AVR fuses and lock bits
write_fuse = Builder(action = avrdude_base + ' -U lfuse:w:' + lfuse + ':m -U hfuse:w:' + hfuse + 
                    ':m -U efuse:w:' + efuse + ':m -U lock:w:' + lockbits + ':m')
env.Append(BUILDERS = {'WriteFuses' : write_fuse})
wf = env.WriteFuses()
wfa = env.Alias('write-fuses', wf)
env.AlwaysBuild(wfa)

使用此代码,scons总是退出说没有什么可做的。我认为这是因为,代码的显示方式,我没有给这些构建器(env.EraseDevice()env.WriteFuses())提供任何源文件;因此,SCons认为不需要调用它们。

这就是我接下来尝试的。我只是将现有的文件名传递给这两个构建器,以使scons满意,即使它不需要。现在的问题是,无论我是想运行scons write-fusesscons erase-flash还是其他使用avrdude的目标,scons就像我正在尝试编写保险丝一样。例如,如果我传入的文件名是 foo.hex ,那么scons现在认为它必须每次运行write-fuses目标因为scons认为'avrdude'是假设的生成一个名为 foo 的输出文件,但该文件永远不会生成。

另外,这样做意味着我必须在擦除器件或编程熔丝位之前构建hex文件,这通常是不必要的。

如何在SCons中创建不需要任何输入源且不产生任何输出的目标?

谢谢!

1 个答案:

答案 0 :(得分:1)

你说scons没有运行任何东西是正确的,因为它没有任何来源可以变成输出,但关键是scons想要生成目标而且它不认为有任何建立。

一个简单的解决方法是为erase-devicewrite-fuse命令提供虚拟目标。永远不会生成这些目标文件,因此如果scons确定需要构建此目标(因为它是在命令行中指定的或者是命令行上某些内容的依赖项),则scons将始终运行相应的{{1}命令。

我认为使用Builders会增加你不需要的额外复杂性。构建器适合创建目标映射的新源,但您实际上并不需要涉及文件。

avrdude ...

作为旁注,ed = env.Command('erase.dummy', [], avrdude_base + ' -e') ed = env.EraseDevice() env.AlwaysBuild(ed) env.Alias('erase-device', ed) ... 是查看scons计算的依赖树的好方法。如果您对scons正在做的事情感到困惑,那么查看依赖关系树可以帮助您调试模型与scons不同的地方。