@@ -1124,8 +1124,6 @@ func compileUploadSketch(
11241124 arduinoApp * app.ArduinoApp ,
11251125 w io.Writer ,
11261126) error {
1127- const fqbn = "arduino:zephyr:unoq"
1128-
11291127 logrus .SetLevel (logrus .ErrorLevel ) // Reduce the log level of arduino-cli
11301128 srv := commands .NewArduinoCoreServer ()
11311129
@@ -1147,6 +1145,9 @@ func compileUploadSketch(
11471145 }
11481146 sketch := sketchResp .GetSketch ()
11491147 profile := sketch .GetDefaultProfile ().GetName ()
1148+ if profile == "" {
1149+ return fmt .Errorf ("sketch %q has no default profile" , sketchPath )
1150+ }
11501151 initReq := & rpc.InitRequest {
11511152 Instance : inst ,
11521153 SketchPath : sketchPath ,
@@ -1186,18 +1187,13 @@ func compileUploadSketch(
11861187
11871188 // build the sketch
11881189 server , getCompileResult := commands .CompilerServerToStreams (ctx , w , w , nil )
1189-
1190- // TODO: add build cache
11911190 compileReq := rpc.CompileRequest {
11921191 Instance : inst ,
1193- Fqbn : fqbn ,
1192+ Fqbn : "arduino:zephyr:unoq" ,
11941193 SketchPath : sketchPath ,
11951194 BuildPath : buildPath ,
11961195 Jobs : 2 ,
11971196 }
1198- if profile == "" {
1199- compileReq .Libraries = []string {sketchPath + "/../../sketch-libraries" }
1200- }
12011197
12021198 err = srv .Compile (& compileReq , server )
12031199 if err != nil {
@@ -1220,12 +1216,67 @@ func compileUploadSketch(
12201216 slog .Info ("Used library " + lib .GetName () + " (" + lib .GetVersion () + ") in " + lib .GetInstallDir ())
12211217 }
12221218
1219+ if err := uploadSketchInRam (ctx , w , srv , inst , sketchPath , buildPath ); err != nil {
1220+ slog .Warn ("failed to upload in ram mode, trying to configure the board in ram mode, and retry" , slog .String ("error" , err .Error ()))
1221+ if err := configureMicroInRamMode (ctx , w , srv , inst ); err != nil {
1222+ return err
1223+ }
1224+ return uploadSketchInRam (ctx , w , srv , inst , sketchPath , buildPath )
1225+ }
1226+ return nil
1227+ }
1228+
1229+ func uploadSketchInRam (ctx context.Context ,
1230+ w io.Writer ,
1231+ srv rpc.ArduinoCoreServiceServer ,
1232+ inst * rpc.Instance ,
1233+ sketchPath string ,
1234+ buildPath string ,
1235+ ) error {
12231236 stream , _ := commands .UploadToServerStreams (ctx , w , w )
1224- return srv .Upload (& rpc.UploadRequest {
1237+ if err := srv .Upload (& rpc.UploadRequest {
12251238 Instance : inst ,
1226- Fqbn : fqbn ,
1239+ Fqbn : "arduino:zephyr:unoq:flash_mode=ram" ,
12271240 SketchPath : sketchPath ,
12281241 ImportDir : buildPath ,
1242+ }, stream ); err != nil {
1243+ return err
1244+ }
1245+ return nil
1246+ }
1247+
1248+ // configureMicroInRamMode uploads an empty binary overing any sketch previously uploaded in flash.
1249+ // This is required to be able to upload sketches in ram mode after if there is already a sketch in flash.
1250+ func configureMicroInRamMode (
1251+ ctx context.Context ,
1252+ w io.Writer ,
1253+ srv rpc.ArduinoCoreServiceServer ,
1254+ inst * rpc.Instance ,
1255+ ) error {
1256+ emptyBinDir := paths .New ("/tmp/empty" )
1257+ _ = emptyBinDir .MkdirAll ()
1258+ defer func () { _ = emptyBinDir .RemoveAll () }()
1259+
1260+ zeros , err := os .Open ("/dev/zero" )
1261+ if err != nil {
1262+ return err
1263+ }
1264+ defer zeros .Close ()
1265+
1266+ empty , err := emptyBinDir .Join ("empty.ino.elf-zsk.bin" ).Create ()
1267+ if err != nil {
1268+ return err
1269+ }
1270+ defer empty .Close ()
1271+ if _ , err := io .CopyN (empty , zeros , 50 ); err != nil {
1272+ return err
1273+ }
1274+
1275+ stream , _ := commands .UploadToServerStreams (ctx , w , w )
1276+ return srv .Upload (& rpc.UploadRequest {
1277+ Instance : inst ,
1278+ Fqbn : "arduino:zephyr:unoq:flash_mode=flash" ,
1279+ ImportDir : emptyBinDir .String (),
12291280 }, stream )
12301281}
12311282
0 commit comments