Update MKR 1000 WiFi Firmware
Update the firmware or loading certificates on your MKR1000 WiFi board or WiFi Shield 101
Introduction
This tutorial will guide you in the process of updating the firmware or loading certificates on your MKR1000 WiFi board or WiFi Shield 101. If the Check WiFi101 Firmware Version tells you that you may have issues because the firmware and library versions do not match, here is the solution to align them.
Goals
- How to update the firmware and loading certificates on the MKR1000 WiFi and WiFi Shield 101.
Hardware & Software Needed
- MKR1000 WiFi or WiFi Shield 101 connected to an Arduino board
- Arduino IDE (online or offline).
Note: As of Arduino IDE 2.2.0, the procedure covered in this article no longer works as described for this version. However, you can still use Arduino IDE 1.x.
Circuit
The board should be connected to the USB port of the computer ready with Arduino IDE.
Important note: The 19.6.1 firmware is only available for model B of the WINC1500, this is used in the MKR1000 board. Unfortunately, the WiFi shield 101 uses model A, which Atmel has stopped supporting, so there is no 19.6.1 firmware release for it, 19.4.4 will be the latest firmware version that is compatible.
Firmware Update Procedure
To simplify the process, we have prepared a specific sketch: this FirmwareUpdater that you must load on the host board (either the one with the shield plugged in, or the MKR1000 itself) and an easy to use plug-in available in Arduino Software (IDE) 1.6.10 onwards.
Upload the sketch and keep the board (either the one with the shield plugged in, or the MKR1000 itself) connected to the computer. Once done, open the plug-in that is available in the Tools menu.
If not is not on the list, please check that it is properly configured in the Tools menu.
To update the firmware you should choose the right type of board. You can find your model looking at the WiFi module: the first line in the sticker or the last line of the silk print on the right side of the PCB shows the microcontroller model. It can be either MR210PA or MR510PB and the last letter shows yor model accordingly.
Choose in the dropdown list the model corresponding to your unit and proceed clicking on the Update Firmware button. A bar at the bottom will show you the progress of the procedure that includes erasing, writing and verifying of the firmware. At the end you get a clear notice of the successful operation.
Certificate Uploading
With the same procedure, you may load root certificates on the WiFi module to access securely specific websites. Your board must be running the FirmwareUpdater sketch to work. The root certificates are issued by a limited number of certification authorities, but it is difficult to know which site is using which authority. To ease your life, we allow you to specify directly the URL to which you need to connect securely, leaving to us the task to download the root certificate.
The list you are building is not saved from one session to the next one. It might happen that a few websites share the same root certificate. You don't have to worry about this as we take care of it. The space available on your WiFi module to store the certificates is limited to around 10 certificates that, being issued by a limited number of authorities, should be more than enough for the average projects.
The procedure starts connecting your board (either the one with the shield plugged in, or the MKR1000 itself) to your computer and selecting it from the Tools menu of the Arduino Software (IDE). Load the FirmwareUpdater on the board and launch the WiFi 101 Firmware Updater from Tools and go to the third section of the interface.
There you find on the left an empty list and on the right the buttons to add or remove the URL from which you want to download the root certificates. The URL should be exactly the one to which you need to connect. Add all the websites' URLs needed and then proceed with the uploading process. Please remember that you erase all the existing certificates when you load a new set. Press the ''Upload Certificates to WiFi module" and wait for the confirmation message.
Programming the Board
When you load the sketch on the board, it prepares the communication between the plug-in and the WiFi chip. It opens up the communication through the serial port to the WiFi module hosted on the board. It is necessary to perform all the procedures managed by the Firmware Upgrader Plugin. Everything will be managed by the plug-in, but it is important to upload this sketch first.
The complete sketch is below:
Code
1/*2
3 FirmwareUpdate.h - Firmware Updater for WiFi101 / WINC1500.4
5 Copyright (c) 2015 Arduino LLC. All right reserved.6
7 This library is free software; you can redistribute it and/or8
9 modify it under the terms of the GNU Lesser General Public10
11 License as published by the Free Software Foundation; either12
13 version 2.1 of the License, or (at your option) any later version.14
15 This library is distributed in the hope that it will be useful,16
17 but WITHOUT ANY WARRANTY; without even the implied warranty of18
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU20
21 Lesser General Public License for more details.22
23 You should have received a copy of the GNU Lesser General Public24
25 License along with this library; if not, write to the Free Software26
27 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA28
29*/30
31#include <WiFi101.h>32#include <spi_flash/include/spi_flash.h>33
34typedef struct __attribute__((__packed__)) {35
36 uint8_t command;37
38 uint32_t address;39
40 uint32_t arg1;41
42 uint16_t payloadLength;43
44 // payloadLenght bytes of data follows...45} UartPacket;46
47static const int MAX_PAYLOAD_SIZE = 1024;48
49#define CMD_READ_FLASH 0x0150#define CMD_WRITE_FLASH 0x0251#define CMD_ERASE_FLASH 0x0352#define CMD_MAX_PAYLOAD_SIZE 0x5053#define CMD_HELLO 0x9954
55void setup() {56
57 Serial.begin(115200);58
59 nm_bsp_init();60
61 if (m2m_wifi_download_mode() != M2M_SUCCESS) {62
63 Serial.println(F("Failed to put the WiFi module in download mode"));64
65 while (true)66
67 ;68
69 }70}71
72void receivePacket(UartPacket *pkt, uint8_t *payload) {73
74 // Read command75
76 uint8_t *p = reinterpret_cast<uint8_t *>(pkt);77
78 uint16_t l = sizeof(UartPacket);79
80 while (l > 0) {81
82 int c = Serial.read();83
84 if (c == -1)85
86 continue;87
88 *p++ = c;89
90 l--;91
92 }93
94 // Convert parameters from network byte order to cpu byte order95
96 pkt->address = fromNetwork32(pkt->address);97
98 pkt->arg1 = fromNetwork32(pkt->arg1);99
100 pkt->payloadLength = fromNetwork16(pkt->payloadLength);101
102 // Read payload103
104 l = pkt->payloadLength;105
106 while (l > 0) {107
108 int c = Serial.read();109
110 if (c == -1)111
112 continue;113
114 *payload++ = c;115
116 l--;117
118 }119}120
121// Allocated statically so the compiler can tell us122// about the amount of used RAM123static UartPacket pkt;124static uint8_t payload[MAX_PAYLOAD_SIZE];125
126void loop() {127
128 receivePacket(&pkt, payload);129
130 if (pkt.command == CMD_HELLO) {131
132 if (pkt.address == 0x11223344 && pkt.arg1 == 0x55667788)133
134 Serial.print("v10000");135
136 }137
138 if (pkt.command == CMD_MAX_PAYLOAD_SIZE) {139
140 uint16_t res = toNetwork16(MAX_PAYLOAD_SIZE);141
142 Serial.write(reinterpret_cast<uint8_t *>(&res), sizeof(res));143
144 }145
146 if (pkt.command == CMD_READ_FLASH) {147
148 uint32_t address = pkt.address;149
150 uint32_t len = pkt.arg1;151
152 if (spi_flash_read(payload, address, len) != M2M_SUCCESS) {153
154 Serial.println("ER");155
156 } else {157
158 Serial.write(payload, len);159
160 Serial.print("OK");161
162 }163
164 }165
166 if (pkt.command == CMD_WRITE_FLASH) {167
168 uint32_t address = pkt.address;169
170 uint32_t len = pkt.payloadLength;171
172 if (spi_flash_write(payload, address, len) != M2M_SUCCESS) {173
174 Serial.print("ER");175
176 } else {177
178 Serial.print("OK");179
180 }181
182 }183
184 if (pkt.command == CMD_ERASE_FLASH) {185
186 uint32_t address = pkt.address;187
188 uint32_t len = pkt.arg1;189
190 if (spi_flash_erase(address, len) != M2M_SUCCESS) {191
192 Serial.print("ER");193
194 } else {195
196 Serial.print("OK");197
198 }199
200 }201}
If you are NOT opening the FirmwareUpdater from the examples available in the Arduino Software (IDE) as described in the paragraphs above and wish to copy and paste the code from this tutorial, you need to create another TAB in your sketch and add the Endianness.ino listed below.
1/*2
3 Endianness.ino - Network byte order conversion functions.4
5 Copyright (c) 2015 Arduino LLC. All right reserved.6
7 This library is free software; you can redistribute it and/or8
9 modify it under the terms of the GNU Lesser General Public10
11 License as published by the Free Software Foundation; either12
13 version 2.1 of the License, or (at your option) any later version.14
15 This library is distributed in the hope that it will be useful,16
17 but WITHOUT ANY WARRANTY; without even the implied warranty of18
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU20
21 Lesser General Public License for more details.22
23 You should have received a copy of the GNU Lesser General Public24
25 License along with this library; if not, write to the Free Software26
27 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA28
29*/30
31bool isBigEndian() {32
33 uint32_t test = 0x11223344;34
35 uint8_t *pTest = reinterpret_cast<uint8_t *>(&test);36
37 return pTest[0] == 0x11;38}39
40uint32_t fromNetwork32(uint32_t from) {41
42 static const bool be = isBigEndian();43
44 if (be) {45
46 return from;47
48 } else {49
50 uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);51
52 uint32_t to;53
54 to = pFrom[0]; to <<= 8;55
56 to |= pFrom[1]; to <<= 8;57
58 to |= pFrom[2]; to <<= 8;59
60 to |= pFrom[3];61
62 return to;63
64 }65}66
67uint16_t fromNetwork16(uint16_t from) {68
69 static bool be = isBigEndian();70
71 if (be) {72
73 return from;74
75 } else {76
77 uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);78
79 uint16_t to;80
81 to = pFrom[0]; to <<= 8;82
83 to |= pFrom[1];84
85 return to;86
87 }88}89
90uint32_t toNetwork32(uint32_t to) {91
92 return fromNetwork32(to);93}94
95uint16_t toNetwork16(uint16_t to) {96
97 return fromNetwork16(to);98}
Testing It Out
After you have uploaded the code, open the serial monitor to confirm that the update has successfully been uploaded.
Troubleshoot
If the code is not working, there are some common issues we can troubleshoot:
- You have not uploaded the sketch to the board.
- Your board is not properly configured in the Tools menu.
Conclusion
In this tutorial, we have learned how to update the firmware or loading certificates on the MKR1000 WiFi board or WiFi Shield 101.
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.