Skip to content

Commit

Permalink
Add persistent RAM block and other minor fixes.
Browse files Browse the repository at this point in the history
* Add persistent RAM block to "preserve" RTC clock over soft reset
* New command: SYS:FLASH?
* Fix PANIC when https server responded with larger payload
* Typo fixes.
  • Loading branch information
tjko committed Jan 21, 2024
1 parent c171f09 commit 83025b3
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 17 deletions.
14 changes: 14 additions & 0 deletions commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ Fanpico supports following commands:
* [SYStem:ECHO](#systemecho)
* [SYStem:ECHO?](#systemecho)
* [SYStem:FANS?](#systemfans)
* [SYStem:FLASH?](#systemflash)
* [SYStem:LED](#systemled)
* [SYStem:LED?](#systemled-1)
* [SYStem:MBFANS?](#systemmbfans)
Expand Down Expand Up @@ -1621,6 +1622,19 @@ SYS:FANS?
```


### SYStem:FLASH?
Returns information about Pico flash memory usage.

Example:
```
SYS:FLASH?
Flash memory size: 2097152
Binary size: 683520
LittleFS size: 262144
Unused flash memory: 1151488
```


#### SYStem:LED
Set system indicator LED operating mode.

Expand Down
23 changes: 18 additions & 5 deletions src/command.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* command.c
Copyright (C) 2021-2023 Timo Kokkonen <tjko@iki.fi>
Copyright (C) 2021-2024 Timo Kokkonen <tjko@iki.fi>
SPDX-License-Identifier: GPL-3.0-or-later
Expand Down Expand Up @@ -410,6 +410,7 @@ int cmd_reset(const char *cmd, const char *args, int query, char *prev_cmd)

log_msg(LOG_ALERT, "Initiating reboot...");
display_message(1, msg);
update_persistent_memory();

watchdog_disable();
sleep_ms(500);
Expand Down Expand Up @@ -2052,7 +2053,7 @@ int cmd_tls_pkey(const char *cmd, const char *args, int query, char *prev_cmd)
printf("Failed to delete private key: %d\n", res);
res = 2;
} else {
printf("Private key succesfully deleted.\n");
printf("Private key successfully deleted.\n");
}
}
else {
Expand All @@ -2077,7 +2078,7 @@ int cmd_tls_pkey(const char *cmd, const char *args, int query, char *prev_cmd)
printf("Failed to save private key.\n");
res = 2;
} else {
printf("Private key succesfully saved. (length=%u)\n",
printf("Private key successfully saved. (length=%u)\n",
strlen(buf));
res = 0;
}
Expand Down Expand Up @@ -2133,7 +2134,7 @@ int cmd_tls_cert(const char *cmd, const char *args, int query, char *prev_cmd)
printf("Failed to delete certificate: %d\n", res);
res = 2;
} else {
printf("Certificate succesfully deleted.\n");
printf("Certificate successfully deleted.\n");
}
}
else {
Expand All @@ -2150,7 +2151,7 @@ int cmd_tls_cert(const char *cmd, const char *args, int query, char *prev_cmd)
printf("Failed to save certificate.\n");
res = 2;
} else {
printf("Certificate succesfully saved. (length=%u)\n",
printf("Certificate successfully saved. (length=%u)\n",
strlen(buf));
res = 0;
}
Expand Down Expand Up @@ -2232,6 +2233,17 @@ int cmd_name(const char *cmd, const char *args, int query, char *prev_cmd)
conf->name, sizeof(conf->name), "System Name");
}


int cmd_flash(const char *cmd, const char *args, int query, char *prev_cmd)
{
if (!query)
return 1;

print_rp2040_flashinfo();
return 0;
}


#define TEST_MEM_SIZE (264*1024)

int cmd_memory(const char *cmd, const char *args, int query, char *prev_cmd)
Expand Down Expand Up @@ -2392,6 +2404,7 @@ const struct cmd_t system_commands[] = {
{ "ECHO", 4, NULL, cmd_echo },
{ "ERRor", 3, NULL, cmd_err },
{ "FANS", 4, NULL, cmd_fans },
{ "FLASH", 5, NULL, cmd_flash },
{ "LED", 3, NULL, cmd_led },
{ "LOG", 3, NULL, cmd_log_level },
{ "MBFANS", 6, NULL, cmd_mbfans },
Expand Down
82 changes: 78 additions & 4 deletions src/fanpico.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,74 @@

static struct fanpico_state core1_state;
static struct fanpico_config core1_config;

static struct fanpico_state transfer_state;

static struct fanpico_state system_state;
const struct fanpico_state *fanpico_state = &system_state;

struct persistent_memory_block __uninitialized_ram(persistent_memory);
struct persistent_memory_block *persistent_mem = &persistent_memory;

#define PERSISTENT_MEMORY_ID 0x42c0ffee
#define PERSISTENT_MEMORY_CRC_LEN offsetof(struct persistent_memory_block, crc32)

auto_init_mutex(pmem_mutex_inst);
mutex_t *pmem_mutex = &pmem_mutex_inst;
auto_init_mutex(state_mutex_inst);
mutex_t *state_mutex = &state_mutex_inst;
bool rebooted_by_watchdog = false;


void update_persistent_memory_crc()
{
struct persistent_memory_block *m = persistent_mem;

m->crc32 = xcrc32((unsigned char*)m, PERSISTENT_MEMORY_CRC_LEN, 0);
}

void init_persistent_memory()
{
struct persistent_memory_block *m = persistent_mem;
uint32_t crc;
char s[32];

if (m->id == PERSISTENT_MEMORY_ID) {
crc = xcrc32((unsigned char*)m, PERSISTENT_MEMORY_CRC_LEN, 0);
if (crc == m->crc32) {
printf("Found persistent memory block\n");
datetime_str(s, sizeof(s), &m->saved_time);
if (!rtc_set_datetime(&m->saved_time)) {
printf("Failed to restore RTC clock: %s\n", s);
}
if (m->uptime) {
m->prev_uptime = m->uptime;
update_persistent_memory_crc();
}
return;
}
printf("Found corrupt persistent memory block"
" (CRC-32 mismatch %08lx != %08lx)\n", crc, m->crc32);
}

printf("Initializing persistent memory block...\n");
memset(m, 0, sizeof(*m));
m->id = PERSISTENT_MEMORY_ID;
update_persistent_memory_crc();
}

void update_persistent_memory()
{
struct persistent_memory_block *m = persistent_mem;
datetime_t t;

mutex_enter_blocking(pmem_mutex);
if (rtc_get_datetime(&t)) {
m->saved_time = t;
}
m->uptime = to_us_since_boot(get_absolute_time());
update_persistent_memory_crc();
mutex_exit(pmem_mutex);
}

void boot_reason()
{
printf(" CHIP_RESET: %08lx\n", vreg_and_chip_reset_hw->chip_reset);
Expand All @@ -62,6 +119,8 @@ void boot_reason()

void setup()
{
datetime_t t;
char buf[32];
int i = 0;

rtc_init();
Expand Down Expand Up @@ -103,6 +162,18 @@ void setup()
clock_get_hz(clk_sys) / 1000000.0);
printf(" Serial Number: %s\n\n", pico_serial_str());

init_persistent_memory();
printf("\n");

log_msg(LOG_NOTICE, "System starting...");
if (persistent_mem->prev_uptime) {
log_msg(LOG_NOTICE, "Uptime before soft reset: %llus\n",
persistent_mem->prev_uptime / 1000000);
}
if (rtc_get_datetime(&t)) {
log_msg(LOG_NOTICE, "RTC clock time: %s", datetime_str(buf, sizeof(buf), &t));
}

display_init();
network_init(&system_state);

Expand Down Expand Up @@ -341,7 +412,7 @@ int main()
{
absolute_time_t ABSOLUTE_TIME_INITIALIZED_VAR(t_led, 0);
absolute_time_t ABSOLUTE_TIME_INITIALIZED_VAR(t_network, 0);
absolute_time_t t_now, t_last, t_display;
absolute_time_t t_now, t_last, t_display, t_ram;
uint8_t led_state = 0;
int64_t max_delta = 0;
int64_t delta;
Expand Down Expand Up @@ -372,7 +443,7 @@ int main()
#endif

t_last = get_absolute_time();
t_display = t_last;
t_ram = t_display = t_last;

while (1) {
t_now = get_absolute_time();
Expand All @@ -387,6 +458,9 @@ int main()
if (time_passed(&t_network, 1)) {
network_poll();
}
if (time_passed(&t_ram, 1000)) {
update_persistent_memory();
}

/* Toggle LED every 1000ms */
if (time_passed(&t_led, 1000)) {
Expand Down
14 changes: 13 additions & 1 deletion src/fanpico.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* fanpico.h
Copyright (C) 2021-2023 Timo Kokkonen <tjko@iki.fi>
Copyright (C) 2021-2024 Timo Kokkonen <tjko@iki.fi>
SPDX-License-Identifier: GPL-3.0-or-later
Expand Down Expand Up @@ -257,12 +257,22 @@ struct fanpico_state {
float mbfan_freq_prev[MBFAN_MAX_COUNT];
};

struct persistent_memory_block {
uint32_t id;
datetime_t saved_time;
uint64_t uptime;
uint64_t prev_uptime;
uint32_t crc32;
};


/* fanpico.c */
extern struct persistent_memory_block *persistent_mem;
extern const struct fanpico_state *fanpico_state;
extern bool rebooted_by_watchdog;
extern mutex_t *state_mutex;
void update_display_state();
void update_persistent_memory();

/* bi_decl.c */
void set_binary_info();
Expand Down Expand Up @@ -397,6 +407,7 @@ char *trim_str(char *s);
int str_to_int(const char *str, int *val, int base);
int str_to_float(const char *str, float *val);
int str_to_datetime(const char *str, datetime_t *t);
char* datetime_str(char *buf, size_t size, const datetime_t *t);
datetime_t *tm_to_datetime(const struct tm *tm, datetime_t *t);
struct tm *datetime_to_tm(const datetime_t *t, struct tm *tm);
time_t datetime_to_time(const datetime_t *datetime);
Expand All @@ -417,6 +428,7 @@ int str_to_bitmask(const char *str, uint16_t len, uint32_t *mask, uint8_t base);
/* util_rp2040.c */
uint32_t get_stack_pointer();
uint32_t get_stack_free();
void print_rp2040_flashinfo();
void print_rp2040_meminfo();
void print_irqinfo();
void watchdog_disable();
Expand Down
2 changes: 1 addition & 1 deletion src/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int flash_write_file(const char *buf, uint32_t size, const char *filename)
filename, wrote);
res = -3;
} else {
log_msg(LOG_INFO, "File \"%s\" sucfessfully created: %li bytes",
log_msg(LOG_INFO, "File \"%s\" successfully created: %li bytes",
filename, wrote);
res = 0;
}
Expand Down
4 changes: 3 additions & 1 deletion src/mbedtls_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT

#define MBEDTLS_SSL_OUT_CONTENT_LEN 4096
#define MBEDTLS_SSL_OUT_CONTENT_LEN 4096
/* seems like apparent bug (?) in LwIP altcp_tls requires this when MBEDTLS_SSL_OUT_CONTENT_LEN is over 2048 */
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH 4096

#define MBEDTLS_ALLOW_PRIVATE_ACCESS
#define MBEDTLS_HAVE_TIME
Expand Down
4 changes: 2 additions & 2 deletions src/mqtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,8 @@ void fanpico_mqtt_scpi_command()
strncopy(cmd, mqtt_scpi_cmd, sizeof(cmd));
process_command(st, (struct fanpico_config *)cfg, cmd);
if ((res = last_command_status()) == 0) {
log_msg(LOG_INFO, "MQTT SCPI command successfull: '%s'", mqtt_scpi_cmd);
send_mqtt_command_response(mqtt_scpi_cmd, res, "SCPI command successfull");
log_msg(LOG_INFO, "MQTT SCPI command successful: '%s'", mqtt_scpi_cmd);
send_mqtt_command_response(mqtt_scpi_cmd, res, "SCPI command successful");
} else {
log_msg(LOG_NOTICE, "MQTT SCPI command failed: '%s' (%d)", mqtt_scpi_cmd, res);
if (res == -113)
Expand Down
2 changes: 1 addition & 1 deletion src/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ void wifi_init()
cfg->wifi_passwd,
CYW43_AUTH_WPA2_AES_PSK);
} else {
/* If "SYS:WIFI:MODE 1" has been used, attemp synchronous connection
/* If "SYS:WIFI:MODE 1" has been used, attempt synchronous connection
as connection to some buggy(?) APs don't seem to always work with
asynchronouse connection... */
int retries = 2;
Expand Down
14 changes: 13 additions & 1 deletion src/util.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* util.c
Copyright (C) 2021-2022 Timo Kokkonen <tjko@iki.fi>
Copyright (C) 2021-2024 Timo Kokkonen <tjko@iki.fi>
SPDX-License-Identifier: GPL-3.0-or-later
Expand Down Expand Up @@ -151,6 +151,18 @@ int str_to_datetime(const char *str, datetime_t *t)
}


char* datetime_str(char *buf, size_t size, const datetime_t *t)
{
if (!t || !buf)
return NULL;

snprintf(buf, size, "%04d-%02d-%02d %02d:%02d:%02d",
t->year, t->month, t->day, t->hour, t->min, t->sec);

return buf;
}


datetime_t *tm_to_datetime(const struct tm *tm, datetime_t *t)
{
if (!tm || !t)
Expand Down
18 changes: 17 additions & 1 deletion src/util_rp2040.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* util_rp2040.c
Copyright (C) 2021-2023 Timo Kokkonen <tjko@iki.fi>
Copyright (C) 2021-2024 Timo Kokkonen <tjko@iki.fi>
SPDX-License-Identifier: GPL-3.0-or-later
Expand Down Expand Up @@ -28,6 +28,7 @@
#include "pico/multicore.h"
#include "hardware/watchdog.h"

#include "pico_hal.h"

#include "fanpico.h"

Expand All @@ -39,6 +40,9 @@ extern char __StackOneBottom;
extern char __StackLimit;
extern char __HeapLimit;
extern char __end__;
extern char __flash_binary_start;
extern char __flash_binary_end;
extern struct lfs_config pico_cfg;


inline uint32_t get_stack_pointer() {
Expand All @@ -58,6 +62,18 @@ inline uint32_t get_stack_free()
return (sp > end ? sp - end : 0);
}

void print_rp2040_flashinfo()
{
size_t binary_size = &__flash_binary_end - &__flash_binary_start;
size_t fs_size = pico_cfg.block_count * pico_cfg.block_size;

printf("Flash memory size: %u\n", PICO_FLASH_SIZE_BYTES);
printf("Binary size: %u\n", binary_size);
printf("LittleFS size: %u\n", fs_size);
printf("Unused flash memory: %u\n",
PICO_FLASH_SIZE_BYTES - binary_size - fs_size);

}

void print_rp2040_meminfo()
{
Expand Down

0 comments on commit 83025b3

Please sign in to comment.