fw-build.sh 7.3 KB

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