progmem.sh 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/bin/bash
  2. #
  3. # Version 1.0.1 Build 12
  4. #
  5. # progmem.sh - multi-language support script
  6. # Examine content of progmem sections (default is progmem1).
  7. #
  8. # Input files:
  9. # $OUTDIR/Firmware.ino.elf
  10. # $OUTDIR/sketch/*.o (all object files)
  11. #
  12. # Output files:
  13. # text.sym - formated symbol listing of section '.text'
  14. # $PROGMEM.sym - formated symbol listing of section '.progmemX'
  15. # $PROGMEM.lss - disassembly listing file
  16. # $PROGMEM.hex - variables - hex
  17. # $PROGMEM.chr - variables - char escape
  18. # $PROGMEM.var - variables - strings
  19. # $PROGMEM.txt - text data only (not used)
  20. #
  21. #############################################################################
  22. # Change log:
  23. # 31 May 2018, XPila, Initial
  24. # 9 June 2020, 3d-gussner, Added version and Change log
  25. # 9 June 2020, 3d-gussner, colored output
  26. # 2 Apr. 2021, 3d-gussner, Use `git rev-list --count HEAD progmem.sh`
  27. # to get Build Nr
  28. #############################################################################
  29. #
  30. # Config:
  31. if [ -z "$CONFIG_OK" ]; then eval "$(cat config.sh)"; fi
  32. if [ -z "$OUTDIR" ]; then echo "$(tput setaf 1)variable OUTDIR not set!$(tput sgr0)" >&2; exit 1; fi
  33. if [ -z "$OBJDIR" ]; then echo "$(tput setaf 1)variable OBJDIR not set!$(tput sgr0)" >&2; exit 1; fi
  34. if [ -z "$INOELF" ]; then echo "$(tput setaf 1)variable INOELF not set!$(tput sgr0)" >&2; exit 1; fi
  35. if [ -z "$OBJDUMP" ]; then echo "$(tput setaf 1)variable OBJDUMP not set!$(tput sgr0)" >&2; exit 1; fi
  36. if [ -z "$CONFIG_OK" ] | [ $CONFIG_OK -eq 0 ]; then echo "$(tput setaf 1)Config NG!$(tput sgr0)" >&2; exit 1; fi
  37. #
  38. # Program memory used
  39. PROGMEM=progmem$1
  40. if [ -z "$1" ]; then PROGMEM=progmem1; fi
  41. #
  42. # Description of process:
  43. # 0. check input files
  44. # 1. remove output files
  45. # 2. list symbol table of section '.text' from output elf file to text.sym (sorted by address)
  46. # 3. calculate start and stop address of section '.$PROGMEM'
  47. # 4. extract string data from elf file to $PROGMEM.hex
  48. # 5. prepare string data for character check and conversion (output to $PROGMEM.chr)
  49. # 6. perform character check and conversion (output to $PROGMEM.var and $PROGMEM.txt)
  50. #
  51. echo "$(tput setaf 2)progmem.sh started$(tput sgr0)" >&2
  52. # (0)
  53. echo " progmem.sh (0) - checking input files" >&2
  54. if [ ! -e $OUTDIR ]; then echo "progmem.sh - file $(tput setaf 2)"$INOELF"$(tput sgr 0) not found!" >&2; exit 1; fi
  55. # (1)
  56. echo " progmem.sh (1) - removing output files" >&2
  57. #remove output files if exists
  58. if [ -e text.sym ]; then rm text.sym; fi
  59. if [ -e $PROGMEM.sym ]; then rm $PROGMEM.sym; fi
  60. if [ -e $PROGMEM.lss ]; then rm $PROGMEM.lss; fi
  61. if [ -e $PROGMEM.hex ]; then rm $PROGMEM.hex; fi
  62. if [ -e $PROGMEM.chr ]; then rm $PROGMEM.chr; fi
  63. if [ -e $PROGMEM.var ]; then rm $PROGMEM.var; fi
  64. if [ -e $PROGMEM.txt ]; then rm $PROGMEM.txt; fi
  65. # (2)
  66. echo " progmem.sh (2) - listing symbol table of section '.text'" >&2
  67. #list symbols from section '.text' into file text.sym (only address, size and name)
  68. #$OBJDUMP -t -j ".text" $INOELF | sort > text.sym
  69. $OBJDUMP -t -j ".text" $INOELF | tail -n +5 | grep -E "^[0-9a-f]{8} [gl] [O ]" | cut -c1-9,28-36,37- | sed "/^$/d" | sort > text.sym
  70. # (3)
  71. echo " progmem.sh (3) - calculating start and end address" >&2
  72. #calculate start addres of section ".$PROGMEM"
  73. PROGMEM_BEG=$(cat text.sym | grep "__loc_pri_start" | while read offs size name; do echo "0x"$offs; done)
  74. #calculate stop addres of section ".$PROGMEM"
  75. PROGMEM_END=$(cat text.sym | grep "__loc_pri_end" | while read offs size name; do echo "0x"$offs; done)
  76. echo " START address = "$PROGMEM_BEG >&2
  77. echo " STOP address = "$PROGMEM_END >&2
  78. # (4)
  79. echo " progmem.sh (4) - extracting string data from elf" >&2
  80. #dump $PROGMEM data in hex format, cut disassembly (keep hex data only)
  81. $OBJDUMP -D -j ".text" -w -z --start-address=$PROGMEM_BEG --stop-address=$PROGMEM_END $INOELF |\
  82. tail -n +7 | sed "s/ \t.*$//" > $PROGMEM.lss
  83. #convert $PROGMEM.lss to $PROGMEM.hex:
  84. # replace empty lines with '|' (variables separated by empty lines)
  85. # remove address from multiline variables (keep address at first variable line only)
  86. # remove '<' and '>:', remove whitespace at end of lines
  87. # remove line-endings, replace separator with '\n' (join hex data lines - each line will contain single variable)
  88. cat $PROGMEM.lss | sed -E 's/^$/|/;s/^ ....:\t//;s/[ ]*$/ /' | tr -d '\n' | tr '|' '\n' |\
  89. sed "s/^ //;s/<//;s/>:/ /;s/00 [1-9a-f][1-9a-f] $/00 /; s/ $//" > $PROGMEM.hex
  90. # (5)
  91. echo " progmem.sh (5) - preparing string data" >&2
  92. #convert $PROGMEM.hex to $PROGMEM.chr (prepare string data for character check and conversion)
  93. # replace first space with tab
  94. # replace second and third space with tab and space
  95. # replace all remaining spaces with '\x'
  96. # replace all tabs with spaces
  97. cat $PROGMEM.hex | sed 's/ /\t/;s/ /\t /;s/ /\\x/g;s/\t/ /g' > $PROGMEM.chr
  98. # (6)
  99. #convert $PROGMEM.chr to $PROGMEM.var (convert data to text)
  100. echo " progmem.sh (6) - converting string data" >&2
  101. (\
  102. echo "/bin\/echo -e \\"; \
  103. cat $PROGMEM.chr | \
  104. sed 's/ \\xff\\xff/ /;' | \
  105. sed 's/\\x22/\\\\\\x22/g;' | \
  106. sed 's/\\x1b/\\\\\\x1b/g;' | \
  107. sed 's/\\x01/\\\\\\x01/g;' | \
  108. sed 's/\\xf8/\\\\\\xf8/g;' | \
  109. sed 's/\\x0a/\\\\\\x0a/g;' | \
  110. sed 's/\\x04/\\\\\\x04/g;' | \
  111. sed 's/\\xe4/\\\\\\xe4/g;' | \
  112. sed 's/\\n/\\\\\\0a/g;' | \
  113. sed 's/\\x00$/\n/;s/^/\"/;s/$/\"\\/'; \
  114. ) | sh > $PROGMEM.var
  115. #this step can be omitted because .txt file is not used
  116. cat $PROGMEM.var | sed 's/\r/\n/g' | sed -E 's/^[0-9a-f]{8} [^ ]* //' >$PROGMEM.txt
  117. echo "$(tput setaf 2)progmem.sh finished$(tput sgr0)" >&2
  118. exit 0