embed_utils 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6fb100fa932598d3d79d17397b8c9fcca8811a93
4
+ data.tar.gz: 104aa9de4713ba590a038c47b0a38d7cb13a0604
5
+ SHA512:
6
+ metadata.gz: 691ff56cca9562afd84e052afe6ec318fff1964a89eed2393df85d53013de8eb3b587c9d980948952541672202aa7ee47214213dbcd09b2a239bd0134a3a7d28
7
+ data.tar.gz: aa75664f2e402d8af277f843012122044d94daf7c53717feb945103bedbd2e2c5764098ac76c092abcbffea3d9aafb25156933949462a9e413efef6b6fd76b58
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EmbedUtils
4
+ class Board
5
+ class << self
6
+ def [] key
7
+ case key
8
+ when :uno then Board::Uno
9
+ when :micro then Board::Micro
10
+ else fail ArgumentError, "unknown board: `#{key}'"
11
+ end.new
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ class Base
18
+ def variant
19
+ :standard
20
+ end
21
+
22
+ def predefines
23
+ %w[
24
+ -DARDUINO=167
25
+ -DARDUINO_ARCH_AVR
26
+ -D__PROG_TYPES_COMPAT__
27
+ ]
28
+ end
29
+ end
30
+
31
+ class Uno < Base
32
+ def mcu
33
+ :atmega328p
34
+ end
35
+
36
+ def predefines
37
+ super + %w[
38
+ -DF_CPU=16000000L
39
+ ]
40
+ end
41
+
42
+ def avr_mcu
43
+ mcu
44
+ end
45
+
46
+ def avr_programmer
47
+ 'arduino'
48
+ end
49
+
50
+ def upload_speed
51
+ 115200
52
+ end
53
+ end
54
+
55
+ class Micro < Base
56
+ def mcu
57
+ :atmega32u4
58
+ end
59
+
60
+ def variant
61
+ :micro
62
+ end
63
+
64
+ def predefines
65
+ super + %w[
66
+ -DF_CPU=16000000L
67
+ -DUSB_VID=0x2341
68
+ -DUSB_PID=0x8037
69
+ ]
70
+ end
71
+
72
+ def avr_mcu
73
+ 'm32u4'
74
+ end
75
+
76
+ def avr_programmer
77
+ 'avr109'
78
+ end
79
+
80
+ def upload_speed
81
+ 57600
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake/tasklib'
4
+
5
+ require 'embed_utils/board'
6
+
7
+ module EmbedUtils
8
+ class RakeTask < Rake::TaskLib
9
+ BUILD_DIR = 'build'
10
+ HEX_FILE = "#{BUILD_DIR}/main.hex"
11
+ ELF_FILE = "#{BUILD_DIR}/main.elf"
12
+ LIBS_ARCHIVE = "#{BUILD_DIR}/libcore.a"
13
+
14
+ LIBRARIES = %w[arduino]
15
+ LIBRARIES_DIR = 'libraries'
16
+
17
+ SRC_DIR = 'src'
18
+ ARDUINO_DIR = '/usr/local/arduino'
19
+
20
+ CC = 'avr-gcc'
21
+ CXX = 'avr-g++'
22
+ AR = 'avr-ar'
23
+ OBJCOPY = 'avr-objcopy'
24
+ SIZE = 'avr-size'
25
+ CXXFLAGS = %w[
26
+ -std=c++11
27
+ -fno-exceptions
28
+ -fno-threadsafe-statics
29
+ ]
30
+
31
+ # FIXME: for default one, sort /dev/cuaU? by date and pick last one
32
+ PORT = ENV.fetch 'PORT', '/dev/cuaU1'
33
+
34
+ attr_reader :board
35
+ attr_accessor :libs_archive, :libraries, :src_dir, :arduino_dir, :options
36
+
37
+ def initialize
38
+ @board = Board[:uno]
39
+ @libs_archive = LIBS_ARCHIVE
40
+ @libraries = LIBRARIES
41
+ @src_dir = SRC_DIR
42
+ @arduino_dir = ARDUINO_DIR
43
+ @options = [*ENV['OPTIONS']&.split].compact
44
+ yield self if block_given?
45
+ define
46
+ end
47
+
48
+ def board= identifier
49
+ @board = Board[identifier]
50
+ end
51
+
52
+ private
53
+
54
+ def define
55
+ file HEX_FILE => ELF_FILE do |t|
56
+ sh "#{SIZE} #{ELF_FILE}"
57
+ sh "#{OBJCOPY} -O ihex -R .eeprom #{ELF_FILE} #{t.name}"
58
+ end
59
+
60
+ file ELF_FILE => [*objs, libs_archive] do |t|
61
+ sh "#{CC} #{linker_flags} -o #{t.name} #{t.prerequisites.join ' '}"
62
+ end
63
+
64
+ file libs_archive => libs_objs do |t|
65
+ sh "#{AR} rcs #{t.name} #{t.sources.join ' '}"
66
+ end
67
+
68
+ libs.each do |lib|
69
+ directory lib_build_dir lib
70
+ end
71
+
72
+ rule '.o' => [obj_to_src, *libs_build_dirs] do |t|
73
+ args = [*cpp_flags, *board.predefines, *includes, *options].compact
74
+ if t.source.pathmap('%x') == '.c'
75
+ sh "#{CC} #{args.join ' '} #{t.source} -c -o #{t.name}"
76
+ else
77
+ args += CXXFLAGS
78
+ sh "#{CXX} #{args.join ' '} #{t.source} -c -o #{t.name}"
79
+ end
80
+ end
81
+
82
+ desc 'Build the hex file'
83
+ task hex: HEX_FILE
84
+
85
+ desc 'Install program on USB board'
86
+ task install: :hex do
87
+ sh "avrdude -V -p #{board.avr_mcu} -D -c #{board.avr_programmer}" \
88
+ " -P #{PORT} -b #{board.upload_speed} -U flash:w:#{HEX_FILE}:i"
89
+ end
90
+
91
+ desc 'Remove build directory'
92
+ task :clean do
93
+ rm_rf BUILD_DIR
94
+ end
95
+ end
96
+
97
+ def objs
98
+ FileList["#{src_dir}/*.cpp"].pathmap "%{^#{src_dir},#{BUILD_DIR}}X.o"
99
+ end
100
+
101
+ def obj_to_src
102
+ -> t do
103
+ if lib = libs.find { |l| lib_objs(l).include? t }
104
+ lib_srcs(lib).find do |e|
105
+ e.pathmap("%{^#{lib_src_dir lib},#{BUILD_DIR}/#{lib}}X") == t.pathmap('%X')
106
+ end
107
+ else
108
+ t.pathmap "%{^#{BUILD_DIR},#{src_dir}}X.cpp"
109
+ end
110
+ end
111
+ end
112
+
113
+ def includes
114
+ %W[
115
+ -Iinclude
116
+ -I#{arduino_dir}/hardware/arduino/avr/cores/arduino
117
+ -I#{arduino_dir}/hardware/arduino/avr/variants/#{board.variant}
118
+ ] + libs.select { |lib| lib != 'arduino' }.map do |lib|
119
+ "-I#{lib_include_dir lib}"
120
+ end
121
+ end
122
+
123
+ def linker_flags
124
+ "-mmcu=#{board.mcu} -Wl,--gc-sections -Os"
125
+ end
126
+
127
+ def cpp_flags
128
+ %W[
129
+ -MMD -mmcu=#{board.mcu}
130
+ -Wall -ffunction-sections -fdata-sections -Os
131
+ ]
132
+ end
133
+
134
+ def libs
135
+ libraries
136
+ end
137
+
138
+ def libs_objs
139
+ libs.inject [] do |m, lib|
140
+ m + lib_objs(lib)
141
+ end
142
+ end
143
+
144
+ def libs_build_dirs
145
+ libs.map do |lib|
146
+ lib_build_dir lib
147
+ end
148
+ end
149
+
150
+ def lib_build_dir lib
151
+ "#{BUILD_DIR}/#{lib}"
152
+ end
153
+
154
+ def lib_objs lib
155
+ lib_srcs(lib).pathmap "%{^#{lib_src_dir lib},#{BUILD_DIR}/#{lib}}X.o"
156
+ end
157
+
158
+ def lib_srcs lib
159
+ [
160
+ FileList["#{lib_src_dir lib}/*.c"],
161
+ FileList["#{lib_src_dir lib}/*.cpp"],
162
+ FileList["#{lib_src_dir lib}/*.S"]
163
+ ].inject :+
164
+ end
165
+
166
+ def lib_include_dir lib
167
+ %W[
168
+ #{LIBRARIES_DIR}/#{lib}
169
+ #{arduino_dir}/libraries/#{lib}/src
170
+ #{arduino_dir}/hardware/arduino/avr/libraries/#{lib}
171
+ ].find do |lib_dir|
172
+ Dir.exist? lib_dir
173
+ end
174
+ end
175
+
176
+ def lib_src_dir lib
177
+ case lib
178
+ when 'arduino'
179
+ "#{arduino_dir}/hardware/arduino/avr/cores/arduino"
180
+ else
181
+ %W[
182
+ #{LIBRARIES_DIR}/#{lib}
183
+ #{arduino_dir}/libraries/#{lib}/src/avr
184
+ #{arduino_dir}/libraries/#{lib}/src
185
+ #{arduino_dir}/hardware/arduino/avr/libraries/#{lib}
186
+ ].find do |lib_dir|
187
+ Dir.exist? lib_dir
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: embed_utils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Thibault Jouan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: tj@a13.fr
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/embed_utils/board.rb
20
+ - lib/embed_utils/rake_task.rb
21
+ homepage: https://rubygems.org/gems/embed_utils
22
+ licenses:
23
+ - BSD-3-Clause
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.6.10
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Embed utils
45
+ test_files: []