touchgfx compilation attempt
This commit is contained in:
@ -0,0 +1,50 @@
|
||||
#!env ruby
|
||||
# Copyright (c) 2018(-2024) STMicroelectronics.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the TouchGFX 4.24.2 distribution.
|
||||
#
|
||||
# This software is licensed under terms that can be found in the LICENSE file in
|
||||
# the root directory of this software component.
|
||||
# If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
#
|
||||
###############################################################################/
|
||||
require 'fileutils'
|
||||
|
||||
###### SETUP ###############
|
||||
input = ARGV[0]
|
||||
output = ARGV[1]
|
||||
bins = Dir[input + "/bin/*.bin"]
|
||||
FileUtils.mkdir_p("#{output}/obj") #Create obj folder
|
||||
symbol_file_name = "#{output}/obj/rename_symbols.txt"
|
||||
###############################################
|
||||
|
||||
############### Process files ########################
|
||||
bins.each do |bin|
|
||||
bin_file_name = File.basename(bin)
|
||||
|
||||
puts "Generating elf32 object from binary file #{input}/bin/#{bin_file_name}..."
|
||||
`arm-none-eabi-objcopy.exe -B arm --rename-section .data=ExtFlashSection,contents,alloc,load,readonly,data -I binary -O elf32-littlearm #{input}/bin/#{bin_file_name} #{output}/obj/#{bin_file_name}.o`
|
||||
|
||||
#Rename the symbols
|
||||
output_folder_name_subst = "#{output+'/bin'}".gsub('.', '_').gsub('/', '_')
|
||||
bin_file_name_subst = File.basename(bin).gsub('.', '_').gsub('/', '_')
|
||||
str = output_folder_name_subst + "_" + bin_file_name_subst
|
||||
|
||||
content =
|
||||
"_binary_#{str}_start video_#{bin_file_name_subst}_start\n" +
|
||||
"_binary_#{str}_end video_#{bin_file_name_subst}_end\n" +
|
||||
"_binary_#{str}_size video_#{bin_file_name_subst}_size\n"
|
||||
|
||||
puts "Renaming symbols..."
|
||||
FileUtils.mkdir_p(File.dirname(symbol_file_name))
|
||||
unless File.exist?(symbol_file_name) && content == File.open(symbol_file_name, 'r') { |f| f.read() }
|
||||
File.open(symbol_file_name, 'w') { |f| f.write(content) }
|
||||
end
|
||||
|
||||
# Bulk rename using objcopy --redefine-syms
|
||||
`arm-none-eabi-objcopy.exe --redefine-syms #{output}/obj/rename_symbols.txt #{output}/obj/#{bin_file_name}.o`
|
||||
end
|
||||
|
||||
#Remove temp file
|
||||
FileUtils.rm(symbol_file_name)
|
||||
@ -0,0 +1,246 @@
|
||||
# Copyright (c) 2018(-2024) STMicroelectronics.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of the TouchGFX 4.24.2 distribution.
|
||||
#
|
||||
# This software is licensed under terms that can be found in the LICENSE file in
|
||||
# the root directory of this software component.
|
||||
# If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
#
|
||||
###############################################################################/
|
||||
require 'fileutils'
|
||||
|
||||
def root_dir
|
||||
# Get the dirname of this (videoconvert.rb) file:
|
||||
@root_dir ||= File.dirname(__FILE__)
|
||||
end
|
||||
|
||||
class Main
|
||||
def self.banner
|
||||
<<-BANNER
|
||||
Convert video files.
|
||||
|
||||
Usage: #{File.basename($0)} {root_folder} asset_folder generated_folder
|
||||
|
||||
Example: #{File.basename($0)} assets/videos generated/videos
|
||||
will process files in assets/videos and place the result in generated/videos
|
||||
|
||||
Example: #{File.basename($0)} /c/Project assets/videos generated/videos
|
||||
will process files in /c/Project/assets/videos and place the result in /c/Project/generated/videos
|
||||
BANNER
|
||||
end
|
||||
|
||||
def self.write_file(file_name, content)
|
||||
FileUtils.mkdir_p(File.dirname(file_name))
|
||||
unless File.exist?(file_name) && content == File.open(file_name, 'r') { |f| f.read() }
|
||||
puts "Generating #{file_name}"
|
||||
File.open(file_name, 'w') { |f| f.write(content) }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.bin_to_obj(bin, out_dir)
|
||||
|
||||
symbol_file_name = "#{out_dir}/obj/rename_symbols.txt"
|
||||
bin_file_name = File.basename(bin)
|
||||
|
||||
puts "Generating elf32 object from binary file #{out_dir}/bin/#{bin_file_name}..."
|
||||
`arm-none-eabi-objcopy.exe -B arm --rename-section .data=ExtFlashSection,contents,alloc,load,readonly,data -I binary -O elf32-littlearm \"#{out_dir}/bin/#{bin_file_name}\" \"#{out_dir}/obj/#{bin_file_name}.o\"`
|
||||
|
||||
#Rename the symbols
|
||||
output_folder_name_subst = "#{out_dir+'/bin'}".gsub('.', '_').gsub('/', '_')
|
||||
bin_file_name_subst = File.basename(bin).gsub('.', '_').gsub('/', '_')
|
||||
str = output_folder_name_subst + "_" + bin_file_name_subst
|
||||
|
||||
content =
|
||||
"_binary_#{str}_start video_#{bin_file_name_subst}_start\n" +
|
||||
"_binary_#{str}_end video_#{bin_file_name_subst}_end\n" +
|
||||
"_binary_#{str}_size video_#{bin_file_name_subst}_size\n"
|
||||
|
||||
puts "Renaming symbols..."
|
||||
File.open(symbol_file_name, 'w') { |f| f.write(content) }
|
||||
|
||||
# Bulk rename using objcopy --redefine-syms
|
||||
`arm-none-eabi-objcopy.exe --redefine-syms #{symbol_file_name} \"#{out_dir}/obj/#{bin_file_name}.o\"`
|
||||
|
||||
#Remove temp file
|
||||
FileUtils.rm(symbol_file_name)
|
||||
end
|
||||
|
||||
root_dir = '.'
|
||||
if ARGV.count == 3
|
||||
root_dir = ARGV.shift
|
||||
end
|
||||
|
||||
if ARGV.count != 2
|
||||
abort self.banner
|
||||
end
|
||||
|
||||
Dir.chdir(root_dir) do
|
||||
avi_dir = ARGV.shift.gsub('\\', '/')
|
||||
out_dir = ARGV.shift.gsub('\\', '/')
|
||||
bin_dir = File.join(out_dir, 'bin')
|
||||
obj_dir = File.join(out_dir, 'obj')
|
||||
avis = Dir[File.join(avi_dir, '**', '*.avi')]
|
||||
|
||||
# Create the output folder:
|
||||
FileUtils.mkdir_p(bin_dir)
|
||||
|
||||
# Create mapping from existing .avi files to the .bin files
|
||||
avi2bin = {}
|
||||
avi2obj = {}
|
||||
obj2avi = {}
|
||||
bin2avi = {}
|
||||
|
||||
avis.each do |avi|
|
||||
bin = File.join(bin_dir, File.basename(avi.gsub(/avi$/i,'bin')))
|
||||
obj = File.join(obj_dir, File.basename(avi.gsub(/avi$/i,'bin.o')))
|
||||
avi2bin[avi] = bin
|
||||
avi2obj[avi] = obj
|
||||
|
||||
if bin2avi[bin]
|
||||
abort "Duplication avi files: #{bin2avi[bin]} and #{avi}"
|
||||
end
|
||||
|
||||
bin2avi[bin] = avi
|
||||
obj2avi[obj] = avi
|
||||
end
|
||||
|
||||
# Remove bin files that have no corresponding avi file
|
||||
Dir[File.join(bin_dir, '*.bin')].each do |bin|
|
||||
if !bin2avi[bin]
|
||||
puts "Removing #{bin}"
|
||||
FileUtils.rm_f(bin)
|
||||
end
|
||||
end
|
||||
|
||||
# Remove obj files that have no corresponding avi file
|
||||
Dir[File.join(obj_dir, '*.bin.o')].each do |obj|
|
||||
if !obj2avi[obj]
|
||||
puts "Removing #{obj}"
|
||||
FileUtils.rm_f(obj)
|
||||
end
|
||||
end
|
||||
|
||||
# Now process each avi file
|
||||
avi2bin.each do |avi,bin|
|
||||
if !File.exist?(bin) || (File.mtime(avi) > File.mtime(bin))
|
||||
puts "Generating #{bin}"
|
||||
FileUtils.cp(avi, bin)
|
||||
end
|
||||
end
|
||||
|
||||
# Convert .bin to .obj
|
||||
FileUtils.mkdir_p("#{out_dir}/obj")
|
||||
avi2obj.each do |avi, obj|
|
||||
bin = avi2bin[avi]
|
||||
|
||||
if !File.exist?(obj) || (File.mtime(bin) > File.mtime(obj))
|
||||
puts "Converting #{bin} to #{obj}"
|
||||
bin_to_obj(bin, out_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Locate .ioc file
|
||||
project_file = Dir['../*.ioc'].first
|
||||
if project_file.nil? # search in next parent directory if .ioc file not found
|
||||
project_file = Dir['../../*.ioc'].first
|
||||
end
|
||||
|
||||
# Determine if keil is toolchain and structure of project
|
||||
touchgfx_folder_path = "../TouchGFX"
|
||||
toolchain_is_keil = false # Assume it is not Keil
|
||||
dual_core = false # Assume it is not dual core
|
||||
context_enabled = false # Assume not context enabled
|
||||
trust_zone = false # Assume not trust zone
|
||||
if project_file
|
||||
# From cubemx_project_selector.rb in touchgfx-cli:
|
||||
content = File.read(project_file, :encoding=>'utf-8')
|
||||
target_toolchain = content.match(/ProjectManager.TargetToolchain=([\w\s\d\.\-]+)/) || abort("Unable to parse #{File.expand_path(@project_file)}")
|
||||
toolchain = target_toolchain.captures.first
|
||||
toolchain_is_keil = toolchain.match(/MDK-ARM/) # "ProjectManager.TargetToolchain=MDK-ARM..." is Keil
|
||||
|
||||
# Determine if dual core
|
||||
# From cubemx_project_selector.rb in touchgfx-cli:
|
||||
content = File.read(project_file, :encoding=>'utf-8')
|
||||
dual_core = content.match(/Mcu.ThirdParty\d+_Instance=STMicroelectronics.X-CUBE-TOUCHGFX.\d+.\d+.\d+_M(\d+)/)
|
||||
if dual_core then
|
||||
touchgfx_folder_path = "../CM#{$1}/TouchGFX"
|
||||
end
|
||||
|
||||
# Determine if context enabled project
|
||||
# From cubemx_project_selector.rb in touchgfx-cli:
|
||||
content = File.read(project_file, :encoding=>'utf-8')
|
||||
context_enabled = content.match(/Mcu.ThirdParty\d+_Instance=STMicroelectronics.X-CUBE-TOUCHGFX.\d+.\d+.\d+_App/)
|
||||
if context_enabled then
|
||||
touchgfx_folder_path = "../../Appli/TouchGFX"
|
||||
end
|
||||
|
||||
# Determine if trust zone (non secure only) project
|
||||
# From cubemx_project_selector.rb in touchgfx-cli:
|
||||
content = File.read(project_file, :encoding=>'utf-8')
|
||||
trust_zone = content.match(/Mcu.ThirdParty\d+_Instance=STMicroelectronics.X-CUBE-TOUCHGFX.\d+.\d+.\d+_M\d+NS/)
|
||||
if trust_zone
|
||||
# match expression is for dual is also true for trust zone, so we must disable dual core
|
||||
dual_core = false
|
||||
touchgfx_folder_path = "../NonSecure/TouchGFX"
|
||||
end
|
||||
end
|
||||
|
||||
# Generate header file
|
||||
hpp_content = ""
|
||||
keil_export = ""
|
||||
keil_incbin = ""
|
||||
|
||||
avi2bin.each do |avi,bin|
|
||||
name = File.basename(bin).gsub('.', '_').gsub('/', '_')
|
||||
length = File.size(avi);
|
||||
|
||||
symbol = "video_#{name}"
|
||||
start_symbol = "#{symbol}_start"
|
||||
length_symbol = "#{symbol}_length"
|
||||
|
||||
hpp_content += "const uint32_t #{length_symbol} = #{length};\n"
|
||||
hpp_content += "#ifdef SIMULATOR\n"
|
||||
hpp_content += "extern const uint8_t* #{start_symbol};\n"
|
||||
hpp_content += "#else\n"
|
||||
hpp_content += "extern const uint8_t #{start_symbol}[];\n"
|
||||
hpp_content += "#endif\n\n"
|
||||
|
||||
keil_export += "\tEXPORT\t#{start_symbol}\n"
|
||||
keil_incbin += "\n#{start_symbol}\n\tINCBIN\t#{touchgfx_folder_path}/#{bin}\n"
|
||||
end
|
||||
|
||||
hpp_file = File.join(out_dir, 'include', 'videos', 'VideoDatabase.hpp')
|
||||
write_file(hpp_file,
|
||||
"// Generated by videoconvert. Please, do not edit!\n\n"+
|
||||
"#ifndef TOUCHGFX_VIDEODATABASE_HPP\n"+
|
||||
"#define TOUCHGFX_VIDEODATABASE_HPP\n"+
|
||||
"\n#include <touchgfx/hal/Types.hpp>\n\n"+
|
||||
hpp_content+
|
||||
"#endif // TOUCHGFX_VIDEODATABASE_HPP\n")
|
||||
|
||||
keil_path = [out_dir, 'src', 'keil', 'Videos.s']
|
||||
keil_file = File.join(keil_path)
|
||||
# Only generate Videos.s if there are video files AND we are using Keil:
|
||||
if avi2bin.empty? || !toolchain_is_keil
|
||||
# Try to remove existing Videos.s file and folder structure (if it is empty)
|
||||
begin
|
||||
FileUtils.rm(keil_file) if File.exist?(keil_file)
|
||||
keil_folder = File.join(keil_path[0...-1])
|
||||
FileUtils.rmdir(keil_folder) if File.directory?(keil_folder)
|
||||
src_folder = File.join(keil_path[0...-2])
|
||||
FileUtils.rmdir(File.join(keil_path[0...-2])) if File.directory?(src_folder);
|
||||
rescue
|
||||
end
|
||||
else
|
||||
# There are videos and we are on Keil. Generate Videos.s
|
||||
write_file(keil_file,
|
||||
"; Generated by videoconvert. Please, do not edit!\n\n"+
|
||||
"\tAREA\tExtFlashSection, DATA, READONLY\n\n"+
|
||||
keil_export+
|
||||
keil_incbin+
|
||||
"\n\tEND\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user