bug #34302: Feature request : device configuration with parent classes
(not in original patch) * avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part- functions now duplicate the opcodes in their op-array to avoid memory leaks. * doc/avrdude.texi: Added description of part parent f git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1028 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
64b32eb829
commit
7b66c21c05
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: Added part parent rule and allow overwriting existing
|
||||
data at several places
|
||||
* avrdude.conf.in: Added description comment and m328/m328p as example
|
||||
* avrpart.c: avr_dup_mem-functions now copy buf and tags memory block
|
||||
only they are already allocated.
|
||||
* lexer.l: Added parent as valid token
|
||||
|
||||
(not in original patch)
|
||||
* avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part-
|
||||
functions now duplicate the opcodes in their op-array to avoid memory leaks.
|
||||
* doc/avrdude.texi: Added description of part parent feature
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
|
|
|
@ -138,6 +138,17 @@
|
|||
# values. If a required parameter is left empty, AVRDUDE will
|
||||
# complain.
|
||||
#
|
||||
# Parts can also inherit parameters from previously defined parts
|
||||
# using the following syntax. In this case specified integer and
|
||||
# string values override parameter values from the parent part. New
|
||||
# memory definitions are added to the definitions inherited from the
|
||||
# parent.
|
||||
#
|
||||
# part parent <id> # quoted string
|
||||
# id = <id> ; # quoted string
|
||||
# <any set of other parameters from the list above>
|
||||
# ;
|
||||
#
|
||||
# NOTES:
|
||||
# * 'devicecode' is the device code used by the STK500 (see codes
|
||||
# listed below)
|
||||
|
@ -9223,12 +9234,12 @@ part
|
|||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega328P
|
||||
# ATmega328
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "m328p";
|
||||
desc = "ATmega328P";
|
||||
id = "m328";
|
||||
desc = "ATmega328";
|
||||
has_debugwire = yes;
|
||||
flash_instr = 0xB6, 0x01, 0x11;
|
||||
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
|
||||
|
@ -9236,7 +9247,7 @@ part
|
|||
0x99, 0xF9, 0xBB, 0xAF;
|
||||
stk500_devcode = 0x86;
|
||||
# avr910_devcode = 0x;
|
||||
signature = 0x1e 0x95 0x0F;
|
||||
signature = 0x1e 0x95 0x14;
|
||||
pagel = 0xd7;
|
||||
bs2 = 0xc2;
|
||||
chip_erase_delay = 9000;
|
||||
|
@ -9410,6 +9421,12 @@ part
|
|||
;
|
||||
;
|
||||
|
||||
part parent "m328"
|
||||
id = "m328p";
|
||||
desc = "ATmega328P";
|
||||
signature = 0x1e 0x95 0x0F;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny2313
|
||||
#------------------------------------------------------------
|
||||
|
|
62
avrpart.c
62
avrpart.c
|
@ -47,6 +47,26 @@ OPCODE * avr_new_opcode(void)
|
|||
return m;
|
||||
}
|
||||
|
||||
static OPCODE * avr_dup_opcode(OPCODE * op)
|
||||
{
|
||||
OPCODE * m;
|
||||
|
||||
/* this makes life easier */
|
||||
if (op == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m = (OPCODE *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
fprintf(stderr, "avr_dup_opcode(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(m, op, sizeof(*m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* avr_set_bits()
|
||||
|
@ -248,28 +268,37 @@ int avr_initmem(AVRPART * p)
|
|||
AVRMEM * avr_dup_mem(AVRMEM * m)
|
||||
{
|
||||
AVRMEM * n;
|
||||
int i;
|
||||
|
||||
n = avr_new_memtype();
|
||||
|
||||
*n = *m;
|
||||
|
||||
n->buf = (unsigned char *)malloc(n->size);
|
||||
if (n->buf == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
if (m->buf != NULL) {
|
||||
n->buf = (unsigned char *)malloc(n->size);
|
||||
if (n->buf == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(n->buf, m->buf, n->size);
|
||||
}
|
||||
memcpy(n->buf, m->buf, n->size);
|
||||
|
||||
n->tags = (unsigned char *)malloc(n->size);
|
||||
if (n->tags == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
if (m->tags != NULL) {
|
||||
n->tags = (unsigned char *)malloc(n->size);
|
||||
if (n->tags == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(n->tags, m->tags, n->size);
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
n->op[i] = avr_dup_opcode(n->op[i]);
|
||||
}
|
||||
memcpy(n->tags, m->tags, n->size);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -398,6 +427,7 @@ AVRPART * avr_dup_part(AVRPART * d)
|
|||
AVRPART * p;
|
||||
LISTID save;
|
||||
LNODEID ln;
|
||||
int i;
|
||||
|
||||
p = avr_new_part();
|
||||
save = p->mem;
|
||||
|
@ -410,6 +440,10 @@ AVRPART * avr_dup_part(AVRPART * d)
|
|||
ladd(p->mem, avr_dup_mem(ldata(ln)));
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
p->op[i] = avr_dup_opcode(p->op[i]);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ static int pin_name;
|
|||
%token K_PAGEL
|
||||
%token K_PAR
|
||||
%token K_PARALLEL
|
||||
%token K_PARENT
|
||||
%token K_PART
|
||||
%token K_PGMLED
|
||||
%token K_PROGRAMMER
|
||||
|
@ -316,13 +317,7 @@ prog_decl :
|
|||
|
||||
|
||||
part_def :
|
||||
K_PART
|
||||
{
|
||||
current_part = avr_new_part();
|
||||
strcpy(current_part->config_file, infile);
|
||||
current_part->lineno = lineno;
|
||||
}
|
||||
part_parms
|
||||
part_decl part_parms
|
||||
{
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
@ -376,6 +371,30 @@ part_def :
|
|||
}
|
||||
;
|
||||
|
||||
part_decl :
|
||||
K_PART
|
||||
{
|
||||
current_part = avr_new_part();
|
||||
strcpy(current_part->config_file, infile);
|
||||
current_part->lineno = lineno;
|
||||
} |
|
||||
K_PART K_PARENT TKN_STRING
|
||||
{
|
||||
AVRPART * parent_part = locate_part(part_list, $3->value.string);
|
||||
if (parent_part == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: error at %s:%d: can't find parent part",
|
||||
progname, infile, lineno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_part = avr_dup_part(parent_part);
|
||||
strcpy(current_part->config_file, infile);
|
||||
current_part->lineno = lineno;
|
||||
|
||||
free_token($3);
|
||||
}
|
||||
;
|
||||
|
||||
string_list :
|
||||
TKN_STRING { ladd(string_list, $1); } |
|
||||
|
@ -632,19 +651,11 @@ part_parm :
|
|||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
if (current_part->ctl_stack_type != CTL_STACK_NONE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: "
|
||||
"control stack already defined\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_part->ctl_stack_type = CTL_STACK_PP;
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
memset(current_part->controlstack, 0, CTL_STACK_SIZE);
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < CTL_STACK_SIZE)
|
||||
|
@ -674,19 +685,11 @@ part_parm :
|
|||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
if (current_part->ctl_stack_type != CTL_STACK_NONE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: "
|
||||
"control stack already defined\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_part->ctl_stack_type = CTL_STACK_HVSP;
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
memset(current_part->controlstack, 0, CTL_STACK_SIZE);
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < CTL_STACK_SIZE)
|
||||
|
@ -719,6 +722,7 @@ part_parm :
|
|||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE);
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < FLASH_INSTR_SIZE)
|
||||
|
@ -751,6 +755,7 @@ part_parm :
|
|||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE);
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < EEPROM_INSTR_SIZE)
|
||||
|
@ -1154,9 +1159,9 @@ part_parm :
|
|||
op = avr_new_opcode();
|
||||
parse_cmdbits(op);
|
||||
if (current_part->op[opnum] != NULL) {
|
||||
fprintf(stderr,
|
||||
/*fprintf(stderr,
|
||||
"%s: warning at %s:%d: operation redefined\n",
|
||||
progname, infile, lineno);
|
||||
progname, infile, lineno);*/
|
||||
free(current_part->op[opnum]);
|
||||
}
|
||||
current_part->op[opnum] = op;
|
||||
|
@ -1281,9 +1286,9 @@ mem_spec :
|
|||
op = avr_new_opcode();
|
||||
parse_cmdbits(op);
|
||||
if (current_mem->op[opnum] != NULL) {
|
||||
fprintf(stderr,
|
||||
/*fprintf(stderr,
|
||||
"%s: warning at %s:%d: operation redefined\n",
|
||||
progname, infile, lineno);
|
||||
progname, infile, lineno);*/
|
||||
free(current_mem->op[opnum]);
|
||||
}
|
||||
current_mem->op[opnum] = op;
|
||||
|
|
|
@ -1529,13 +1529,34 @@ part
|
|||
@end smallexample
|
||||
|
||||
@menu
|
||||
* Parent Part::
|
||||
* Instruction Format::
|
||||
@end menu
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Instruction Format, , Part Definitions, Part Definitions
|
||||
@node Parent Part, Instruction Format, Part Definitions, Part Definitions
|
||||
@subsection Parent Part
|
||||
|
||||
@noindent
|
||||
Parts can also inherit parameters from previously defined parts
|
||||
using the following syntax. In this case specified integer and
|
||||
string values override parameter values from the parent part. New
|
||||
memory definitions are added to the definitions inherited from the
|
||||
parent.
|
||||
|
||||
@smallexample
|
||||
part parent <id> # quoted string
|
||||
id = <id> ; # quoted string
|
||||
<any set of other parameters from the list above>
|
||||
;
|
||||
@end smallexample
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Instruction Format, , Parent Part, Part Definitions
|
||||
@subsection Instruction Format
|
||||
|
||||
@noindent
|
||||
|
|
1
lexer.l
1
lexer.l
|
@ -177,6 +177,7 @@ paged { yylval=NULL; return K_PAGED; }
|
|||
pagel { yylval=NULL; return K_PAGEL; }
|
||||
par { yylval=NULL; return K_PAR; }
|
||||
parallel { yylval=NULL; return K_PARALLEL; }
|
||||
parent { yylval=NULL; return K_PARENT; }
|
||||
part { yylval=NULL; return K_PART; }
|
||||
pgmled { yylval=NULL; return K_PGMLED; }
|
||||
programmer { yylval=NULL; return K_PROGRAMMER; }
|
||||
|
|
Loading…
Reference in New Issue