4#include "user_app_exe.h"
15static char errbuf[80];
16static uint8_t flashloader;
17static byte flashbuf[512];
19static byte flashmode = 0;
21static uint32_t f_flags = 0;
25static void flash_start() {
26 led_indicate(LED_FLASHSTART);
28static void flash_end() {
29 led_indicate(LED_FLASHEND);
34static int comparemem(
byte *adr1,
byte *adr2,
int size) {
37 for (i = 0; i < size; i++) {
38 if (*adr1++ != *adr2++) {
45static void set_new_userapp(
int streamfd,
void *baseaddr) {
46 if (userapp_checksum_valid(baseadr)) {
47 printf(
"[flashapp] Set new userapp to %p\r\n", baseadr);
48 config_set_userapp((int32_t)baseadr);
53 if (uai->magic != 0x53435541) {
54 stream_seterror(streamfd,
"[flashapp] not setting new userapp, invalid magic %p\r\n", uai->magic);
57 uint32_t checksum = calc_crc32((
void *)uai, uai->length, 8);
59 stream_seterror(streamfd,
"[flashapp] Not setting new userapp to %p (checksum error). Calculated: %p, Expected: %p (length=%i)\r\n", baseadr, checksum, uai->checksum, uai->length);
63 baseadr = (
void *)0x08034800;
64 flash_app_close(1, 77);
66int flash_app_close(
int fd,
int reason) {
71 if (f_flags & (1 << FLASH_FLAGS_SET_LATEST_USERAPP)) {
72 set_new_userapp(fd, baseadr);
76 if (f_flags & (1 << FLASH_FLAGS_START_USERAPP)) {
79 if ((f_flags & (1 << FLASH_FLAGS_USE_DIRECT_WRITE)) == 0) {
80 mculib_flash_lock(MAIN_MCULIBHANDLE);
83 if ((f_flags == 0) || (f_flags & (1 << FLASH_FLAGS_SET_LATEST_APP))) {
84 if (flashloader == 0) {
86 if (ah->magic == 0x53434657) {
87 set_latest_app(baseadr);
94 printf(
"[flashapp] Flash closed (fd=%i,reason=%i,flags=%i)\r\n", fd, reason, f_flags);
114 if (header->base != ((uint32_t)baseadr)) {
115 stream_seterror(streamfd,
"[flashapp] Base mismatch. Expected %p and got %p", baseadr, header->base);
121 if (flashmode == 5) {
122 stream_seterror(streamfd,
"[flashapp] Flash failed - previous block was padded");
126 if (size <
sizeof(flashbuf)) {
127 size =
sizeof(flashbuf);
136 if ((r =
flash_write(b, baseadr + offset, size))) {
138 stream_seterror(streamfd,
"%s", errbuf);
145 printf(
"[flashapp] written from %i to %i at %p\r\n", offset, offset + size, baseadr + offset);
146 offset = offset + size;
161 if ((f_flags & (1 << FLASH_FLAGS_USE_DIRECT_WRITE)) != 0) {
162 byte *target = (
byte *)adr;
163 for (r = 0; r < size; r++) {
171 if (comparemem(b, adr, size)) {
174 printf(
"[flashapp] %i bytes @ %p optimized out, bytes identical\r\n", size, adr);
177 mculib_flash_lock(MAIN_MCULIBHANDLE);
178 if ((r = mculib_flash_unlock(MAIN_MCULIBHANDLE))) {
179 snprintf(errbuf,
sizeof(errbuf),
"[flashapp] unlock failed (%i)\r\n", r);
180 mculib_flash_lock(MAIN_MCULIBHANDLE);
183 if ((f_flags & (1 << FLASH_FLAGS_PRE_ERASE)) == 0) {
184 if ((r = mculib_flash_erase(MAIN_MCULIBHANDLE, adr, size))) {
185 snprintf(errbuf,
sizeof(errbuf),
"[flashapp] erase failed (%i)\r\n", r);
186 mculib_flash_lock(MAIN_MCULIBHANDLE);
190 if ((f_flags & (1 << FLASH_FLAGS_WRITE_OLD))) {
191 r = mculib_flash_write(MAIN_MCULIBHANDLE, b, adr, size);
194 r = mculib_flash_write_page(MAIN_MCULIBHANDLE, b, adr, size);
196 mculib_flash_lock(MAIN_MCULIBHANDLE);
198 snprintf(errbuf,
sizeof(errbuf),
"[flashapp] write failure at address %p (%i bytes): %i\r\n", adr, size, r);
201 printf(
"[flashapp] written %i bytes @ %p\n", size, adr);
207int flash_app_init(
void *base, uint32_t flags) {
208 printf(
"[flashapp] init, base=%p, flags=%i\r\n", base, flags);
213 if (f_flags & (1 << FLASH_FLAGS_STOP_USERAPP)) {
218static void flash_action_not_supported(
struct command *com,
int errno) {
229 int bases = loader_get_app_base_address_count();
234 void *writeto = NULL;
240 return flash_action_not_supported(
com, 1);
248 long base = ascii_parse_hex((
const byte *)para, strlen(para), NULL);
253 if ((
void *)base == get_app_header()) {
257 writeto = (
void *)base;
260 printf(
"[flashapp] Update loader enabled (2)\r\n");
270 printf(
"[flashapp] Update loader enabled\r\n");
271 writeto = (
void *)0x8000000;
277 printf(
"[flashapp] Got %i base addresses\r\n", bases);
278 for (i = 0; i < bases; i++) {
279 void *optadr = loader_get_app_base_address(i);
280 printf(
"[flashapp] %i. baseaddress = %p\r\n", i, optadr);
281 if ((optadr != NULL) && (optadr != get_app_header())) {
286 if (writeto == NULL) {
287 printf(
"[flashapp] No baseaddress for flash!\n");
294 printf(
"[flashapp] Expecting flash at address 0x%p\r\n", writeto);
295 flash_app_init(writeto,
flags);
303 int er =
stream_associate(fd, &flashconsumerinfo, (
byte *)&flashbuf,
sizeof(flashbuf), 512);
306 printf(
"[flashapp] Failed to associate stream with flash (%i)\r\n", er);
312 printf(
"[flashapp] failed to alloc command\r\n");
321 printf(
"[flashapp] Failed to send flash data to sender\r\n");
330 printf(
"[flashapp] Flash setup ok (base=%p)\r\n", writeto);
333 printf(
"[flashapp] Flash setup failed (%i)\r\n", ec);
340 snprintf(e, 99,
"err=%i", ec);
341 snprintf(e2, 100,
"em=%s", errbuf);
int send_command_reply_with_args(struct command *com, byte flags, const char *format,...)
send a reply to a command
int stream_associate(int fd, const struct consumerinfo *c, byte *buf, int bufsize, int packetsize)
associate a stream with a consumer. return 0 if ok otherwise errorcode
int send_command(struct command *com)
send a command to another module (or broadcast)
void free_command(struct command *com)
free a command
void command_add_arg(struct command *com, const char *format,...)
adds an arg to a partially initialised command structure
int flash_write(byte *b, void *adr, int size)
unlock, erase, write, lock
const char * namedarg(struct command *com, const char *name)
get a named arg (key-value pair) or NULL
int send_command_reply(struct command *com, byte flags)
send a reply to a command
int flash_app_consumer(int streamfd, byte *b, int size)
called by stream whenever we got sufficient bytes (and only on full blocks!)
struct command * get_data_reply(struct command *com)
allocates and initializes a packet to be send as "data" to the command typically you'd add some data ...
void flashcom(struct command *com)
set up a flash connection, associate with stream, called by command-handler for command "flash-app"
this must be implemented by the userapp, stored in flash at the beginning of the file (offset 0)