瀏覽代碼

New ML support
lang_en.txt - fix missing empty line
progmem.sh, postbuild.sh - improved
textaddr.sh, update_lang.sh - new files

Robert Pelnar 6 年之前
父節點
當前提交
b8075e1132
共有 5 個文件被更改,包括 251 次插入96 次删除
  1. 2 1
      lang/lang_en.txt
  2. 75 68
      lang/postbuild.sh
  3. 38 27
      lang/progmem.sh
  4. 68 0
      lang/textaddr.sh
  5. 68 0
      lang/update_lang.sh

+ 2 - 1
lang/lang_en.txt

@@ -638,7 +638,8 @@
 "Please clean the nozzle for calibration. Click when done."
 
 #MSG_SELFTEST_PLEASECHECK c=0 r=0
-"Please check :"	
+"Please check :"
+
 #MSG_WIZARD_CALIBRATION_FAILED c=20 r=8
 "Please check our handbook and fix the problem. Then resume the Wizard by rebooting the printer."
 

+ 75 - 68
lang/postbuild.sh

@@ -1,5 +1,20 @@
 #!/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:
 OUTDIR="../../output"
@@ -7,93 +22,85 @@ OUTELF="$OUTDIR/Firmware.ino.elf"
 #
 # 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
- echo "postbuild.sh finished... press enter key"
- read
- exit
+ if [ "$1" == "0" ]; then
+  echo "postbuild.sh finished with success" >&2
+ 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
-echo " checking files:"
-if [ ! -e $OUTDIR ]; then echo "  folder '$OUTDIR' not found!"; finish; fi
-echo "  folder OK"
-if [ ! -e $OUTELF ]; then echo "  elf file '$OUTELF' not found!"; finish; fi
-echo "  elf OK"
-if ! ls $OUTDIR/sketch/*.o >/dev/null 2>&1; then echo "  no object files in '$OUTDIR/sketch/'!"; finish; fi
-echo "  objects OK"
+echo " checking files:" >&2
+if [ ! -e $OUTDIR ]; then echo "  folder '$OUTDIR' not found!" >&2; finish 1; fi
+echo "  folder  OK" >&2
+if [ ! -e $OUTELF ]; then echo "  elf file '$OUTELF' not found!" >&2; finish 1; fi
+echo "  elf     OK" >&2
+if ! ls $OUTDIR/sketch/*.o >/dev/null 2>&1; then echo "  no object files in '$OUTDIR/sketch/'!" >&2; finish 1; fi
+echo "  objects OK" >&2
 
-#run progmem.sh to examine content of progmem1
-./progmem.sh 1
+#run progmem.sh - examine content of progmem1
+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
-#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 to file textaddr.txt
-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
+#run textaddr.sh - map progmem addreses to text identifiers
+echo -n " running textaddr.sh..." >&2
+./textaddr.sh 2>textaddr.out
+if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
+echo "OK" >&2
 
 #check for messages declared in progmem1, but not found in lang_en.txt
-echo "checking textaddr.txt..."
-if cat textaddr.txt | grep "^ADDR NF"; then echo "Some strings not found in lang_en.txt!"; finish; fi
+echo -n " checking textaddr.txt..." >&2
+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
-echo "extracting binary..."
+echo -n " extracting binary..." >&2
 $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
-echo "updating binary..."
-#dd if=/dev/zero of=test.bin bs=512 count=64 2>/dev/null
-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), hi, lo); }' |\
+echo -n "  primary language ids..." >&2
+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); }' |\
  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
  done
+echo "OK" >&2
 
-#update progmem1 id entries in binary file
-echo "converting to hex..."
+#update _SEC_LANG in binary file if language is selected
+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
+echo "OK" >&2
 
-finish
+finish 0

+ 38 - 27
lang/progmem.sh

@@ -1,19 +1,10 @@
 #!/bin/sh
-#
-# Multi-language support postbuild script
-# 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)
+# progmem.sh - multi-language support low-level script
+#  for examining content of progmem sections (default is progmem1)
 #
 # Input files:
-#  Firmware.ino.elf
-#  *.o (all object files)
+#  $OUTDIR/Firmware.ino.elf
+#  $OUTDIR/sketch/*.o (all object files)
 #
 # Output files:
 #  text.sym
@@ -34,11 +25,28 @@ OUTELF="$OUTDIR/Firmware.ino.elf"
 #
 # AVR gcc tools used:
 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)
-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
 if [ -e text.sym ]; then rm text.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
 
 # (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)
 $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)
-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
 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)
- $OBJDUMP -t -j ".$PROGMEM" $fn | tail -n +5 | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> $PROGMEM.sym
-done 2>/dev/null
+ $OBJDUMP -t -j ".$PROGMEM" $fn 2>/dev/null | tail -n +5 | cut -c1-9,28-36,37- | sed "/^$/d" | sort >> $PROGMEM.sym
+done
 #exit
 # (3)
-echo "step 3 - filtering $PROGMEM symbols"
+echo " progmem.sh (4) - filtering $PROGMEM symbols" >&2
 #create list of $PROGMEM symbol names separated by '\|'
 progmem=$(cut -c19- $PROGMEM.sym)
 progmem=$(echo $progmem | sed "s/ /\\\b\\\|\\\b/g")
@@ -72,16 +80,16 @@ progmem='\b'$progmem'\b'
 cat text.sym | grep $progmem > $PROGMEM.sym
 
 # (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"
 PROGMEM_BEG=$(head -n1 $PROGMEM.sym | while read offs size name; do echo "0x"$offs; done)
 #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)
-echo " START address = "$PROGMEM_BEG
-echo " STOP address  = "$PROGMEM_END
+echo "  START address = "$PROGMEM_BEG >&2
+echo "  STOP  address = "$PROGMEM_END >&2
 
 # (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)
 $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:
@@ -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
 
 # (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) 
 # replace first space with tab
 # 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)
 #convert $PROGMEM.chr to $PROGMEM.var (convert data to text)
+echo " progmem.sh (8) - converting string data" >&2
 cat $PROGMEM.chr | \
  sed 's/ \\xff\\xff/ /;' | \
  sed 's/\\x22/\\\\\\x22/g;' | \
@@ -113,4 +122,6 @@ cat $PROGMEM.chr | \
  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
 
-read
+echo "progmem.sh finished" >&2
+
+exit 0

+ 68 - 0
lang/textaddr.sh

@@ -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 - 0
lang/update_lang.sh

@@ -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