1

我有一个像这样的 Makefile:

baud=19200
src=dimmer
avrType=attiny13
programmerDev=/dev/ttyUSB003
programmerType=stk500v1

object:
        avr-gcc -g -DF_CPU=$(avrFreq) -Wall -Os -mmcu=$(avrType) -c -o $(src).o $(src).cpp

read:
        @for memory in calibration eeprom efuse flash fuse hfuse lfuse lock signature application apptable boot prodsig usersig; do \
                avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
        done

哪个按预期工作。当我键入make read几个文件时,从微控制器中提取。由于连接速度慢和数据量大,这可能需要一些时间,所以我认为能够只键入 会很好make read flash,但我不知道该怎么做。

当然,我可以输入类似read_flash, read_hfuse... 但我觉得它可以做得更聪明。

我还希望能够运行一个命令,该命令make read all将依次从控制器执行每个文件。

现在我是创建 Makfile 的新手,所以也许我一起走错了路。请随时解释应该如何做。

我在 Linux 上。

4

3 回答 3

2

如果您可以接受高度特定于 GNU 的 makefile(并且我认为使用可移植make的 GNU 文件比编写可移植的 makefile 要好得多),您可以很容易地实现这一点:

ALL = calibration eeprom efuse flash fuse hfuse lfuse lock signature \
      application apptable boot prodsig usersig

ifeq (read,$(firstword $(MAKECMDGOALS)))
  WANT := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
  ifneq ($(WANT),)
    $(eval $(WANT):;@:)
  endif
  UNKNOWN := $(filter-out $(ALL),$(WANT))
  ifneq ($(UNKNOWN),)
    $(error Invalid arguments: $(UNKNOWN))
  endif
endif

read-one = avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) \
        -b$(baud) -v -U $1:r:./$(avrType).$1.hex:i

.PHONY: read
read:
    $(foreach w,$(or $(WANT),$(ALL)),$(call read-one,$w) &&) :

如果命令行中的第一个参数是“读取”,这会将WANT变量设置为第一个之后的参数列表。然后它将这些名称转换为无操作目标,并使目标为每个名称read调用函数,或者如果没有指定名称。read-one$(ALL)

我经常使用它的变体,例如make print VARIABLE...,它只会打印$(VARIABLE)make help TOPIC显示有关目标的信息。

于 2012-12-14T22:12:37.507 回答
1

我会做:make flashmake hfusemake all使用以下Makefile:

baud=19200
avrType=attiny13
programmerDev=/dev/ttyUSB003
programmerType=stk500v1

all: calibration eeprom efuse flash fuse hfuse lfuse lock signature \
    application apptable boot prodsig usersig

%:
        avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) \
        -v -U $@:r:./$(avrType).$$memory.hex:i || rm ./$(avrType).$@.hex;

这可能不是可移植的 Make,但它适用于 gnu make。这不允许任何其他规则,但您可以命名此文件read并执行make -f read flash. 这将允许将其他规则放置在其他 make 文件中。

请注意,这并不是特别安全,因为它将在 avrdude 上运行make foo。要更严格地控​​制目标,您可以执行以下操作:

.SUFFIXES: .ph
.PHONY: efuse.ph eeprom.ph ...
all: efuse eeprom ...
.ph:
        avrdude ...

这样,只有被列为 PHONY 的目标才是有效目标。

于 2012-12-14T18:37:22.357 回答
1

如何使模块列表成为具有默认值的可配置列表:

LIST = calibration eeprom efuse flash fuse \
       hfuse lfuse lock signature application \
       apptable boot prodsig usersig

read:
        @for memory in $(LIST); do \
             avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) \
               -b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
        done

然后调用 make 作为make默认值,或者make LIST="eeprom efuse"只调用两个模块。

于 2012-12-14T18:55:12.157 回答