mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 11:09:01 +08:00
Merge pull request #1975 from cesanta/hwtest
Cleanup, adopt for HW test
This commit is contained in:
commit
b04612e80d
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@ -98,6 +98,7 @@ jobs:
|
||||
- path: stm32/stm32-nucleo-f429z
|
||||
- path: stm32/stm32-nucleo-h743z
|
||||
- path: stm32/nucleo-f429zi-baremetal
|
||||
target: test
|
||||
- path: stm32/nucleo-f429zi-freertos-mip
|
||||
- path: stm32/nucleo-f429zi-usb-rndis
|
||||
- path: stm32/nucleo-f746zg-baremetal
|
||||
@ -135,7 +136,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- run: sudo apt -y install gcc-arm-none-eabi
|
||||
- name: ${{ matrix.example.path }}
|
||||
run: make -C examples/${{ matrix.example.path }} build
|
||||
run: make -C examples/${{ matrix.example.path }} ${{ matrix.example.target || 'build' }} VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||
zephyr_examples:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
@ -109,6 +109,7 @@ static void mqtt_fn(struct mg_connection *c, int ev, void *ev_data, void *fnd) {
|
||||
c->is_hexdumping = 1;
|
||||
mg_mqtt_sub(s_mqtt, mg_str(s_config.sub), 2);
|
||||
send_notification(c->mgr, "{%Q:%Q,%Q:null}", "name", "config", "data");
|
||||
MG_INFO(("MQTT connected, server %s", MQTT_SERVER));
|
||||
} else if (ev == MG_EV_MQTT_MSG) {
|
||||
struct mg_mqtt_message *mm = ev_data;
|
||||
send_notification(c->mgr, "{%Q:%Q,%Q:{%Q: %.*Q, %Q: %.*Q, %Q: %d}}", "name",
|
||||
|
@ -1,42 +1,35 @@
|
||||
TARGET = firmware
|
||||
ROOT ?= $(realpath $(CURDIR)/../../..)
|
||||
D ?= docker
|
||||
DOCKER ?= $(D) run --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/armgcc
|
||||
CROSS ?= arm-none-eabi
|
||||
CFLAGS ?= -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion \
|
||||
-Wformat-truncation -fno-common -Wconversion \
|
||||
-g3 -Os -ffunction-sections -fdata-sections -I. -I$(ROOT) \
|
||||
-DMG_ARCH=MG_ARCH_NEWLIB -DMIP_DEBUG=1 -DMG_ENABLE_PACKED_FS=1 \
|
||||
-DMG_ENABLE_CUSTOM_MILLIS=1 -DxMG_ENABLE_LINES=1 -DMG_ENABLE_MIP=1 \
|
||||
-g3 -Os -ffunction-sections -fdata-sections -I. \
|
||||
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(EXTRA_CFLAGS)
|
||||
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
||||
SOURCES = boot.c main.c syscalls.c \
|
||||
$(ROOT)/mongoose.c \
|
||||
$(ROOT)/examples/device-dashboard/packed_fs.c \
|
||||
$(ROOT)/examples/device-dashboard/net.c
|
||||
SOURCES = boot.c main.c syscalls.c
|
||||
|
||||
all build example: $(TARGET).bin
|
||||
# Add Mongoose-specific flags and source files
|
||||
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_PACKED_FS=1
|
||||
SOURCES += ../../../mongoose.c ../../device-dashboard/net.c ../../device-dashboard/packed_fs.c
|
||||
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
$(DOCKER) $(CROSS)-objcopy -O binary $< $@
|
||||
all build example: firmware.bin
|
||||
|
||||
$(TARGET).elf: $(SOURCES) mcu.h
|
||||
$(DOCKER) $(CROSS)-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
firmware.bin: firmware.elf
|
||||
arm-none-eabi-objcopy -O binary $< $@
|
||||
|
||||
# Build on Windows. Download Win32 Zip from ARM GCC downloads, unzip to c:\armgcc
|
||||
ARMGCC ?= c:/armgcc
|
||||
windows: $(TARGET).bin
|
||||
windows: CROSS = $(ARMGCC)/bin/arm-none-eabi
|
||||
windows: DOCKER =
|
||||
|
||||
# Show top 10 stack-hungry functions
|
||||
su: CFLAGS += -fstack-usage
|
||||
su: $(TARGET).elf
|
||||
cat *.su | sort -rnk2 | head -10
|
||||
firmware.elf: $(SOURCES) mcu.h
|
||||
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
# Note: on "unknown chip id" flash error, wire BOOT0 to VDD and st-flash erase
|
||||
flash: $(TARGET).bin
|
||||
st-flash --reset write $(TARGET).bin 0x8000000
|
||||
flash: firmware.bin
|
||||
st-flash --reset write $< 0x8000000
|
||||
|
||||
# Requires env variable VCON_API_KEY set
|
||||
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/2
|
||||
test: update
|
||||
curl --fail -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
||||
grep 'Ethernet: up' /tmp/output.txt
|
||||
grep 'MQTT connected' /tmp/output.txt
|
||||
|
||||
update: firmware.bin
|
||||
curl --fail -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||
|
||||
clean:
|
||||
@rm -rf $(TARGET).* *.su
|
||||
@rm -rf firmware.* *.su
|
||||
|
@ -4,19 +4,14 @@
|
||||
#include "mcu.h"
|
||||
#include "mongoose.h"
|
||||
|
||||
#define LED1 PIN('B', 0) // On-board LED pin (green)
|
||||
#define LED2 PIN('B', 7) // On-board LED pin (blue)
|
||||
#define LED3 PIN('B', 14) // On-board LED pin (red)
|
||||
#define BTN1 PIN('C', 13) // On-board user button
|
||||
#define LED1 PIN('B', 0) // On-board LED pin (green)
|
||||
#define LED2 PIN('B', 7) // On-board LED pin (blue)
|
||||
#define LED3 PIN('B', 14) // On-board LED pin (red)
|
||||
#define BTN1 PIN('C', 13) // On-board user button
|
||||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
||||
|
||||
static uint64_t s_ticks, s_exti; // Counters, increased by IRQ handlers
|
||||
|
||||
static void blink_cb(void *arg) { // Blink periodically
|
||||
// MG_INFO(("ticks: %u", (unsigned) s_ticks));
|
||||
gpio_toggle(LED2);
|
||||
(void) arg;
|
||||
}
|
||||
|
||||
uint64_t mg_millis(void) { // Declare our own uptime function
|
||||
return s_ticks; // Return number of milliseconds since boot
|
||||
}
|
||||
@ -36,15 +31,22 @@ void EXTI15_10_IRQHandler(void) { // External interrupt handler
|
||||
gpio_write(LED1, gpio_read(BTN1)); // No debounce. Turn LED if button pressed
|
||||
}
|
||||
|
||||
static void timer_cb(void *arg) {
|
||||
gpio_toggle(LED2); // Blink LED
|
||||
bool up = ((struct mip_if *) arg)->state == MIP_STATE_READY;
|
||||
MG_INFO(("Ethernet: %s", up ? "up" : "down")); // Show network status
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
static struct uart *uart = UART3; // Use UART3 - its attached to debug
|
||||
clock_init(); // Set clock to 180MHz
|
||||
systick_init(FREQ / 1000); // Increment s_ticks every ms
|
||||
gpio_output(LED1); // Setup green LED
|
||||
gpio_output(LED2); // Setup blue LED
|
||||
gpio_input(BTN1); // Set button to input
|
||||
irq_exti_attach(BTN1); // Attach BTN1 to exti
|
||||
uart_init(uart, 115200); // It is wired to the debug port
|
||||
clock_init(); // Set clock to 180MHz
|
||||
systick_init(SYS_FREQUENCY / 1000); // Increment s_ticks every ms
|
||||
gpio_output(LED1); // Setup green LED
|
||||
gpio_output(LED2); // Setup blue LED
|
||||
gpio_input(BTN1); // Set button to input
|
||||
irq_exti_attach(BTN1); // Attach BTN1 to exti
|
||||
uart_init(UART1, 115200); // Initialise debug printf
|
||||
|
||||
MG_INFO(("Starting, CPU freq %g MHz", (double) SYS_FREQUENCY / 1000000));
|
||||
|
||||
// Initialise Ethernet. Enable MAC GPIO pins, see
|
||||
// https://www.farnell.com/datasheets/2014265.pdf section 6.10
|
||||
@ -65,23 +67,30 @@ int main(void) {
|
||||
struct mg_mgr mgr; // Initialise Mongoose event manager
|
||||
mg_mgr_init(&mgr); // and attach it to the MIP interface
|
||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
|
||||
|
||||
// Initialise Mongoose network stack
|
||||
// Specify MAC address, and IP/mask/GW in network byte order for static
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4}; // See driver_stm32.h
|
||||
struct mip_if mif = {
|
||||
.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_stm32,
|
||||
.driver_data = &driver_data,
|
||||
};
|
||||
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4}; // driver_stm32.h
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_cb, &mif);
|
||||
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
MG_INFO(("Waiting until network is up..."));
|
||||
while (mif.state != MIP_STATE_READY) {
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
}
|
||||
|
||||
MG_INFO(("Initialising application..."));
|
||||
extern void device_dashboard_fn(struct mg_connection *, int, void *, void *);
|
||||
mg_http_listen(&mgr, "http://0.0.0.0", device_dashboard_fn, &mgr);
|
||||
for (;;) mg_mgr_poll(&mgr, 0); // Infinite event loop
|
||||
|
||||
MG_INFO(("Starting event loop"));
|
||||
for (;;) {
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,10 +20,10 @@
|
||||
// 33.4: The AHB clock must be at least 25 MHz when Ethernet is used
|
||||
enum { APB1_PRE = 5 /* AHB clock / 4 */, APB2_PRE = 4 /* AHB clock / 2 */ };
|
||||
enum { PLL_HSI = 16, PLL_M = 8, PLL_N = 180, PLL_P = 2 }; // Run at 180 Mhz
|
||||
//#define PLL_FREQ PLL_HSI
|
||||
#define PLL_FREQ (PLL_HSI * PLL_N / PLL_M / PLL_P)
|
||||
#define FLASH_LATENCY 5
|
||||
#define FREQ (PLL_FREQ * 1000000)
|
||||
#define SYS_FREQUENCY ((PLL_HSI * PLL_N / PLL_M / PLL_P) * 1000000)
|
||||
#define APB2_FREQUENCY (SYS_FREQUENCY / (BIT(APB2_PRE - 3)))
|
||||
#define APB1_FREQUENCY (SYS_FREQUENCY / (BIT(APB1_PRE - 3)))
|
||||
|
||||
static inline void spin(volatile uint32_t count) {
|
||||
while (count--) asm("nop");
|
||||
@ -93,13 +93,11 @@ struct gpio {
|
||||
};
|
||||
#define GPIO(N) ((struct gpio *) (0x40020000 + 0x400 * (N)))
|
||||
|
||||
static struct gpio *gpio_bank(uint16_t pin) {
|
||||
return GPIO(PINBANK(pin));
|
||||
}
|
||||
static struct gpio *gpio_bank(uint16_t pin) { return GPIO(PINBANK(pin)); }
|
||||
static inline void gpio_toggle(uint16_t pin) {
|
||||
struct gpio *gpio = gpio_bank(pin);
|
||||
uint32_t mask = BIT(PINNO(pin));
|
||||
gpio->BSRR |= mask << (gpio->ODR & mask ? 16 : 0);
|
||||
gpio->BSRR = mask << (gpio->ODR & mask ? 16 : 0);
|
||||
}
|
||||
static inline int gpio_read(uint16_t pin) {
|
||||
return gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0;
|
||||
@ -163,10 +161,11 @@ static inline void uart_init(struct uart *uart, unsigned long baud) {
|
||||
// https://www.st.com/resource/en/datasheet/stm32f429zi.pdf
|
||||
uint8_t af = 7; // Alternate function
|
||||
uint16_t rx = 0, tx = 0; // pins
|
||||
uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1
|
||||
|
||||
if (uart == UART1) RCC->APB2ENR |= BIT(4);
|
||||
if (uart == UART2) RCC->APB1ENR |= BIT(17);
|
||||
if (uart == UART3) RCC->APB1ENR |= BIT(18);
|
||||
if (uart == UART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4);
|
||||
if (uart == UART2) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(17);
|
||||
if (uart == UART3) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(18);
|
||||
|
||||
if (uart == UART1) tx = PIN('A', 9), rx = PIN('A', 10);
|
||||
if (uart == UART2) tx = PIN('A', 2), rx = PIN('A', 3);
|
||||
@ -174,9 +173,8 @@ static inline void uart_init(struct uart *uart, unsigned long baud) {
|
||||
|
||||
gpio_init(tx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af);
|
||||
gpio_init(rx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af);
|
||||
uart->CR1 = 0; // Disable this UART
|
||||
uart->BRR = FREQ / 4 / baud; // Baud rate, "4" is APBx prescaler, different from APBx_PRE
|
||||
// TODO(): make this configurable ?
|
||||
uart->CR1 = 0; // Disable this UART
|
||||
uart->BRR = freq / baud; // Set baud rate
|
||||
uart->CR1 |= BIT(13) | BIT(2) | BIT(3); // Set UE, RE, TE
|
||||
}
|
||||
static inline void uart_write_byte(struct uart *uart, uint8_t byte) {
|
||||
|
@ -53,7 +53,7 @@ int _getpid(void) {
|
||||
|
||||
int _write(int fd, char *ptr, int len) {
|
||||
(void) fd, (void) ptr, (void) len;
|
||||
if (fd == 1) uart_write_buf(UART3, ptr, (size_t) len);
|
||||
if (fd == 1) uart_write_buf(UART1, ptr, (size_t) len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user