fw-build.sh 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #!/bin/bash
  2. #
  3. # postbuild.sh - multi-language support script
  4. # Generate binary with secondary language.
  5. #
  6. # Input files:
  7. # $OUTDIR/Firmware.ino.elf
  8. # $OUTDIR/sketch/*.o (all object files)
  9. #
  10. # Output files:
  11. # text.sym
  12. # $PROGMEM.sym (progmem1.sym)
  13. # $PROGMEM.lss (...)
  14. # $PROGMEM.hex
  15. # $PROGMEM.chr
  16. # $PROGMEM.var
  17. # $PROGMEM.txt
  18. # textaddr.txt
  19. #
  20. #
  21. # Config:
  22. if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi
  23. if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo 'Config NG!' >&2; exit 1; fi
  24. #
  25. # Selected language:
  26. LNG=$1
  27. #if [ -z "$LNG" ]; then LNG='cz'; fi
  28. #
  29. # Params:
  30. IGNORE_MISSING_TEXT=1
  31. # List of supported languages
  32. if [ -z "$LANGUAGES" ]; then
  33. LANGUAGES="cz de es fr it pl"
  34. fi
  35. # Community languages
  36. if [ ! -z "$COMMUNITY_LANGUAGES" ]; then
  37. LANGUAGES+=" $COMMUNITY_LANGUAGES"
  38. fi
  39. echo "fw-build languages:$LANGUAGES" >&2
  40. finish()
  41. {
  42. echo
  43. if [ "$1" = "0" ]; then
  44. echo "postbuild.sh finished with success" >&2
  45. else
  46. echo "postbuild.sh finished with errors!" >&2
  47. fi
  48. case "$-" in
  49. *i*) echo "press enter key"; read ;;
  50. esac
  51. exit $1
  52. }
  53. echo "postbuild.sh started" >&2
  54. #check input files
  55. echo " checking files:" >&2
  56. if [ ! -e $OUTDIR ]; then echo " folder '$OUTDIR' not found!" >&2; finish 1; fi
  57. echo " folder OK" >&2
  58. if [ ! -e $INOELF ]; then echo " elf file '$INOELF' not found!" >&2; finish 1; fi
  59. echo " elf OK" >&2
  60. if ! ls $OBJDIR/*.o >/dev/null 2>&1; then echo " no object files in '$OBJDIR/'!" >&2; finish 1; fi
  61. echo " objects OK" >&2
  62. #run progmem.sh - examine content of progmem1
  63. echo -n " running progmem.sh..." >&2
  64. ./progmem.sh 1 2>progmem.out
  65. if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
  66. echo "OK" >&2
  67. #run textaddr.sh - map progmem addreses to text identifiers
  68. echo -n " running textaddr.sh..." >&2
  69. ./textaddr.sh 2>textaddr.out
  70. if [ $? -ne 0 ]; then echo "NG! - check progmem.out file" >&2; finish 1; fi
  71. echo "OK" >&2
  72. #check for messages declared in progmem1, but not found in lang_en.txt
  73. echo -n " checking textaddr.txt..." >&2
  74. cat textaddr.txt | grep "^TEXT NF" | sed "s/[^\"]*\"//;s/\"$//" >not_used.txt
  75. cat textaddr.txt | grep "^ADDR NF" | sed "s/[^\"]*\"//;s/\"$//" >not_tran.txt
  76. if cat textaddr.txt | grep "^ADDR NF" >/dev/null; then
  77. echo "NG! - some texts not found in lang_en.txt!"
  78. if [ $IGNORE_MISSING_TEXT -eq 0 ]; then
  79. finish 1
  80. else
  81. echo " missing text ignored!" >&2
  82. fi
  83. else
  84. echo "OK" >&2
  85. fi
  86. #extract binary file
  87. echo -n " extracting binary..." >&2
  88. $OBJCOPY -I ihex -O binary $INOHEX ./firmware.bin
  89. echo "OK" >&2
  90. #update binary file
  91. echo " updating binary:" >&2
  92. #update progmem1 id entries in binary file
  93. echo -n " primary language ids..." >&2
  94. cat textaddr.txt | grep "^ADDR OK" | cut -f3- -d' ' | sed "s/^0000/0x/" |\
  95. awk '{ id = $2 - 1; hi = int(id / 256); lo = int(id - 256 * hi); printf("%d \\\\x%02x\\\\x%02x\n", strtonum($1), lo, hi); }' |\
  96. while read addr data; do
  97. /bin/echo -n -e $data | dd of=./firmware.bin bs=1 count=2 seek=$addr conv=notrunc oflag=nonblock 2>/dev/null
  98. done
  99. echo "OK" >&2
  100. #update primary language signature in binary file
  101. echo -n " primary language signature..." >&2
  102. if [ -e lang_en.bin ]; then
  103. #find symbol _PRI_LANG_SIGNATURE in section '.text'
  104. pri_lang=$(cat text.sym | grep -E "\b_PRI_LANG_SIGNATURE\b")
  105. if [ -z "$pri_lang" ]; then echo "NG!\n symbol _PRI_LANG_SIGNATURE not found!" >&2; finish 1; fi
  106. #get pri_lang address
  107. pri_lang_addr='0x'$(echo $pri_lang | cut -f1 -d' ')
  108. #read header from primary language binary file
  109. header=$(dd if=lang_en.bin bs=1 count=16 2>/dev/null | xxd | cut -c11-49 | sed 's/\([0-9a-f][0-9a-f]\)[\ ]*/\1 /g')
  110. #read checksum and count data as 4 byte signature
  111. chscnt=$(echo $header | cut -c18-29 | sed "s/ /\\\\x/g")
  112. /bin/echo -e -n "$chscnt" |\
  113. dd of=firmware.bin bs=1 count=4 seek=$(($pri_lang_addr)) conv=notrunc 2>/dev/null
  114. echo "OK" >&2
  115. else
  116. echo "NG! - file lang_en.bin not found!" >&2;
  117. finish 1
  118. fi
  119. #convert bin to hex
  120. echo -n " converting to hex..." >&2
  121. $OBJCOPY -I binary -O ihex ./firmware.bin ./firmware.hex
  122. echo "OK" >&2
  123. #update _SEC_LANG in binary file if language is selected
  124. echo -n " secondary language data..." >&2
  125. if [ ! -z "$LNG" ]; then
  126. ./update_lang.sh $LNG 2>./update_lang.out
  127. if [ $? -ne 0 ]; then echo "NG! - check update_lang.out file" >&2; finish 1; fi
  128. echo "OK" >&2
  129. finish 0
  130. else
  131. echo "Updating languages:" >&2
  132. for lang in $LANGUAGES; do
  133. if [ -e lang_$lang.bin ]; then
  134. echo -n " $lang : " >&2
  135. ./update_lang.sh $lang 2>./update_lang_$lang.out 1>/dev/null
  136. if [ $? -eq 0 ]; then echo 'OK' >&2; else echo 'NG!' >&2; finish 1; fi
  137. fi
  138. done
  139. fi
  140. #create binary file with all languages
  141. rm -f lang.bin
  142. for lang in $LANGUAGES; do
  143. if [ -e lang_$lang.bin ]; then cat lang_$lang.bin >> lang.bin; fi
  144. done
  145. # Check that the language data doesn't exceed the reserved XFLASH space
  146. echo " checking language data size:"
  147. lang_size=$(wc -c lang.bin | cut -f1 -d' ')
  148. lang_size_pad=$(( ($lang_size+4096-1) / 4096 * 4096 ))
  149. # TODO: hard-coded! get value by preprocessing LANG_SIZE from xflash_layout.h!
  150. lang_reserved=249856
  151. echo " total size usage: $lang_size_pad ($lang_size)"
  152. echo " reserved size: $lang_reserved"
  153. if [ $lang_size_pad -gt $lang_reserved ]; then
  154. echo "NG! - language data too large" >&2
  155. finish 1
  156. fi
  157. #convert lang.bin to lang.hex
  158. echo -n " converting to hex..." >&2
  159. $OBJCOPY -I binary -O ihex ./lang.bin ./lang.hex
  160. echo "OK" >&2
  161. #append languages to hex file
  162. cat ./lang.hex >> firmware.hex
  163. finish 0