Skip to content

Commit 2fb1cd6

Browse files
committed
Add Arduino framework support
Signed-off-by: Ajay Bhargav <[email protected]>
1 parent d553bbb commit 2fb1cd6

File tree

3 files changed

+261
-0
lines changed

3 files changed

+261
-0
lines changed

boards/s20gsm.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@
1414
]
1515
]
1616
},
17+
"connectivity": [
18+
"GSM",
19+
"Bluetooth",
20+
"GPS"
21+
],
1722
"frameworks": [
23+
"arduino",
1824
"siwisdk"
1925
],
2026
"name": "S20 GSM Module",

builder/framework/siwiduino.py

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# Copyright 2020 SiWi Embedded Solutions Pvt. Ltd.
2+
#
3+
# SPDX-License-Identifier: MIT
4+
#
5+
6+
"""
7+
Arduino
8+
9+
Arduino Wiring-based Framework allows writing cross-platform software to
10+
control devices attached to a wide range of Arduino boards to create all
11+
kinds of creative coding, interactive objects, spaces or physical experiences.
12+
13+
http://arduino.cc/en/Reference/HomePage
14+
"""
15+
16+
from os.path import abspath, isdir, isfile, join, dirname, getsize
17+
from os import remove
18+
from shutil import copyfile
19+
from hashlib import md5
20+
21+
from SCons.Script import DefaultEnvironment
22+
23+
env = DefaultEnvironment()
24+
platform = env.PioPlatform()
25+
board = env.BoardConfig()
26+
27+
FRAMEWORK_DIR = platform.get_package_dir("framework-siwiduino")
28+
assert isdir(FRAMEWORK_DIR)
29+
30+
def fota_crc16(data:bytearray, length):
31+
crc = 0
32+
for i in range(length):
33+
data_byte = data[i] & 0xff
34+
crc = crc ^ (data_byte << 8)
35+
for _ in range(8):
36+
if (crc & 0x8000):
37+
crc = (crc << 1) ^ 0x1021
38+
else:
39+
crc = crc << 1
40+
return crc & 0xffff
41+
42+
def gen_bin_file(target, source, env):
43+
cmd = ["$OBJCOPY"]
44+
(target_firm, ) = target
45+
(target_elf, ) = source
46+
47+
temp_firm = dirname(target_firm.get_abspath()) + "/temp.bin"
48+
cmd.extend(["-O", "binary"])
49+
cmd.append(target_elf.get_abspath())
50+
cmd.append(temp_firm)
51+
env.Execute(env.VerboseAction(" ".join(cmd), " "))
52+
53+
GFH_Header = bytearray([
54+
0x4D, 0x4D, 0x4D, 0x01, 0x40, 0x00, 0x00, 0x00,
55+
0x46, 0x49, 0x4C, 0x45, 0x5F, 0x49, 0x4E, 0x46,
56+
0x4F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
57+
0x00, 0x70, 0x07, 0x00, 0x00, 0x00, 0x2E, 0x10,
58+
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
59+
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60+
0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
61+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22,
62+
])
63+
firm_size = (getsize(temp_firm) + 64).to_bytes(4, "little")
64+
GFH_Header[0x20:0x23] = firm_size[0:3]
65+
66+
with open(target_firm.get_abspath(), "wb") as out_firm:
67+
with open(temp_firm, "rb") as in_firm:
68+
out_firm.write(GFH_Header)
69+
out_firm.write(in_firm.read())
70+
in_firm.close()
71+
out_firm.close()
72+
remove(temp_firm)
73+
74+
def gen_fota_file(target, source, env):
75+
(fota_firm, ) = target
76+
(firm_bin, ) = source
77+
# 0x1c : Filesize
78+
# 0x4c : CRC16
79+
FOTA_Header = bytearray([
80+
0x53, 0x49, 0x57, 0x49, 0x5F, 0x41, 0x50, 0x50,
81+
0x5F, 0x46, 0x4F, 0x54, 0x41, 0x5F, 0x55, 0x50,
82+
0x44, 0x41, 0x54, 0x45, 0x00, 0x00, 0x01, 0x00,
83+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84+
0x10, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
85+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
86+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
87+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
88+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
89+
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
90+
])
91+
firm_size = getsize(firm_bin.get_abspath()).to_bytes(4, "little")
92+
FOTA_Header[0x1c:0x1f] = firm_size[0:3]
93+
crc = fota_crc16(FOTA_Header, len(FOTA_Header) - 4).to_bytes(4, "little")
94+
FOTA_Header[0x4c:0x4f] = crc[0:3]
95+
hash = md5()
96+
hash.update(FOTA_Header)
97+
with open(firm_bin.get_abspath(), "rb") as in_firm:
98+
in_firm_data = in_firm.read()
99+
hash.update(in_firm_data)
100+
with open(fota_firm.get_abspath(), "wb") as out_firm:
101+
out_firm.write(FOTA_Header)
102+
out_firm.write(in_firm_data)
103+
out_firm.write(hash.digest())
104+
out_firm.close()
105+
in_firm.close()
106+
107+
# Setup ENV
108+
env.Append(
109+
ASFLAGS=["-x", "assembler-with-cpp"],
110+
111+
CCFLAGS=[
112+
"-Os", # optimize for size
113+
"-g",
114+
"-march=armv5te",
115+
"-mfloat-abi=soft",
116+
"-fmessage-length=0",
117+
"-ffunction-sections", # place each function in its own section
118+
"-fdata-sections",
119+
"-fsigned-char",
120+
"-Wall",
121+
"-mthumb",
122+
"-mthumb-interwork",
123+
],
124+
125+
CFLAGS=[
126+
"-std=gnu11",
127+
"-Wno-old-style-declaration"
128+
],
129+
130+
CXXFLAGS=[
131+
"-std=gnu++11",
132+
"-fno-rtti",
133+
"-fno-exceptions",
134+
"-fno-use-cxa-atexit",
135+
"-fno-threadsafe-statics"
136+
],
137+
138+
CPPDEFINES=[
139+
("__BUFSIZ__", "512"),
140+
("__FILENAME_MAX__", "256"),
141+
("F_CPU", "$BOARD_F_CPU"),
142+
("ARDUINO", 10813),
143+
"ARDUINO_ARCH_ARM",
144+
("ARDUINO_VARIANT", '\\"%s\\"' % env.BoardConfig().get("build.variant").replace('"', "")),
145+
("ARDUINO_BOARD", '\\"%s\\"' % env.BoardConfig().get("name").replace('"', ""))
146+
],
147+
148+
CPPPATH=[
149+
join(FRAMEWORK_DIR, "cores", "siwigsm", "siwisdk", "include"),
150+
join(FRAMEWORK_DIR, "cores", "siwigsm", "siwisdk", "include", "ril"),
151+
join(FRAMEWORK_DIR, "cores", "siwigsm")
152+
],
153+
154+
LINKFLAGS=[
155+
"-march=armv5te",
156+
"-mthumb",
157+
"-mthumb-interwork",
158+
"-mfloat-abi=soft",
159+
"-Os",
160+
"-Wl,--gc-sections,--relax",
161+
"-nostartfiles",
162+
"-nostdlib",
163+
"-nostartfiles",
164+
"-nodefaultlibs",
165+
"-u", "main",
166+
"-T", "linkerscript.ld"
167+
],
168+
169+
LIBPATH=[
170+
join(FRAMEWORK_DIR, "cores", "siwigsm", "siwisdk", "lib")
171+
],
172+
173+
LIBS=[
174+
"siwisdk",
175+
"c",
176+
"gcc",
177+
"m",
178+
"stdc++"
179+
],
180+
181+
LIBSOURCE_DIRS=[
182+
join(FRAMEWORK_DIR, "libraries")
183+
],
184+
185+
BUILDERS=dict(
186+
ElfToBin=Builder(
187+
action=env.VerboseAction(gen_bin_file, "Generating $TARGET"),
188+
suffix=".bin"
189+
),
190+
BinToFOTA=Builder(
191+
action=env.VerboseAction(gen_fota_file, "Generating FOTA firmware $TARGET"),
192+
suffix=".bin"
193+
)
194+
)
195+
)
196+
197+
if board.get("build.newlib") == "nano":
198+
env.Append(
199+
LINKFLAGS=[
200+
"--specs=nano.specs",
201+
"-u", "_printf_float",
202+
"-u", "_scanf_float",
203+
"--specs=nosys.specs",
204+
]
205+
)
206+
207+
# copy CCFLAGS to ASFLAGS (-x assembler-with-cpp mode)
208+
env.Append(ASFLAGS=env.get("CCFLAGS", [])[:])
209+
210+
def load_siwilib_debug():
211+
for i, libs in enumerate(env["LIBS"]):
212+
if libs == "siwisdk":
213+
env["LIBS"][i] = "siwisdk_debug"
214+
215+
if board.get("build.siwilib") == "debug":
216+
load_siwilib_debug()
217+
218+
if env.GetBuildType() == "debug":
219+
load_siwilib_debug()
220+
221+
#
222+
# Target: Build Core Library
223+
#
224+
225+
libs = []
226+
227+
if "build.variant" in env.BoardConfig():
228+
env.Append(
229+
CPPPATH=[
230+
join(FRAMEWORK_DIR, "variants",
231+
env.BoardConfig().get("build.variant"))
232+
]
233+
)
234+
libs.append(env.BuildLibrary(
235+
join("$BUILD_DIR", "FrameworkArduinoVariant"),
236+
join(FRAMEWORK_DIR, "variants", env.BoardConfig().get("build.variant"))
237+
))
238+
239+
envsafe = env.Clone()
240+
241+
libs.append(envsafe.BuildLibrary(
242+
join("$BUILD_DIR", "FrameworkArduino"),
243+
join(FRAMEWORK_DIR, "cores", "siwigsm")
244+
))
245+
246+
env.Prepend(LIBS=libs)

platform.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
"siwisdk": {
2121
"package": "framework-siwisdk",
2222
"script": "builder/framework/siwisdk.py"
23+
},
24+
"arduino": {
25+
"package": "framework-siwiduino",
26+
"script": "builder/framework/siwiduino.py"
2327
}
2428
},
2529
"packages": {
@@ -31,6 +35,11 @@
3135
"type": "framework",
3236
"version": "~0.4.0"
3337
},
38+
"framework-siwiduino": {
39+
"type": "framework",
40+
"optional": true,
41+
"version": "~0.3.0"
42+
},
3443
"tool-siwiflasher": {
3544
"type": "uploader",
3645
"optional": true,

0 commit comments

Comments
 (0)