New ML support

lang_en.txt - fix missing empty line
progmem.sh, postbuild.sh - improved
textaddr.sh, update_lang.sh - new files
This commit is contained in:
Robert Pelnar 2018-05-26 21:24:42 +02:00
parent 1f7324ea9a
commit b8075e1132
5 changed files with 251 additions and 96 deletions

View File

@ -639,6 +639,7 @@
#MSG_SELFTEST_PLEASECHECK c=0 r=0 #MSG_SELFTEST_PLEASECHECK c=0 r=0
"Please check :" "Please check :"
#MSG_WIZARD_CALIBRATION_FAILED c=20 r=8 #MSG_WIZARD_CALIBRATION_FAILED c=20 r=8
"Please check our handbook and fix the problem. Then resume the Wizard by rebooting the printer." "Please check our handbook and fix the problem. Then resume the Wizard by rebooting the printer."

View File

@ -1,5 +1,20 @@
#!/bin/sh #!/bin/sh
# postbuild.sh # postbuild.sh - multi-language support high-level script
# for generating binary with secondary language
#
# Input files:
# $OUTDIR/Firmware.ino.elf
# $OUTDIR/sketch/*.o (all object files)
#
# Output files:
# text.sym
# $PROGMEM.sym (progmem1.sym)
# $PROGMEM.lss (...)
# $PROGMEM.dat
# $PROGMEM.chr
# $PROGMEM.var
# $PROGMEM.txt
# textaddr.txt
# #
# Output folder and elf file: # Output folder and elf file:
OUTDIR="../../output" OUTDIR="../../output"
@ -7,93 +22,85 @@ OUTELF="$OUTDIR/Firmware.ino.elf"
# #
# AVR gcc tools used: # AVR gcc tools used:
OBJCOPY=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objcopy.exe OBJCOPY=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objcopy.exe
#
# Selected language:
LANG=$1
#if [ -z "$LANG" ]; then LANG='cz'; fi
function finish function finish
{ {
echo echo
echo "postbuild.sh finished... press enter key" if [ "$1" == "0" ]; then
read echo "postbuild.sh finished with success" >&2
exit else
echo "postbuild.sh finished with errors!" >&2
fi
case "$-" in
*i*) echo "press enter key"; read ;;
esac
exit $1
} }
echo "postbuild.sh started..." echo "postbuild.sh started" >&2
#check input files #check input files
echo " checking files:" echo " checking files:" >&2
if [ ! -e $OUTDIR ]; then echo " folder '$OUTDIR' not found!"; finish; fi if [ ! -e $OUTDIR ]; then echo " folder '$OUTDIR' not found!" >&2; finish 1; fi
echo " folder OK" echo " folder OK" >&2
if [ ! -e $OUTELF ]; then echo " elf file '$OUTELF' not found!"; finish; fi if [ ! -e $OUTELF ]; then echo " elf file '$OUTELF' not found!" >&2; finish 1; fi
echo " elf OK" echo " elf OK" >&2
if ! ls $OUTDIR/sketch/*.o >/dev/null 2>&1; then echo " no object files in '$OUTDIR/sketch/'!"; finish; fi if ! ls $OUTDIR/sketch/*.o >/dev/null 2>&1; then echo " no object files in '$OUTDIR/sketch/'!" >&2; finish 1; fi
echo " objects OK" echo " objects OK" >&2
#run progmem.sh to examine content of progmem1 #run progmem.sh - examine content of progmem1
./progmem.sh 1 echo -n " running progmem.sh..." >&2
./progmem.sh 1 2>progmem.out
if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
echo "OK" >&2
#create sorted list of strings from progmem1.var and lang_en.txt #run textaddr.sh - map progmem addreses to text identifiers
#lines from progmem1.var will contain addres (8 chars) and english text echo -n " running textaddr.sh..." >&2
#lines from lang_en.txt will contain linenumber and english text ./textaddr.sh 2>textaddr.out
#after sort this will generate pairs of lines (line from progmem1 first) if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
#result of sort is compiled with simple script and stored to file textaddr.txt echo "OK" >&2
echo "compiling progmem1.var and lang_en.txt"
addr=''
text=''
(cat progmem1.var | sed -E "s/^([^ ]*) ([^ ]*) (.*)/\1 \"\3\"/";\
cat lang_en.txt | sed "/^$/d;/^#/d" | sed = | sed '{N;s/\n/ /}') |\
sort -k2 |\
sed "s/\\\/\\\\\\\/g" | while read num txt; do
if [ ${#num} -eq 8 ]; then
if [ -z "$addr" ]; then
addr=$num
else
if [ "$text" == "$txt" ]; then
addr="$addr $num"
else
echo "ADDR NF $addr $text"
addr=$num
fi
fi
text=$txt
else
if [ -z "$addr" ]; then
echo "TEXT NF $num $txt"
else
if [ "$text" == "$txt" ]; then
if [ ${#addr} -eq 8 ]; then
echo "ADDR OK $addr $num"
else
echo "$addr" | sed "s/ /\n/g" | while read ad; do
echo "ADDR OK $ad $num"
done
fi
addr=''
text=''
else
echo "TEXT NF $num $txt"
fi
fi
fi
done > textaddr.txt
#check for messages declared in progmem1, but not found in lang_en.txt #check for messages declared in progmem1, but not found in lang_en.txt
echo "checking textaddr.txt..." echo -n " checking textaddr.txt..." >&2
if cat textaddr.txt | grep "^ADDR NF"; then echo "Some strings not found in lang_en.txt!"; finish; fi if cat textaddr.txt | grep "^ADDR NF"; then echo "NG! - some strings not found in lang_en.txt!"; finish 1; fi
echo "OK" >&2
#update progmem1 id entries in binary file #update progmem1 id entries in binary file
echo "extracting binary..." echo -n " extracting binary..." >&2
$OBJCOPY -I ihex -O binary $OUTDIR/Firmware.ino.hex ./firmware.bin $OBJCOPY -I ihex -O binary $OUTDIR/Firmware.ino.hex ./firmware.bin
echo "OK" >&2
#update binary file
echo " updating binary:" >&2
#update progmem1 id entries in binary file #update progmem1 id entries in binary file
echo "updating binary..." echo -n " primary language ids..." >&2
#dd if=/dev/zero of=test.bin bs=512 count=64 2>/dev/null cat textaddr.txt | grep "^ADDR OK" | cut -f3- -d' ' | sed "s/^0000/0x/" |\
time cat textaddr.txt | grep "^ADDR OK" | cut -f3- -d' ' | sed "s/^0000/0x/" |\ awk '{ hi = int($2 / 256); lo = int($2 - 256 * hi); printf("%d \\\\x%02x\\\\x%02x\n", strtonum($1), lo, hi); }' |\
awk '{ hi = int($2 / 256); lo = int($2 - 256 * hi); printf("%d \\\\x%02x\\\\x%02x\n", strtonum($1), hi, lo); }' |\
while read addr data; do while read addr data; do
echo -n -e $data | dd of=./firmware.bin bs=1 count=2 seek=$addr conv=notrunc oflag=nonblock 2>/dev/null echo -n -e $data | dd of=./firmware.bin bs=1 count=2 seek=$addr conv=notrunc oflag=nonblock 2>/dev/null
done done
echo "OK" >&2
#update progmem1 id entries in binary file #update _SEC_LANG in binary file if language is selected
echo "converting to hex..." echo -n " secondary language data..." >&2
if [ ! -z "$LANG" ]; then
./update_lang.sh $LANG 2>./update_lang.out
if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi
echo "OK" >&2
finish 0
else
echo "skipped" >&2
fi
#convert bin to hex
echo -n " converting to hex..." >&2
$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex $OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
echo "OK" >&2
finish finish 0

View File

@ -1,19 +1,10 @@
#!/bin/sh #!/bin/sh
# # progmem.sh - multi-language support low-level script
# Multi-language support postbuild script # for examining content of progmem sections (default is progmem1)
# Description of proces:
# 0. remove output files
# 1. list symbol table of section '.text' from output elf file to text.sym (sorted by address)
# 2. list symbol table of section '.$PROGMEM' from all output object files to $PROGMEM.sym
# 3. filter only $PROGMEM symbols from text.sym and store it back to $PROGMEM.sym with absolute address
# 4. calculate start and stop address of section '.$PROGMEM'
# 5. extract string data from elf file to $PROGMEM.dat
# 6. prepare string data for character check and conversion (output to $PROGMEM.chr)
# 7. perform character check and conversion (output to $PROGMEM.var and $PROGMEM.txt)
# #
# Input files: # Input files:
# Firmware.ino.elf # $OUTDIR/Firmware.ino.elf
# *.o (all object files) # $OUTDIR/sketch/*.o (all object files)
# #
# Output files: # Output files:
# text.sym # text.sym
@ -34,11 +25,28 @@ OUTELF="$OUTDIR/Firmware.ino.elf"
# #
# AVR gcc tools used: # AVR gcc tools used:
OBJDUMP=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objdump.exe OBJDUMP=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objdump.exe
#READELF=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-readelf.exe #
#
# Description of process:
# 0. check input files
# 1. remove output files
# 2. list symbol table of section '.text' from output elf file to text.sym (sorted by address)
# 3. list symbol table of section '.$PROGMEM' from all output object files to $PROGMEM.sym
# 4. filter only $PROGMEM symbols from text.sym and store it back to $PROGMEM.sym with absolute address
# 5. calculate start and stop address of section '.$PROGMEM'
# 6. extract string data from elf file to $PROGMEM.dat
# 7. prepare string data for character check and conversion (output to $PROGMEM.chr)
# 8. perform character check and conversion (output to $PROGMEM.var and $PROGMEM.txt)
#
echo "progmem.sh started" >&2
# (0) # (0)
echo "step 0 - removing output files" echo " progmem.sh (0) - checking input files" >&2
if [ ! -e $OUTDIR ]; then echo "progmem.sh - file '$OUTELF' not found!" >&2; exit 1; fi
# (1)
echo " progmem.sh (1) - removing output files" >&2
#remove output files if exists #remove output files if exists
if [ -e text.sym ]; then rm text.sym; fi if [ -e text.sym ]; then rm text.sym; fi
if [ -e $PROGMEM.sym ]; then rm $PROGMEM.sym; fi if [ -e $PROGMEM.sym ]; then rm $PROGMEM.sym; fi
@ -49,21 +57,21 @@ if [ -e $PROGMEM.var ]; then rm $PROGMEM.var; fi
if [ -e $PROGMEM.txt ]; then rm $PROGMEM.txt; fi if [ -e $PROGMEM.txt ]; then rm $PROGMEM.txt; fi
# (1) # (1)
echo "step 1 - listing symbol table of section '.text'" echo " progmem.sh (2) - listing symbol table of section '.text'" >&2
#list symbols from section '.text' into file text.sym (only address, size and name) #list symbols from section '.text' into file text.sym (only address, size and name)
$OBJDUMP -t -j ".text" $OUTELF | tail -n +5 | grep -E "^[0-9a-f]{8} [gl] O" | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> text.sym $OBJDUMP -t -j ".text" $OUTELF | tail -n +5 | grep -E "^[0-9a-f]{8} [gl] O" | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> text.sym
# (2) # (2)
echo "step 2 - listing symbol table of section '.$PROGMEM'" echo " progmem.sh (3) - listing symbol table of section '.$PROGMEM'" >&2
#loop over all object files #loop over all object files
ls "$OUTDIR"/sketch/*.o | while read fn; do ls "$OUTDIR"/sketch/*.o | while read fn; do
echo " processing $fn" echo " processing $fn" >&2
#list symbols from section $PROGMEM (only address, size and name) #list symbols from section $PROGMEM (only address, size and name)
$OBJDUMP -t -j ".$PROGMEM" $fn | tail -n +5 | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> $PROGMEM.sym $OBJDUMP -t -j ".$PROGMEM" $fn 2>/dev/null | tail -n +5 | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> $PROGMEM.sym
done 2>/dev/null done
#exit #exit
# (3) # (3)
echo "step 3 - filtering $PROGMEM symbols" echo " progmem.sh (4) - filtering $PROGMEM symbols" >&2
#create list of $PROGMEM symbol names separated by '\|' #create list of $PROGMEM symbol names separated by '\|'
progmem=$(cut -c19- $PROGMEM.sym) progmem=$(cut -c19- $PROGMEM.sym)
progmem=$(echo $progmem | sed "s/ /\\\b\\\|\\\b/g") progmem=$(echo $progmem | sed "s/ /\\\b\\\|\\\b/g")
@ -72,16 +80,16 @@ progmem='\b'$progmem'\b'
cat text.sym | grep $progmem > $PROGMEM.sym cat text.sym | grep $progmem > $PROGMEM.sym
# (4) # (4)
echo "step 4 - calculating start and stop address" echo " progmem.sh (5) - calculating start and stop address" >&2
#calculate start addres of section ".$PROGMEM" #calculate start addres of section ".$PROGMEM"
PROGMEM_BEG=$(head -n1 $PROGMEM.sym | while read offs size name; do echo "0x"$offs; done) PROGMEM_BEG=$(head -n1 $PROGMEM.sym | while read offs size name; do echo "0x"$offs; done)
#calculate stop addres of section ".$PROGMEM" #calculate stop addres of section ".$PROGMEM"
PROGMEM_END=$(tail -n1 $PROGMEM.sym | while read offs size name; do printf "0x%x" $(("0x"$offs + "0x"$size)); done) PROGMEM_END=$(tail -n1 $PROGMEM.sym | while read offs size name; do printf "0x%x" $(("0x"$offs + "0x"$size)); done)
echo " START address = "$PROGMEM_BEG echo " START address = "$PROGMEM_BEG >&2
echo " STOP address = "$PROGMEM_END echo " STOP address = "$PROGMEM_END >&2
# (5) # (5)
echo "step 5 - extracting string data from elf" echo " progmem.sh (6) - extracting string data from elf" >&2
#dump $PROGMEM data in hex format, cut textual data (keep hex data only) #dump $PROGMEM data in hex format, cut textual data (keep hex data only)
$OBJDUMP -d -j ".text" -w -z --start-address=$PROGMEM_BEG --stop-address=$PROGMEM_END $OUTELF | cut -c1-57 > $PROGMEM.lss $OBJDUMP -d -j ".text" -w -z --start-address=$PROGMEM_BEG --stop-address=$PROGMEM_END $OUTELF | cut -c1-57 > $PROGMEM.lss
#convert $PROGMEM.lss to $PROGMEM.dat: #convert $PROGMEM.lss to $PROGMEM.dat:
@ -94,7 +102,7 @@ cat $PROGMEM.lss | tail -n +7 | sed -E 's/^$/|/;s/^........:\t/ /;s/<//g;s/>:/ /
tr -d '\n' | sed "s/[|]/\n/g" | grep $progmem > $PROGMEM.dat tr -d '\n' | sed "s/[|]/\n/g" | grep $progmem > $PROGMEM.dat
# (6) # (6)
echo "step 6 - preparing string data" echo " progmem.sh (7) - preparing string data" >&2
#convert $PROGMEM.dat to $PROGMEM.chr (prepare string data for character check and conversion) #convert $PROGMEM.dat to $PROGMEM.chr (prepare string data for character check and conversion)
# replace first space with tab # replace first space with tab
# replace second space with tab and space # replace second space with tab and space
@ -104,6 +112,7 @@ cat $PROGMEM.dat | sed 's/ /\t/;s/ /\t /;s/ /\\x/g;s/\t/ /g' > $PROGMEM.chr
# (7) # (7)
#convert $PROGMEM.chr to $PROGMEM.var (convert data to text) #convert $PROGMEM.chr to $PROGMEM.var (convert data to text)
echo " progmem.sh (8) - converting string data" >&2
cat $PROGMEM.chr | \ cat $PROGMEM.chr | \
sed 's/ \\xff\\xff/ /;' | \ sed 's/ \\xff\\xff/ /;' | \
sed 's/\\x22/\\\\\\x22/g;' | \ sed 's/\\x22/\\\\\\x22/g;' | \
@ -113,4 +122,6 @@ cat $PROGMEM.chr | \
sed 's/\\x00$/\\x0a/;s/^/printf "/;s/$/"/' | sh > $PROGMEM.var sed 's/\\x00$/\\x0a/;s/^/printf "/;s/$/"/' | sh > $PROGMEM.var
cat $PROGMEM.var | sed 's/\r/\n/g' |sed -E 's/^[0-9a-f]{8} [^ ]* //' >$PROGMEM.txt cat $PROGMEM.var | sed 's/\r/\n/g' |sed -E 's/^[0-9a-f]{8} [^ ]* //' >$PROGMEM.txt
read echo "progmem.sh finished" >&2
exit 0

68
lang/textaddr.sh Normal file
View File

@ -0,0 +1,68 @@
#!/bin/sh
# textaddr.sh - multi-language support low level script
# for compiling progmem1.var and lang_en.txt files
# to textaddr.txt file (mapping of progmem addreses to text idenifiers)
#
# Input files:
# progmem1.var
# lang_en.txt
#
# Output files:
# textaddr.txt
#
#
# Dscription of process:
# check if input files exists
# create sorted list of strings from progmem1.var and lang_en.txt
# lines from progmem1.var will contain addres (8 chars) and english text
# lines from lang_en.txt will contain linenumber and english text
# after sort this will generate pairs of lines (line from progmem1 first)
# result of sort is compiled with simple script and stored into file textaddr.txt
#
echo "textaddr.sh started" >&2
if [ ! -e progmem1.var ]; then echo 'textaddr.sh - file progmem1.var not found!' >&2; exit 1; fi
if [ ! -e lang_en.txt ]; then echo 'textaddr.sh - file lang_en.txt not found!' >&2; exit 1; fi
addr=''
text=''
(cat progmem1.var | sed -E "s/^([^ ]*) ([^ ]*) (.*)/\1 \"\3\"/";\
cat lang_en.txt | sed "/^$/d;/^#/d" | sed = | sed '{N;s/\n/ /}') |\
sort -k2 |\
sed "s/\\\/\\\\\\\/g" | while read num txt; do
if [ ${#num} -eq 8 ]; then
if [ -z "$addr" ]; then
addr=$num
else
if [ "$text" == "$txt" ]; then
addr="$addr $num"
else
echo "ADDR NF $addr $text"
addr=$num
fi
fi
text=$txt
else
if [ -z "$addr" ]; then
echo "TEXT NF $num $txt"
else
if [ "$text" == "$txt" ]; then
if [ ${#addr} -eq 8 ]; then
echo "ADDR OK $addr $num"
else
echo "$addr" | sed "s/ /\n/g" | while read ad; do
echo "ADDR OK $ad $num"
done
fi
addr=''
text=''
else
echo "TEXT NF $num $txt"
fi
fi
fi
done > textaddr.txt
echo "textaddr.sh finished" >&2
exit 0

68
lang/update_lang.sh Normal file
View File

@ -0,0 +1,68 @@
#!/bin/sh
# update_lang.sh - multi-language support low level script
# for updating secondary language in binary file
#
# AVR gcc tools used:
OBJCOPY=C:/arduino-1.6.8/hardware/tools/avr/bin/avr-objcopy.exe
#
# Selected language:
LANG=$1
if [ -z "$LANG" ]; then LANG='cz'; fi
#
function finish
{
echo
if [ "$1" == "0" ]; then
echo "update_lang.sh finished with success" >&2
else
echo "update_lang.sh finished with errors!" >&2
fi
case "$-" in
*i*) echo "press enter key"; read ;;
esac
exit $1
}
echo "update_lang.sh started" >&2
echo "selected language=$LANG" >&2
echo -n " checking files..." >&2
if [ ! -e text.sym ]; then echo "NG! file text.sym not found!" >&2; finish 1; fi
if [ ! -e lang_$LANG.bin ]; then echo "NG! file lang_$LANG.bin not found!" >&2; finish 1; fi
if [ ! -e firmware.bin ]; then echo "NG! file firmware.bin not found!" >&2; finish 1; fi
echo "OK" >&2
echo -n " checking symbols..." >&2
#find symbol _SEC_LANG in section '.text'
sec_lang=$(cat text.sym | grep -E "\b_SEC_LANG\b")
if [ -z "$sec_lang" ]; then echo "NG!\n symbol _SEC_LANG not found!" >&2; finish 1; fi
echo "OK" >&2
echo " calculating vars:" >&2
#get addres and size
sec_lang_addr='0x'$(echo $sec_lang | cut -f1 -d' ')
sec_lang_size='0x'$(echo $sec_lang | cut -f2 -d' ')
echo " sec_lang_addr =$sec_lang_addr" >&2
echo " sec_lang_size =$sec_lang_size" >&2
#calculate lang_table_addr (aligned to 256byte page)
lang_table_addr=$((256*$((($sec_lang_addr + 255) / 256))))
printf " lang_table_addr =0x%04x\n" $lang_table_addr >&2
#calculate lang_table_size
lang_table_size=$((256*$((($sec_lang_size - ($lang_table_addr - $sec_lang_addr))/256))))
printf " lang_table_size =0x%04x (=%d bytes)\n" $lang_table_size $lang_table_size >&2
#get lang_cz.bin file size
lang_file_size=$(wc -c lang_cz.bin | cut -f1 -d' ')
printf " lang_file_size =0x%04x (=%d bytes)\n" $lang_file_size $lang_file_size >&2
if [ $lang_file_size -gt $lang_table_size ]; then echo "Lanaguage binary file size too big!"; finish 1; fi
echo "updating 'firmware.bin'..." >&2
dd if=lang_cz.bin of=firmware.bin bs=1 seek=$lang_table_addr conv=notrunc 2>/dev/null
#convert bin to hex
echo "converting to hex..." >&2
$OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
finish 0