Implement ard-parse-boards with shell scripting instead of Perl.
Working towards dropping the dependency on Perl (which very few Windows users have), this commit implements the required functionality from ard-parse-boards in a few shell commands from within the Makefile. Fix #100
This commit is contained in:
parent
df88db2cfb
commit
87e29ea806
3 changed files with 19 additions and 294 deletions
|
@ -14,6 +14,7 @@ The following is the rough list of changes that went into different versions. I
|
|||
- Move binary sketch size verification logic inside makefile. Fix issue #54
|
||||
- Remove dependency on wait-connection-leonardo shell script. Fix issue #95
|
||||
- Add support for the Digilent chipKIT platform. (https://github.com/peplin)
|
||||
- Implement ard-parse-boards with shell scripting instead of Perl (https://github.com/peplin)
|
||||
|
||||
### 0.12.0 (2013-06-20)
|
||||
- Fix "generated_assembly" target, which got broken earlier. Fix issue #76 (https://github.com/matthijskooijman)
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#
|
||||
# We need to worry about three different sorts of file:
|
||||
#
|
||||
# 1. Things which are included in this distribution e.g. ard-parse-boards
|
||||
# 1. Things which are included in this distribution e.g. ard-reset-arduino
|
||||
# => ARDMK_DIR
|
||||
#
|
||||
# 2. Things which are always in the Arduino distribution e.g.
|
||||
|
@ -100,7 +100,7 @@
|
|||
# ARDUINO_PORT - The port where the Arduino can be found (only needed
|
||||
# when uploading)
|
||||
#
|
||||
# BOARD_TAG - The ard-parse-boards tag for the board e.g. uno or mega
|
||||
# BOARD_TAG - The tag for the board e.g. uno or mega
|
||||
# 'make show_boards' shows a list
|
||||
#
|
||||
# If you have your additional libraries relative to your source, rather
|
||||
|
@ -507,78 +507,71 @@ else
|
|||
endif
|
||||
|
||||
ifndef PARSE_BOARD
|
||||
PARSE_BOARD = $(ARDMK_PATH)/ard-parse-boards
|
||||
endif
|
||||
|
||||
ifndef PARSE_BOARD_OPTS
|
||||
PARSE_BOARD_OPTS = --boards_txt=$(BOARDS_TXT)
|
||||
# result = $(call READ_BOARD_TXT, 'boardname', 'parameter')
|
||||
PARSE_BOARD = $(shell grep $(1).$(2) $(BOARDS_TXT) | cut -d = -f 2 )
|
||||
endif
|
||||
|
||||
# If NO_CORE is set, then we don't have to parse boards.txt file
|
||||
# But the user might have to define MCU, F_CPU etc
|
||||
ifeq ($(strip $(NO_CORE)),)
|
||||
|
||||
ifndef PARSE_BOARD_CMD
|
||||
PARSE_BOARD_CMD = $(PARSE_BOARD) $(PARSE_BOARD_OPTS)
|
||||
endif
|
||||
|
||||
# Which variant ? This affects the include path
|
||||
ifndef VARIANT
|
||||
VARIANT = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) build.variant)
|
||||
VARIANT = $(call PARSE_BOARD,$(BOARD_TAG),build.variant)
|
||||
endif
|
||||
|
||||
# processor stuff
|
||||
ifndef MCU
|
||||
MCU = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) build.mcu)
|
||||
MCU = $(call PARSE_BOARD,$(BOARD_TAG),build.mcu)
|
||||
endif
|
||||
|
||||
ifndef F_CPU
|
||||
F_CPU = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) build.f_cpu)
|
||||
F_CPU = $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu)
|
||||
endif
|
||||
|
||||
ifeq ($(VARIANT),leonardo)
|
||||
# USB IDs for the Leonardo
|
||||
ifndef USB_VID
|
||||
USB_VID = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) build.vid 2>/dev/null)
|
||||
USB_VID = $(call PARSE_BOARD,$(BOARD_TAG),build.vid)
|
||||
endif
|
||||
|
||||
ifndef USB_PID
|
||||
USB_PID = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) build.pid 2>/dev/null)
|
||||
USB_PID = $(call PARSE_BOARD,$(BOARD_TAG),build.pid)
|
||||
endif
|
||||
endif
|
||||
|
||||
# normal programming info
|
||||
ifndef AVRDUDE_ARD_PROGRAMMER
|
||||
AVRDUDE_ARD_PROGRAMMER = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) upload.protocol)
|
||||
AVRDUDE_ARD_PROGRAMMER = $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol)
|
||||
endif
|
||||
|
||||
ifndef AVRDUDE_ARD_BAUDRATE
|
||||
AVRDUDE_ARD_BAUDRATE = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) upload.speed)
|
||||
AVRDUDE_ARD_BAUDRATE = $(call PARSE_BOARD,$(BOARD_TAG),upload.speed)
|
||||
endif
|
||||
|
||||
# fuses if you're using e.g. ISP
|
||||
ifndef ISP_LOCK_FUSE_PRE
|
||||
ISP_LOCK_FUSE_PRE = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) bootloader.unlock_bits)
|
||||
ISP_LOCK_FUSE_PRE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.unlock_bits)
|
||||
endif
|
||||
|
||||
ifndef ISP_HIGH_FUSE
|
||||
ISP_HIGH_FUSE = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) bootloader.high_fuses)
|
||||
ISP_HIGH_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.high_fuses)
|
||||
endif
|
||||
|
||||
ifndef ISP_LOW_FUSE
|
||||
ISP_LOW_FUSE = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) bootloader.low_fuses)
|
||||
ISP_LOW_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.low_fuses)
|
||||
endif
|
||||
|
||||
ifndef ISP_EXT_FUSE
|
||||
ISP_EXT_FUSE = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) bootloader.extended_fuses)
|
||||
ISP_EXT_FUSE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.extended_fuses)
|
||||
endif
|
||||
|
||||
ifndef ISP_LOCK_FUSE_POST
|
||||
ISP_LOCK_FUSE_POST = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) bootloader.lock_bits)
|
||||
ISP_LOCK_FUSE_POST = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.lock_bits)
|
||||
endif
|
||||
|
||||
ifndef HEX_MAXIMUM_SIZE
|
||||
HEX_MAXIMUM_SIZE = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) upload.maximum_size)
|
||||
HEX_MAXIMUM_SIZE = $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_size)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
@ -1076,7 +1069,7 @@ size: $(TARGET_HEX)
|
|||
$(call avr_size,$(TARGET_ELF),$(TARGET_HEX))
|
||||
|
||||
show_boards:
|
||||
$(PARSE_BOARD_CMD) --boards
|
||||
@cat $(BOARDS_TXT) | grep -E "^[[:alnum:]]" | cut -d . -f 1 | uniq
|
||||
|
||||
monitor:
|
||||
$(MONITOR_CMD) $(call get_arduino_port) $(MONITOR_BAUDRATE)
|
||||
|
|
|
@ -1,269 +0,0 @@
|
|||
#! /usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use YAML;
|
||||
|
||||
# TODO: If you writing an installation script or a package for the makefile,
|
||||
# then you might want to replace the below path based on the environment.
|
||||
# More discussion at https://github.com/sudar/Arduino-Makefile/issues/50
|
||||
my %Opt =
|
||||
(
|
||||
boards_txt => '/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt',
|
||||
);
|
||||
|
||||
# if the ARDUINO_DIR is defined, then use it
|
||||
if (defined $ENV{'ARDUINO_DIR'}) {
|
||||
$Opt{boards_txt} = "$ENV{'ARDUINO_DIR'}/hardware/arduino/boards.txt";
|
||||
}
|
||||
|
||||
GetOptions(\%Opt,
|
||||
"boards_txt=s", # filename of the boards.txt file
|
||||
"find!", # search for data
|
||||
"dump!", # dump the whole database
|
||||
"boards!", # dump a list of boards
|
||||
"help!",
|
||||
"info!",
|
||||
);
|
||||
|
||||
if ($Opt{help} || $Opt{info})
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
my $db = parse_boards($Opt{boards_txt});
|
||||
|
||||
if ($Opt{dump})
|
||||
{
|
||||
dump_data("$Opt{boards_txt} contains:", $db);
|
||||
}
|
||||
elsif ($Opt{find})
|
||||
{
|
||||
my @terms = @ARGV or usage();
|
||||
find_data($db, \@terms);
|
||||
}
|
||||
elsif ($Opt{boards})
|
||||
{
|
||||
dump_boards($db);
|
||||
}
|
||||
else
|
||||
{
|
||||
my $tag = shift @ARGV or usage();
|
||||
|
||||
if (my $key = shift @ARGV)
|
||||
{
|
||||
die "$key isn't defined for the $tag board, "
|
||||
unless $db->{$tag} && exists $db->{$tag}->{$key};
|
||||
|
||||
print $db->{$tag}->{$key}, "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
die "The $tag board isn't defined, "
|
||||
unless $db->{$tag};
|
||||
|
||||
dump_data("The $tag board:", $db->{$tag});
|
||||
}
|
||||
}
|
||||
|
||||
## here endeth the main
|
||||
|
||||
sub usage
|
||||
{
|
||||
pod2usage(-verbose => 2);
|
||||
}
|
||||
|
||||
# return HoH: {board}->{field} = value
|
||||
sub parse_boards
|
||||
{
|
||||
my $filename = shift;
|
||||
|
||||
my %b;
|
||||
|
||||
open(my $fh, '<', $filename)
|
||||
or die "Can't open $filename, ";
|
||||
|
||||
while(<$fh>)
|
||||
{
|
||||
my ($board, $key, $value) = /^\s*(\S+?)\.(\S+?)\s*=\s*(.+?)\s*$/
|
||||
or next;
|
||||
|
||||
$b{$board}->{$key} = $value;
|
||||
}
|
||||
|
||||
return \%b;
|
||||
}
|
||||
|
||||
# A rudimentary search engine
|
||||
sub find_data
|
||||
{
|
||||
my ($db, $term_list) = @_;
|
||||
|
||||
my @q = map { qr/$_/i } @$term_list;
|
||||
my $q = join(' && ', map { "/$_/i" } @$term_list);
|
||||
|
||||
my %hit;
|
||||
foreach my $b (keys %$db)
|
||||
{
|
||||
foreach my $k (keys %{$db->{$b}})
|
||||
{
|
||||
my $v = $db->{$b}->{$k};
|
||||
$hit{$b}->{$k} = $v if !grep { $v !~ /$_/i } @q;
|
||||
}
|
||||
}
|
||||
|
||||
dump_data("Matches for $q:", \%hit);
|
||||
}
|
||||
|
||||
# The list of boards...
|
||||
sub dump_boards
|
||||
{
|
||||
my $db = shift or return;
|
||||
|
||||
my %name;
|
||||
my $max_l = 0;
|
||||
foreach my $b (keys %$db)
|
||||
{
|
||||
$name{$b} = $db->{$b}->{name} || 'Anonymous';
|
||||
$max_l = length($b) if $max_l < length($b);
|
||||
}
|
||||
|
||||
my $fmt = sprintf("%%-%ds %%s\n", $max_l + 2);
|
||||
|
||||
printf $fmt, "Tag", "Board Name";
|
||||
foreach my $b (sort keys %name)
|
||||
{
|
||||
printf $fmt, $b, $name{$b};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# dump arbitrary data with a title
|
||||
sub dump_data
|
||||
{
|
||||
my ($title, $data) = @_;
|
||||
|
||||
print "# $title\n", Dump($data);
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ard-parse-boards - Read data from the Arduino boards.txt file
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
Dump all the data in the file:
|
||||
$ ard-parse-boards --dump
|
||||
|
||||
See which boards we know about:
|
||||
$ ard-parse-boards --boards
|
||||
|
||||
Look for a particular board...
|
||||
$ ard-parse-boards --find uno
|
||||
|
||||
...multiple terms are implicitly ANDed:
|
||||
$ ard-parse-boards --find duemil 328
|
||||
|
||||
Dump all the data for a particular board:
|
||||
$ ard-parse-boards atmega328
|
||||
|
||||
Extract a particular field:
|
||||
$ ard-parse-boards atmega328 build.f_cpu
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The Arduino software package ships with a boards.txt file which tells
|
||||
the Arduino IDE details about particular hardware. So when the user
|
||||
says he's got a shiny new Arduino Uno, boards.txt knows that it has a
|
||||
16MHz ATmega328 on it. It would be nice to access these data from the
|
||||
command line too.
|
||||
|
||||
In normal operation you simply specify the tag given to the board in
|
||||
the boards.txt file, and optionally a field name. This program then
|
||||
extracts the data to STDOUT.
|
||||
|
||||
Most boards have names which are quite unwieldy, so we always refer to
|
||||
a board by a tag, not its name. Strictly the tag is the bit before the
|
||||
first dot in the boards.txt key. You can see a list of board tags and
|
||||
names with the C<--boards> option.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item --boards_txt=[file]
|
||||
|
||||
Specify the full path to the boards.txt file.
|
||||
|
||||
=back
|
||||
|
||||
The following options all disable the normal 'lookup' operation.
|
||||
|
||||
=over
|
||||
|
||||
=item --dump
|
||||
|
||||
Dump the complete database in YAML format.
|
||||
|
||||
=item ---boards
|
||||
|
||||
Print a list of the tag and name of every board in the file.
|
||||
|
||||
=item --find [query] <query> ...
|
||||
|
||||
Find matching data. Strictly, return a list of values which match all
|
||||
of the query terms, treating each term as a case-insensitive regexp.
|
||||
|
||||
For example:
|
||||
|
||||
=over
|
||||
|
||||
=item --find 328
|
||||
|
||||
List data containing 328 (anywhere in the value).
|
||||
|
||||
=item --find due
|
||||
|
||||
List data containing 'due' (e.g. duemilanove).
|
||||
|
||||
=item --find 328 due
|
||||
|
||||
List data containing both 328 and due.
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
There are no known bugs in this application.
|
||||
|
||||
Please report problems to the author.
|
||||
|
||||
Patches are welcome.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Martin Oldfield, ex-atelier@mjo.tc
|
||||
|
||||
Thanks to Mark Sproul who suggested doing something like this to me ages ago.
|
||||
|
||||
=head1 LICENCE AND COPYRIGHT
|
||||
|
||||
Copyright (c) 2011, Martin Oldfield. All rights reserved.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
Loading…
Reference in a new issue