Update Zephyr to v3.4.0
This commit is contained in:
@@ -119,6 +119,11 @@ if "nobuild" in COMMAND_LINE_TARGETS:
|
||||
else:
|
||||
target_elf = env.BuildProgram()
|
||||
target_firm = env.ElfToBin(join("$BUILD_DIR", "${PROGNAME}"), target_elf)
|
||||
|
||||
if "zephyr" in frameworks and "mcuboot-image" in COMMAND_LINE_TARGETS:
|
||||
target_firm = env.MCUbootImage(
|
||||
join("$BUILD_DIR", "${PROGNAME}.mcuboot.bin"), target_firm)
|
||||
|
||||
env.Depends(target_firm, "checkprogsize")
|
||||
|
||||
AlwaysBuild(env.Alias("nobuild", target_firm))
|
||||
|
||||
@@ -4,48 +4,43 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <device.h>
|
||||
#include <devicetree.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
/* 1000 msec = 1 sec */
|
||||
#define SLEEP_TIME_MS 1000
|
||||
#define SLEEP_TIME_MS 300
|
||||
|
||||
/* The devicetree node identifier for the "led0" alias. */
|
||||
#define LED0_NODE DT_ALIAS(led0)
|
||||
|
||||
#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
|
||||
#define LED0 DT_GPIO_LABEL(LED0_NODE, gpios)
|
||||
#define PIN DT_GPIO_PIN(LED0_NODE, gpios)
|
||||
#define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
|
||||
#else
|
||||
/* A build error here means your board isn't set up to blink an LED. */
|
||||
#error "Unsupported board: led0 devicetree alias is not defined"
|
||||
#define LED0 ""
|
||||
#define PIN 0
|
||||
#define FLAGS 0
|
||||
#endif
|
||||
/*
|
||||
* A build error on this line means your board is unsupported.
|
||||
* See the sample documentation for information on how to fix this.
|
||||
*/
|
||||
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
const struct device *dev;
|
||||
bool led_is_on = true;
|
||||
int ret;
|
||||
|
||||
dev = device_get_binding(LED0);
|
||||
if (dev == NULL) {
|
||||
if (!gpio_is_ready_dt(&led))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
|
||||
if (ret < 0) {
|
||||
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
|
||||
if (ret < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
gpio_pin_set(dev, PIN, (int)led_is_on);
|
||||
led_is_on = !led_is_on;
|
||||
while (1)
|
||||
{
|
||||
ret = gpio_pin_toggle_dt(&led);
|
||||
if (ret < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
k_msleep(SLEEP_TIME_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
# nothing here
|
||||
CONFIG_GPIO=y
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <zephyr.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <sys/printk.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
|
||||
/**
|
||||
* @class semaphore the basic pure virtual semaphore class
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
cpp_semaphore::cpp_semaphore()
|
||||
{
|
||||
printk("Create semaphore %p\n", this);
|
||||
k_sem_init(&_sema_internal, 0, UINT_MAX);
|
||||
k_sem_init(&_sema_internal, 0, K_SEM_MAX_LIMIT);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -98,12 +98,9 @@ int cpp_semaphore::wait(int timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Signal a semaphore
|
||||
*
|
||||
* This routine signals the specified semaphore.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void cpp_semaphore::give(void)
|
||||
{
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
CONFIG_CPLUSPLUS=y
|
||||
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=128
|
||||
CONFIG_CPP=y
|
||||
CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=128
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <kernel.h>
|
||||
#include <sys/printk.h>
|
||||
#include <device.h>
|
||||
#include <drivers/can.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/can.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#define RX_THREAD_STACK_SIZE 512
|
||||
#define RX_THREAD_PRIORITY 2
|
||||
@@ -25,25 +26,34 @@
|
||||
K_THREAD_STACK_DEFINE(rx_thread_stack, RX_THREAD_STACK_SIZE);
|
||||
K_THREAD_STACK_DEFINE(poll_state_stack, STATE_POLL_THREAD_STACK_SIZE);
|
||||
|
||||
const struct device *can_dev;
|
||||
const struct device *led_gpio_dev;
|
||||
const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
|
||||
struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios, {0});
|
||||
|
||||
struct k_thread rx_thread_data;
|
||||
struct k_thread poll_state_thread_data;
|
||||
struct zcan_work rx_work;
|
||||
struct k_work_poll change_led_work;
|
||||
struct k_work state_change_work;
|
||||
enum can_state current_state;
|
||||
struct can_bus_err_cnt current_err_cnt;
|
||||
|
||||
CAN_DEFINE_MSGQ(counter_msgq, 2);
|
||||
CAN_MSGQ_DEFINE(change_led_msgq, 2);
|
||||
CAN_MSGQ_DEFINE(counter_msgq, 2);
|
||||
|
||||
void tx_irq_callback(uint32_t error_flags, void *arg)
|
||||
static struct k_poll_event change_led_events[1] = {
|
||||
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY,
|
||||
&change_led_msgq, 0)
|
||||
};
|
||||
|
||||
void tx_irq_callback(const struct device *dev, int error, void *arg)
|
||||
{
|
||||
char *sender = (char *)arg;
|
||||
|
||||
if (error_flags) {
|
||||
printk("Callback! error-code: %d\nSender: %s\n",
|
||||
error_flags, sender);
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
if (error != 0) {
|
||||
printf("Callback! error-code: %d\nSender: %s\n",
|
||||
error, sender);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,68 +62,63 @@ void rx_thread(void *arg1, void *arg2, void *arg3)
|
||||
ARG_UNUSED(arg1);
|
||||
ARG_UNUSED(arg2);
|
||||
ARG_UNUSED(arg3);
|
||||
const struct zcan_filter filter = {
|
||||
.id_type = CAN_EXTENDED_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
const struct can_filter filter = {
|
||||
.flags = CAN_FILTER_DATA | CAN_FILTER_IDE,
|
||||
.id = COUNTER_MSG_ID,
|
||||
.rtr_mask = 1,
|
||||
.id_mask = CAN_EXT_ID_MASK
|
||||
.mask = CAN_EXT_ID_MASK
|
||||
};
|
||||
struct zcan_frame msg;
|
||||
struct can_frame frame;
|
||||
int filter_id;
|
||||
|
||||
filter_id = can_attach_msgq(can_dev, &counter_msgq, &filter);
|
||||
printk("Counter filter id: %d\n", filter_id);
|
||||
filter_id = can_add_rx_filter_msgq(can_dev, &counter_msgq, &filter);
|
||||
printf("Counter filter id: %d\n", filter_id);
|
||||
|
||||
while (1) {
|
||||
k_msgq_get(&counter_msgq, &msg, K_FOREVER);
|
||||
k_msgq_get(&counter_msgq, &frame, K_FOREVER);
|
||||
|
||||
if (msg.dlc != 2U) {
|
||||
printk("Wrong data length: %u\n", msg.dlc);
|
||||
if (frame.dlc != 2U) {
|
||||
printf("Wrong data length: %u\n", frame.dlc);
|
||||
continue;
|
||||
}
|
||||
|
||||
printk("Counter received: %u\n",
|
||||
sys_be16_to_cpu(UNALIGNED_GET((uint16_t *)&msg.data)));
|
||||
printf("Counter received: %u\n",
|
||||
sys_be16_to_cpu(UNALIGNED_GET((uint16_t *)&frame.data)));
|
||||
}
|
||||
}
|
||||
|
||||
void change_led(struct zcan_frame *msg, void *unused)
|
||||
void change_led_work_handler(struct k_work *work)
|
||||
{
|
||||
ARG_UNUSED(unused);
|
||||
struct can_frame frame;
|
||||
int ret;
|
||||
|
||||
#if DT_PHA_HAS_CELL(DT_ALIAS(led0), gpios, pin) && \
|
||||
DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
|
||||
|
||||
if (!led_gpio_dev) {
|
||||
printk("No LED GPIO device\n");
|
||||
return;
|
||||
while (k_msgq_get(&change_led_msgq, &frame, K_NO_WAIT) == 0) {
|
||||
if (led.port == NULL) {
|
||||
printf("LED %s\n", frame.data[0] == SET_LED ? "ON" : "OFF");
|
||||
} else {
|
||||
gpio_pin_set(led.port, led.pin, frame.data[0] == SET_LED ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
switch (msg->data[0]) {
|
||||
case SET_LED:
|
||||
gpio_pin_set(led_gpio_dev,
|
||||
DT_GPIO_PIN(DT_ALIAS(led0), gpios), 1);
|
||||
break;
|
||||
case RESET_LED:
|
||||
gpio_pin_set(led_gpio_dev,
|
||||
DT_GPIO_PIN(DT_ALIAS(led0), gpios), 0);
|
||||
break;
|
||||
ret = k_work_poll_submit(&change_led_work, change_led_events,
|
||||
ARRAY_SIZE(change_led_events), K_FOREVER);
|
||||
if (ret != 0) {
|
||||
printf("Failed to resubmit msgq polling: %d", ret);
|
||||
}
|
||||
#else
|
||||
printk("LED %s\n", msg->data[0] == SET_LED ? "ON" : "OFF");
|
||||
#endif
|
||||
}
|
||||
|
||||
char *state_to_str(enum can_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case CAN_ERROR_ACTIVE:
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
return "error-active";
|
||||
case CAN_ERROR_PASSIVE:
|
||||
case CAN_STATE_ERROR_WARNING:
|
||||
return "error-warning";
|
||||
case CAN_STATE_ERROR_PASSIVE:
|
||||
return "error-passive";
|
||||
case CAN_BUS_OFF:
|
||||
case CAN_STATE_BUS_OFF:
|
||||
return "bus-off";
|
||||
case CAN_STATE_STOPPED:
|
||||
return "stopped";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
@@ -123,11 +128,18 @@ void poll_state_thread(void *unused1, void *unused2, void *unused3)
|
||||
{
|
||||
struct can_bus_err_cnt err_cnt = {0, 0};
|
||||
struct can_bus_err_cnt err_cnt_prev = {0, 0};
|
||||
enum can_state state_prev = CAN_ERROR_ACTIVE;
|
||||
enum can_state state_prev = CAN_STATE_ERROR_ACTIVE;
|
||||
enum can_state state;
|
||||
int err;
|
||||
|
||||
while (1) {
|
||||
state = can_get_state(can_dev, &err_cnt);
|
||||
err = can_get_state(can_dev, &state, &err_cnt);
|
||||
if (err != 0) {
|
||||
printf("Failed to get CAN controller state: %d", err);
|
||||
k_sleep(K_MSEC(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (err_cnt.tx_err_cnt != err_cnt_prev.tx_err_cnt ||
|
||||
err_cnt.rx_err_cnt != err_cnt_prev.rx_err_cnt ||
|
||||
state_prev != state) {
|
||||
@@ -135,7 +147,7 @@ void poll_state_thread(void *unused1, void *unused2, void *unused3)
|
||||
err_cnt_prev.tx_err_cnt = err_cnt.tx_err_cnt;
|
||||
err_cnt_prev.rx_err_cnt = err_cnt.rx_err_cnt;
|
||||
state_prev = state;
|
||||
printk("state: %s\n"
|
||||
printf("state: %s\n"
|
||||
"rx error count: %d\n"
|
||||
"tx error count: %d\n",
|
||||
state_to_str(state),
|
||||
@@ -148,48 +160,49 @@ void poll_state_thread(void *unused1, void *unused2, void *unused3)
|
||||
|
||||
void state_change_work_handler(struct k_work *work)
|
||||
{
|
||||
printk("State Change ISR\nstate: %s\n"
|
||||
printf("State Change ISR\nstate: %s\n"
|
||||
"rx error count: %d\n"
|
||||
"tx error count: %d\n",
|
||||
state_to_str(current_state),
|
||||
current_err_cnt.rx_err_cnt, current_err_cnt.tx_err_cnt);
|
||||
|
||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||
if (current_state == CAN_BUS_OFF) {
|
||||
printk("Recover from bus-off\n");
|
||||
if (current_state == CAN_STATE_BUS_OFF) {
|
||||
printf("Recover from bus-off\n");
|
||||
|
||||
if (can_recover(can_dev, K_MSEC(100) != 0)) {
|
||||
printk("Recovery timed out\n");
|
||||
if (can_recover(can_dev, K_MSEC(100)) != 0) {
|
||||
printf("Recovery timed out\n");
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
|
||||
}
|
||||
|
||||
void state_change_isr(enum can_state state, struct can_bus_err_cnt err_cnt)
|
||||
void state_change_callback(const struct device *dev, enum can_state state,
|
||||
struct can_bus_err_cnt err_cnt, void *user_data)
|
||||
{
|
||||
struct k_work *work = (struct k_work *)user_data;
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
current_state = state;
|
||||
current_err_cnt = err_cnt;
|
||||
k_work_submit(&state_change_work);
|
||||
k_work_submit(work);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
int main(void)
|
||||
{
|
||||
const struct zcan_filter change_led_filter = {
|
||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
const struct can_filter change_led_filter = {
|
||||
.flags = CAN_FILTER_DATA,
|
||||
.id = LED_MSG_ID,
|
||||
.rtr_mask = 1,
|
||||
.id_mask = CAN_STD_ID_MASK
|
||||
.mask = CAN_STD_ID_MASK
|
||||
};
|
||||
struct zcan_frame change_led_frame = {
|
||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
struct can_frame change_led_frame = {
|
||||
.flags = 0,
|
||||
.id = LED_MSG_ID,
|
||||
.dlc = 1
|
||||
};
|
||||
struct zcan_frame counter_frame = {
|
||||
.id_type = CAN_EXTENDED_IDENTIFIER,
|
||||
.rtr = CAN_DATAFRAME,
|
||||
struct can_frame counter_frame = {
|
||||
.flags = CAN_FRAME_IDE,
|
||||
.id = COUNTER_MSG_ID,
|
||||
.dlc = 2
|
||||
};
|
||||
@@ -198,54 +211,64 @@ void main(void)
|
||||
k_tid_t rx_tid, get_state_tid;
|
||||
int ret;
|
||||
|
||||
can_dev = device_get_binding(DT_CHOSEN_ZEPHYR_CAN_PRIMARY_LABEL);
|
||||
|
||||
if (!can_dev) {
|
||||
printk("CAN: Device driver not found.\n");
|
||||
return;
|
||||
if (!device_is_ready(can_dev)) {
|
||||
printf("CAN: Device %s not ready.\n", can_dev->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOOPBACK_MODE
|
||||
can_set_mode(can_dev, CAN_LOOPBACK_MODE);
|
||||
#endif
|
||||
|
||||
#if DT_PHA_HAS_CELL(DT_ALIAS(led0), gpios, pin) && \
|
||||
DT_NODE_HAS_PROP(DT_ALIAS(led0), gpios)
|
||||
led_gpio_dev = device_get_binding(DT_GPIO_LABEL(DT_ALIAS(led0), gpios));
|
||||
if (!led_gpio_dev) {
|
||||
printk("LED: Device driver not found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure(led_gpio_dev,
|
||||
DT_GPIO_PIN(DT_ALIAS(led0), gpios),
|
||||
GPIO_OUTPUT_HIGH |
|
||||
DT_GPIO_FLAGS(DT_ALIAS(led0), gpios));
|
||||
if (ret < 0) {
|
||||
printk("Error setting LED pin to output mode [%d]", ret);
|
||||
ret = can_set_mode(can_dev, CAN_MODE_LOOPBACK);
|
||||
if (ret != 0) {
|
||||
printf("Error setting CAN mode [%d]", ret);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
ret = can_start(can_dev);
|
||||
if (ret != 0) {
|
||||
printf("Error starting CAN controller [%d]", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (led.port != NULL) {
|
||||
if (!device_is_ready(led.port)) {
|
||||
printf("LED: Device %s not ready.\n",
|
||||
led.port->name);
|
||||
return 0;
|
||||
}
|
||||
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_HIGH);
|
||||
if (ret < 0) {
|
||||
printf("Error setting LED pin to output mode [%d]",
|
||||
ret);
|
||||
led.port = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
k_work_init(&state_change_work, state_change_work_handler);
|
||||
k_work_poll_init(&change_led_work, change_led_work_handler);
|
||||
|
||||
ret = can_attach_workq(can_dev, &k_sys_work_q, &rx_work, change_led,
|
||||
NULL, &change_led_filter);
|
||||
if (ret == CAN_NO_FREE_FILTER) {
|
||||
printk("Error, no filter available!\n");
|
||||
return;
|
||||
ret = can_add_rx_filter_msgq(can_dev, &change_led_msgq, &change_led_filter);
|
||||
if (ret == -ENOSPC) {
|
||||
printf("Error, no filter available!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printk("Change LED filter ID: %d\n", ret);
|
||||
printf("Change LED filter ID: %d\n", ret);
|
||||
|
||||
ret = k_work_poll_submit(&change_led_work, change_led_events,
|
||||
ARRAY_SIZE(change_led_events), K_FOREVER);
|
||||
if (ret != 0) {
|
||||
printf("Failed to submit msgq polling: %d", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rx_tid = k_thread_create(&rx_thread_data, rx_thread_stack,
|
||||
K_THREAD_STACK_SIZEOF(rx_thread_stack),
|
||||
rx_thread, NULL, NULL, NULL,
|
||||
RX_THREAD_PRIORITY, 0, K_NO_WAIT);
|
||||
if (!rx_tid) {
|
||||
printk("ERROR spawning rx thread\n");
|
||||
printf("ERROR spawning rx thread\n");
|
||||
}
|
||||
|
||||
|
||||
get_state_tid = k_thread_create(&poll_state_thread_data,
|
||||
poll_state_stack,
|
||||
K_THREAD_STACK_SIZEOF(poll_state_stack),
|
||||
@@ -253,12 +276,12 @@ void main(void)
|
||||
STATE_POLL_THREAD_PRIORITY, 0,
|
||||
K_NO_WAIT);
|
||||
if (!get_state_tid) {
|
||||
printk("ERROR spawning poll_state_thread\n");
|
||||
printf("ERROR spawning poll_state_thread\n");
|
||||
}
|
||||
|
||||
can_register_state_change_isr(can_dev, state_change_isr);
|
||||
can_set_state_change_callback(can_dev, state_change_callback, &state_change_work);
|
||||
|
||||
printk("Finished init.\n");
|
||||
printf("Finished init.\n");
|
||||
|
||||
while (1) {
|
||||
change_led_frame.data[0] = toggle++ & 0x01 ? SET_LED : RESET_LED;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
CONFIG_POLL=y
|
||||
CONFIG_CAN=y
|
||||
CONFIG_CAN_INIT_PRIORITY=80
|
||||
CONFIG_CAN_MAX_FILTER=5
|
||||
@@ -5,3 +6,9 @@ CONFIG_CAN_MAX_FILTER=5
|
||||
CONFIG_SHELL=y
|
||||
CONFIG_CAN_SHELL=y
|
||||
CONFIG_DEVICE_SHELL=y
|
||||
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_STATS=y
|
||||
CONFIG_STATS_NAMES=y
|
||||
CONFIG_STATS_SHELL=y
|
||||
CONFIG_CAN_STATS=y
|
||||
|
||||
1
examples/zephyr-net-civetweb/.gitignore
vendored
1
examples/zephyr-net-civetweb/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
.pio
|
||||
@@ -1,33 +0,0 @@
|
||||
.. Copyright 2019-present PlatformIO <contact@platformio.org>
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
How to build PlatformIO based project
|
||||
=====================================
|
||||
|
||||
1. [Install PlatformIO Core](https://docs.platformio.org/page/core.html)
|
||||
2. Download [development platform with examples](https://github.com/platformio/platform-ststm32/archive/develop.zip)
|
||||
3. Extract ZIP archive
|
||||
4. Change IP configuration in platform-ststm32/examples/zephyr-net-civetweb/zephyr/prj.conf file. Default server IPv4 address: `10.0.0.111`
|
||||
5. Run these commands:
|
||||
|
||||
```shell
|
||||
# Change directory to example
|
||||
$ cd platform-ststm32/examples/zephyr-net-civetweb
|
||||
|
||||
# Build project
|
||||
$ pio run
|
||||
|
||||
# Upload firmware
|
||||
$ pio run --target upload
|
||||
|
||||
# Clean build files
|
||||
$ pio run --target clean
|
||||
```
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Antmicro Ltd
|
||||
* Copyright (c) 2020 Alexander Kozhinov <AlexanderKozhinov@yandex.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
static void log_access(const struct mg_connection *conn)
|
||||
{
|
||||
const struct mg_request_info *ri;
|
||||
char src_addr[IP_ADDR_STR_LEN];
|
||||
|
||||
if (!conn || !conn->dom_ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
ri = &conn->request_info;
|
||||
|
||||
sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
|
||||
|
||||
LOG_DBG("%s - \"%s %s%s%s HTTP/%s\" %d\n",
|
||||
STR_LOG_ALLOC(src_addr),
|
||||
STR_LOG_ALLOC(ri->request_method),
|
||||
STR_LOG_ALLOC(ri->request_uri),
|
||||
(ri->query_string == NULL) ? log_strdup("?") : log_strdup(""),
|
||||
STR_LOG_ALLOC(ri->query_string),
|
||||
STR_LOG_ALLOC(ri->http_version),
|
||||
conn->status_code);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Antmicro Ltd
|
||||
* Copyright (c) 2020 Alexander Kozhinov <AlexanderKozhinov@yandex.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(mg_cry_internal_impl, LOG_LEVEL_DBG);
|
||||
|
||||
#include "helper.h"
|
||||
|
||||
static void mg_cry_internal_impl(const struct mg_connection *conn,
|
||||
const char *func,
|
||||
unsigned line,
|
||||
const char *fmt,
|
||||
va_list ap)
|
||||
{
|
||||
(void)conn;
|
||||
|
||||
LOG_ERR("%s @ %d in civetweb.c", STR_LOG_ALLOC(func), line);
|
||||
vprintf(fmt, ap);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Alexander Kozhinov Mail: <AlexanderKozhinov@yandex.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __HELPER__
|
||||
#define __HELPER__
|
||||
|
||||
#include <logging/log.h>
|
||||
|
||||
#define STR_LOG_ALLOC(str) ((str == NULL) ? log_strdup("null") :\
|
||||
log_strdup(str))
|
||||
|
||||
#endif /* __HELPER__ */
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Antmicro Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/socket.h>
|
||||
|
||||
#define pollfd zsock_pollfd
|
||||
#define fcntl zsock_fcntl
|
||||
|
||||
#define POLLIN ZSOCK_POLLIN
|
||||
#define POLLOUT ZSOCK_POLLOUT
|
||||
|
||||
#define addrinfo zsock_addrinfo
|
||||
|
||||
#define F_SETFD 2
|
||||
#define FD_CLOEXEC 1
|
||||
|
||||
size_t strcspn(const char *s1, const char *s2);
|
||||
size_t strspn(const char *s1, const char *s2);
|
||||
int iscntrl(int c);
|
||||
|
||||
double atof(const char *str);
|
||||
long long strtoll(const char *str, char **endptr, int base);
|
||||
int sscanf(const char *s, const char *format, ...);
|
||||
char *strerror(int err);
|
||||
unsigned long long strtoull(const char *str, char **endptr, int base);
|
||||
|
||||
time_t time(time_t *t);
|
||||
struct tm *gmtime(const time_t *ptime);
|
||||
size_t strftime(char *dst, size_t dst_size, const char *fmt,
|
||||
const struct tm *tm);
|
||||
double difftime(time_t end, time_t beg);
|
||||
struct tm *localtime(const time_t *timer);
|
||||
|
||||
int fileno(FILE *stream);
|
||||
int ferror(FILE *stream);
|
||||
int fclose(FILE *stream);
|
||||
int fseeko(FILE *stream, off_t offset, int whence);
|
||||
FILE *fopen(const char *filename, const char *mode);
|
||||
char *fgets(char *str, int num, FILE *stream);
|
||||
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
|
||||
int remove(const char *filename);
|
||||
|
||||
int getsockname(int sock, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int poll(struct zsock_pollfd *fds, int nfds, int timeout);
|
||||
|
||||
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
|
||||
char *host, socklen_t hostlen,
|
||||
char *serv, socklen_t servlen, int flags);
|
||||
|
||||
ssize_t send(int sock, const void *buf, size_t len, int flags);
|
||||
ssize_t recv(int sock, void *buf, size_t max_len, int flags);
|
||||
int socket(int family, int type, int proto);
|
||||
int getaddrinfo(const char *host, const char *service,
|
||||
const struct zsock_addrinfo *hints,
|
||||
struct zsock_addrinfo **res);
|
||||
|
||||
void freeaddrinfo(struct zsock_addrinfo *ai);
|
||||
int connect(int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||
int getsockopt(int sock, int level, int optname,
|
||||
void *optval, socklen_t *optlen);
|
||||
int setsockopt(int sock, int level, int optname,
|
||||
const void *optval, socklen_t optlen);
|
||||
int listen(int sock, int backlog);
|
||||
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int bind(int sock, const struct sockaddr *addr, socklen_t addrlen);
|
||||
@@ -1,46 +0,0 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
@@ -1,13 +0,0 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter, extra scripting
|
||||
; Upload options: custom port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nucleo_f767zi]
|
||||
platform = ststm32
|
||||
framework = zephyr
|
||||
board = nucleo_f767zi
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Antmicro Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(lib_extensions, LOG_LEVEL_DBG);
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libc_extensions.h"
|
||||
|
||||
#define FN_MISSING() LOG_DBG("[IMPLEMENTATION MISSING : %s]\n", __func__)
|
||||
|
||||
int iscntrl(int c)
|
||||
{
|
||||
/* All the characters placed before the space on the ASCII table
|
||||
* and the 0x7F character (DEL) are control characters.
|
||||
*/
|
||||
return (int)(c < ' ' || c == 0x7F);
|
||||
}
|
||||
|
||||
size_t strftime(char *dst, size_t dst_size,
|
||||
const char *fmt,
|
||||
const struct tm *tm)
|
||||
{
|
||||
FN_MISSING();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double difftime(time_t end, time_t beg)
|
||||
{
|
||||
return end - beg;
|
||||
}
|
||||
|
||||
struct __strerr_wrap {
|
||||
int err;
|
||||
const char *errstr;
|
||||
};
|
||||
|
||||
/* Implementation suggested by @rakons in #16527 */
|
||||
#define STRERR_DEFINE(e) {e, #e}
|
||||
|
||||
static const struct __strerr_wrap error_strings[] = {
|
||||
STRERR_DEFINE(EILSEQ),
|
||||
STRERR_DEFINE(EDOM),
|
||||
STRERR_DEFINE(ERANGE),
|
||||
STRERR_DEFINE(ENOTTY),
|
||||
STRERR_DEFINE(EACCES),
|
||||
STRERR_DEFINE(EPERM),
|
||||
STRERR_DEFINE(ENOENT),
|
||||
STRERR_DEFINE(ESRCH),
|
||||
STRERR_DEFINE(EEXIST),
|
||||
STRERR_DEFINE(ENOSPC),
|
||||
STRERR_DEFINE(ENOMEM),
|
||||
STRERR_DEFINE(EBUSY),
|
||||
STRERR_DEFINE(EINTR),
|
||||
STRERR_DEFINE(EAGAIN),
|
||||
STRERR_DEFINE(ESPIPE),
|
||||
STRERR_DEFINE(EXDEV),
|
||||
STRERR_DEFINE(EROFS),
|
||||
STRERR_DEFINE(ENOTEMPTY),
|
||||
STRERR_DEFINE(ECONNRESET),
|
||||
STRERR_DEFINE(ETIMEDOUT),
|
||||
STRERR_DEFINE(ECONNREFUSED),
|
||||
STRERR_DEFINE(EHOSTDOWN),
|
||||
STRERR_DEFINE(EHOSTUNREACH),
|
||||
STRERR_DEFINE(EADDRINUSE),
|
||||
STRERR_DEFINE(EPIPE),
|
||||
STRERR_DEFINE(EIO),
|
||||
STRERR_DEFINE(ENXIO),
|
||||
STRERR_DEFINE(ENOTBLK),
|
||||
STRERR_DEFINE(ENODEV),
|
||||
STRERR_DEFINE(ENOTDIR),
|
||||
STRERR_DEFINE(EISDIR),
|
||||
STRERR_DEFINE(ETXTBSY),
|
||||
STRERR_DEFINE(ENOEXEC),
|
||||
STRERR_DEFINE(EINVAL),
|
||||
STRERR_DEFINE(E2BIG),
|
||||
STRERR_DEFINE(ELOOP),
|
||||
STRERR_DEFINE(ENAMETOOLONG),
|
||||
STRERR_DEFINE(ENFILE),
|
||||
STRERR_DEFINE(EMFILE),
|
||||
STRERR_DEFINE(EBADF),
|
||||
STRERR_DEFINE(ECHILD),
|
||||
STRERR_DEFINE(EFAULT),
|
||||
STRERR_DEFINE(EFBIG),
|
||||
STRERR_DEFINE(EMLINK),
|
||||
STRERR_DEFINE(ENOLCK),
|
||||
STRERR_DEFINE(EDEADLK),
|
||||
STRERR_DEFINE(ECANCELED),
|
||||
STRERR_DEFINE(ENOSYS),
|
||||
STRERR_DEFINE(ENOMSG),
|
||||
STRERR_DEFINE(ENOSTR),
|
||||
STRERR_DEFINE(ENODATA),
|
||||
STRERR_DEFINE(ETIME),
|
||||
STRERR_DEFINE(ENOSR),
|
||||
STRERR_DEFINE(EPROTO),
|
||||
STRERR_DEFINE(EBADMSG),
|
||||
STRERR_DEFINE(ENOTSOCK),
|
||||
STRERR_DEFINE(EDESTADDRREQ),
|
||||
STRERR_DEFINE(EMSGSIZE),
|
||||
STRERR_DEFINE(EPROTOTYPE),
|
||||
STRERR_DEFINE(ENOPROTOOPT),
|
||||
STRERR_DEFINE(EPROTONOSUPPORT),
|
||||
STRERR_DEFINE(ESOCKTNOSUPPORT),
|
||||
STRERR_DEFINE(ENOTSUP),
|
||||
STRERR_DEFINE(EPFNOSUPPORT),
|
||||
STRERR_DEFINE(EAFNOSUPPORT),
|
||||
STRERR_DEFINE(EADDRNOTAVAIL),
|
||||
STRERR_DEFINE(ENETDOWN),
|
||||
STRERR_DEFINE(ENETUNREACH),
|
||||
STRERR_DEFINE(ENETRESET),
|
||||
STRERR_DEFINE(ECONNABORTED),
|
||||
STRERR_DEFINE(ENOBUFS),
|
||||
STRERR_DEFINE(EISCONN),
|
||||
STRERR_DEFINE(ENOTCONN),
|
||||
STRERR_DEFINE(ESHUTDOWN),
|
||||
STRERR_DEFINE(EALREADY),
|
||||
STRERR_DEFINE(EINPROGRESS),
|
||||
};
|
||||
|
||||
static char *strerr_unknown = "UNKNOWN";
|
||||
|
||||
char *strerror(int err)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(error_strings); ++i) {
|
||||
if (error_strings[i].err == err) {
|
||||
return (char *)error_strings[i].errstr;
|
||||
}
|
||||
}
|
||||
|
||||
return strerr_unknown;
|
||||
}
|
||||
|
||||
int sscanf(const char *s, const char *format, ...)
|
||||
{
|
||||
FN_MISSING();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double atof(const char *str)
|
||||
{
|
||||
/* XXX good enough for civetweb uses */
|
||||
return (double)atoi(str);
|
||||
}
|
||||
|
||||
long long strtoll(const char *str, char **endptr, int base)
|
||||
{
|
||||
/* XXX good enough for civetweb uses */
|
||||
return (long long)strtol(str, endptr, base);
|
||||
}
|
||||
|
||||
/*
|
||||
* Most of the wrappers below are copies of the wrappers in net/sockets.h,
|
||||
* but they are available only if CONFIG_NET_SOCKETS_POSIX_NAMES is enabled
|
||||
* which is impossible here.
|
||||
*/
|
||||
|
||||
int getsockname(int sock, struct sockaddr *addr,
|
||||
socklen_t *addrlen)
|
||||
{
|
||||
return zsock_getsockname(sock, addr, addrlen);
|
||||
}
|
||||
|
||||
int poll(struct zsock_pollfd *fds, int nfds, int timeout)
|
||||
{
|
||||
return zsock_poll(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
|
||||
char *host, socklen_t hostlen,
|
||||
char *serv, socklen_t servlen, int flags)
|
||||
{
|
||||
return zsock_getnameinfo(addr, addrlen, host, hostlen,
|
||||
serv, servlen, flags);
|
||||
}
|
||||
|
||||
ssize_t send(int sock, const void *buf, size_t len, int flags)
|
||||
{
|
||||
return zsock_send(sock, buf, len, flags);
|
||||
}
|
||||
|
||||
ssize_t recv(int sock, void *buf, size_t max_len, int flags)
|
||||
{
|
||||
return zsock_recv(sock, buf, max_len, flags);
|
||||
}
|
||||
|
||||
int socket(int family, int type, int proto)
|
||||
{
|
||||
return zsock_socket(family, type, proto);
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *host, const char *service,
|
||||
const struct zsock_addrinfo *hints,
|
||||
struct zsock_addrinfo **res)
|
||||
{
|
||||
return zsock_getaddrinfo(host, service, hints, res);
|
||||
}
|
||||
|
||||
void freeaddrinfo(struct zsock_addrinfo *ai)
|
||||
{
|
||||
zsock_freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
int connect(int sock, const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
return zsock_connect(sock, addr, addrlen);
|
||||
}
|
||||
|
||||
int getsockopt(int sock, int level, int optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
return zsock_getsockopt(sock, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int setsockopt(int sock, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
return zsock_setsockopt(sock, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int listen(int sock, int backlog)
|
||||
{
|
||||
return zsock_listen(sock, backlog);
|
||||
}
|
||||
|
||||
int bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
return zsock_bind(sock, addr, addrlen);
|
||||
}
|
||||
|
||||
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
return zsock_accept(sock, addr, addrlen);
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Antmicro Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <posix/pthread.h>
|
||||
#include <data/json.h>
|
||||
|
||||
#include "civetweb.h"
|
||||
|
||||
#define HTTP_PORT 8080
|
||||
#define HTTPS_PORT 4443
|
||||
|
||||
#define CIVETWEB_MAIN_THREAD_STACK_SIZE CONFIG_MAIN_STACK_SIZE
|
||||
|
||||
/* Use samllest possible value of 1024 (see the line 18619 of civetweb.c) */
|
||||
#define MAX_REQUEST_SIZE_BYTES 1024
|
||||
|
||||
K_THREAD_STACK_DEFINE(civetweb_stack, CIVETWEB_MAIN_THREAD_STACK_SIZE);
|
||||
|
||||
struct civetweb_info {
|
||||
const char *version;
|
||||
const char *os;
|
||||
uint32_t features;
|
||||
const char *feature_list;
|
||||
const char *build;
|
||||
const char *compiler;
|
||||
const char *data_model;
|
||||
};
|
||||
|
||||
#define FIELD(struct_, member_, type_) { \
|
||||
.field_name = #member_, \
|
||||
.field_name_len = sizeof(#member_) - 1, \
|
||||
.offset = offsetof(struct_, member_), \
|
||||
.type = type_ \
|
||||
}
|
||||
|
||||
void send_ok(struct mg_connection *conn)
|
||||
{
|
||||
mg_printf(conn,
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/html\r\n"
|
||||
"Connection: close\r\n\r\n");
|
||||
}
|
||||
|
||||
int hello_world_handler(struct mg_connection *conn, void *cbdata)
|
||||
{
|
||||
send_ok(conn);
|
||||
mg_printf(conn, "<html><body>");
|
||||
mg_printf(conn, "<h3>Hello World from Zephyr!</h3>");
|
||||
mg_printf(conn, "See also:\n");
|
||||
mg_printf(conn, "<ul>\n");
|
||||
mg_printf(conn, "<li><a href=/info>system info</a></li>\n");
|
||||
mg_printf(conn, "<li><a href=/history>cookie demo</a></li>\n");
|
||||
mg_printf(conn, "</ul>\n");
|
||||
mg_printf(conn, "</body></html>\n");
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int system_info_handler(struct mg_connection *conn, void *cbdata)
|
||||
{
|
||||
static const struct json_obj_descr descr[] = {
|
||||
FIELD(struct civetweb_info, version, JSON_TOK_STRING),
|
||||
FIELD(struct civetweb_info, os, JSON_TOK_STRING),
|
||||
FIELD(struct civetweb_info, feature_list, JSON_TOK_STRING),
|
||||
FIELD(struct civetweb_info, build, JSON_TOK_STRING),
|
||||
FIELD(struct civetweb_info, compiler, JSON_TOK_STRING),
|
||||
FIELD(struct civetweb_info, data_model, JSON_TOK_STRING),
|
||||
};
|
||||
|
||||
struct civetweb_info info = {};
|
||||
char info_str[1024] = {};
|
||||
int ret;
|
||||
int size;
|
||||
|
||||
size = mg_get_system_info(info_str, sizeof(info_str));
|
||||
|
||||
ret = json_obj_parse(info_str, size, descr, ARRAY_SIZE(descr), &info);
|
||||
|
||||
send_ok(conn);
|
||||
|
||||
if (ret < 0) {
|
||||
mg_printf(conn, "Could not retrieve: %d\n", ret);
|
||||
return 500;
|
||||
}
|
||||
|
||||
|
||||
mg_printf(conn, "<html><body>");
|
||||
|
||||
mg_printf(conn, "<h3>Server info</h3>");
|
||||
mg_printf(conn, "<ul>\n");
|
||||
mg_printf(conn, "<li>host os - %s</li>\n", info.os);
|
||||
mg_printf(conn, "<li>server - civetweb %s</li>\n", info.version);
|
||||
mg_printf(conn, "<li>compiler - %s</li>\n", info.compiler);
|
||||
mg_printf(conn, "<li>board - %s</li>\n", CONFIG_BOARD);
|
||||
mg_printf(conn, "</ul>\n");
|
||||
|
||||
mg_printf(conn, "</body></html>\n");
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int history_handler(struct mg_connection *conn, void *cbdata)
|
||||
{
|
||||
const struct mg_request_info *req_info = mg_get_request_info(conn);
|
||||
const char *cookie = mg_get_header(conn, "Cookie");
|
||||
char history_str[64];
|
||||
|
||||
mg_get_cookie(cookie, "history", history_str, sizeof(history_str));
|
||||
|
||||
mg_printf(conn, "HTTP/1.1 200 OK\r\n");
|
||||
mg_printf(conn, "Connection: close\r\n");
|
||||
mg_printf(conn, "Set-Cookie: history='%s'\r\n", req_info->local_uri);
|
||||
mg_printf(conn, "Content-Type: text/html\r\n\r\n");
|
||||
|
||||
mg_printf(conn, "<html><body>");
|
||||
|
||||
mg_printf(conn, "<h3>Your URI is: %s<h3>\n", req_info->local_uri);
|
||||
|
||||
if (history_str[0] == 0) {
|
||||
mg_printf(conn, "<h5>This is your first visit.</h5>\n");
|
||||
} else {
|
||||
mg_printf(conn, "<h5>your last /history visit was: %s</h5>\n",
|
||||
history_str);
|
||||
}
|
||||
|
||||
mg_printf(conn, "Some cookie-saving links to try:\n");
|
||||
mg_printf(conn, "<ul>\n");
|
||||
mg_printf(conn, "<li><a href=/history/first>first</a></li>\n");
|
||||
mg_printf(conn, "<li><a href=/history/second>second</a></li>\n");
|
||||
mg_printf(conn, "<li><a href=/history/third>third</a></li>\n");
|
||||
mg_printf(conn, "<li><a href=/history/fourth>fourth</a></li>\n");
|
||||
mg_printf(conn, "<li><a href=/history/fifth>fifth</a></li>\n");
|
||||
mg_printf(conn, "</ul>\n");
|
||||
|
||||
mg_printf(conn, "</body></html>\n");
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
void *main_pthread(void *arg)
|
||||
{
|
||||
static const char * const options[] = {
|
||||
"listening_ports",
|
||||
STRINGIFY(HTTP_PORT),
|
||||
"num_threads",
|
||||
"1",
|
||||
"max_request_size",
|
||||
STRINGIFY(MAX_REQUEST_SIZE_BYTES),
|
||||
NULL
|
||||
};
|
||||
|
||||
struct mg_callbacks callbacks;
|
||||
struct mg_context *ctx;
|
||||
|
||||
(void)arg;
|
||||
|
||||
memset(&callbacks, 0, sizeof(callbacks));
|
||||
ctx = mg_start(&callbacks, 0, (const char **)options);
|
||||
|
||||
if (ctx == NULL) {
|
||||
printf("Unable to start the server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mg_set_request_handler(ctx, "/$", hello_world_handler, 0);
|
||||
mg_set_request_handler(ctx, "/info$", system_info_handler, 0);
|
||||
mg_set_request_handler(ctx, "/history", history_handler, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
pthread_attr_t civetweb_attr;
|
||||
pthread_t civetweb_thread;
|
||||
|
||||
(void)pthread_attr_init(&civetweb_attr);
|
||||
(void)pthread_attr_setstack(&civetweb_attr, &civetweb_stack,
|
||||
CIVETWEB_MAIN_THREAD_STACK_SIZE);
|
||||
|
||||
(void)pthread_create(&civetweb_thread, &civetweb_attr,
|
||||
&main_pthread, 0);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
This directory is intended for PIO Unit Testing and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PIO Unit Testing:
|
||||
- https://docs.platformio.org/page/plus/unit-testing.html
|
||||
@@ -1,15 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
|
||||
set (CONF_FILE "prj.conf")
|
||||
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(civetweb-server)
|
||||
|
||||
FILE(GLOB app_sources ../src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
||||
|
||||
zephyr_include_directories(../include)
|
||||
|
||||
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)
|
||||
@@ -1,36 +0,0 @@
|
||||
# General config
|
||||
CONFIG_CIVETWEB=y
|
||||
CONFIG_JSON_LIBRARY=y
|
||||
|
||||
# pthreads
|
||||
CONFIG_POSIX_API=y
|
||||
CONFIG_PTHREAD_IPC=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
|
||||
# networking
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_IPV4=y
|
||||
# CONFIG_NET_IPV6 is not set
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_NET_SOCKETS=y
|
||||
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=16384
|
||||
CONFIG_NET_TX_STACK_SIZE=2048
|
||||
CONFIG_NET_RX_STACK_SIZE=2048
|
||||
CONFIG_ISR_STACK_SIZE=2048
|
||||
CONFIG_MAIN_STACK_SIZE=2048
|
||||
CONFIG_IDLE_STACK_SIZE=1024
|
||||
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
|
||||
CONFIG_NET_CONFIG_SETTINGS=y
|
||||
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
|
||||
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
|
||||
CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"
|
||||
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2"
|
||||
|
||||
# logging
|
||||
CONFIG_NET_LOG=y
|
||||
|
||||
# Do not include mbedtls via this option as civetweb does not
|
||||
# work properly with mbedtls.
|
||||
CONFIG_NET_TCP_ISN_RFC6528=n
|
||||
@@ -4,13 +4,13 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <logging/log.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(net_http_client_sample, LOG_LEVEL_DBG);
|
||||
|
||||
#include <net/net_ip.h>
|
||||
#include <net/socket.h>
|
||||
#include <net/tls_credentials.h>
|
||||
#include <net/http_client.h>
|
||||
#include <zephyr/net/net_ip.h>
|
||||
#include <zephyr/net/socket.h>
|
||||
#include <zephyr/net/tls_credentials.h>
|
||||
#include <zephyr/net/http/client.h>
|
||||
|
||||
#include "ca_certificate.h"
|
||||
|
||||
@@ -356,7 +356,7 @@ static int run_queries(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
int main(void)
|
||||
{
|
||||
int iterations = CONFIG_NET_SAMPLE_SEND_ITERATIONS;
|
||||
int i = 0;
|
||||
@@ -383,4 +383,5 @@ void main(void)
|
||||
}
|
||||
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,66 +4,52 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <zephyr.h>
|
||||
#include <device.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
#include <usb/usb_device.h>
|
||||
#include <usb/class/usb_hid.h>
|
||||
#include <zephyr/usb/usb_device.h>
|
||||
#include <zephyr/usb/class/usb_hid.h>
|
||||
|
||||
#define LOG_LEVEL LOG_LEVEL_DBG
|
||||
LOG_MODULE_REGISTER(main);
|
||||
|
||||
/*
|
||||
* Devicetree node identifiers for the buttons and LED this sample
|
||||
* supports.
|
||||
*/
|
||||
#define SW0_NODE DT_ALIAS(sw0)
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW0_NODE, okay)
|
||||
#define PORT0 DT_GPIO_LABEL(SW0_NODE, gpios)
|
||||
#define PIN0 DT_GPIO_PIN(SW0_NODE, gpios)
|
||||
#define PIN0_FLAGS DT_GPIO_FLAGS(SW0_NODE, gpios)
|
||||
#else
|
||||
#error "Unsupported board: sw0 devicetree alias is not defined"
|
||||
#define PORT0 ""
|
||||
#define PIN0 0
|
||||
#define PIN0_FLAGS 0
|
||||
#endif
|
||||
|
||||
#define SW1_NODE DT_ALIAS(sw1)
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
|
||||
#define PORT1 DT_GPIO_LABEL(SW1_NODE, gpios)
|
||||
#define PIN1 DT_GPIO_PIN(SW1_NODE, gpios)
|
||||
#define PIN1_FLAGS DT_GPIO_FLAGS(SW1_NODE, gpios)
|
||||
#endif
|
||||
|
||||
#define SW2_NODE DT_ALIAS(sw2)
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW2_NODE, okay)
|
||||
#define PORT2 DT_GPIO_LABEL(SW2_NODE, gpios)
|
||||
#define PIN2 DT_GPIO_PIN(SW2_NODE, gpios)
|
||||
#define PIN2_FLAGS DT_GPIO_FLAGS(SW2_NODE, gpios)
|
||||
#endif
|
||||
|
||||
#define SW3_NODE DT_ALIAS(sw3)
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW3_NODE, okay)
|
||||
#define PORT3 DT_GPIO_LABEL(SW3_NODE, gpios)
|
||||
#define PIN3 DT_GPIO_PIN(SW3_NODE, gpios)
|
||||
#define PIN3_FLAGS DT_GPIO_FLAGS(SW3_NODE, gpios)
|
||||
#endif
|
||||
|
||||
#define LED0_NODE DT_ALIAS(led0)
|
||||
|
||||
#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
|
||||
#define LED_PORT DT_GPIO_LABEL(LED0_NODE, gpios)
|
||||
#define LED DT_GPIO_PIN(LED0_NODE, gpios)
|
||||
#define LED_FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
|
||||
#else
|
||||
#error "Unsupported board: led0 devicetree alias is not defined"
|
||||
#define LED_PORT ""
|
||||
#define LED 0
|
||||
#define LED_FLAGS 0
|
||||
/*
|
||||
* Button sw0 and LED led0 are required.
|
||||
*/
|
||||
#if !DT_NODE_EXISTS(SW0_NODE)
|
||||
#error "Unsupported board: sw0 devicetree alias is not defined"
|
||||
#endif
|
||||
|
||||
#if !DT_NODE_EXISTS(LED0_NODE)
|
||||
#error "Unsupported board: led0 devicetree alias is not defined"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper macro for initializing a gpio_dt_spec from the devicetree
|
||||
* with fallback values when the nodes are missing.
|
||||
*/
|
||||
#define GPIO_SPEC(node_id) GPIO_DT_SPEC_GET_OR(node_id, gpios, {0})
|
||||
|
||||
/*
|
||||
* Create gpio_dt_spec structures from the devicetree.
|
||||
*/
|
||||
static const struct gpio_dt_spec sw0 = GPIO_SPEC(SW0_NODE),
|
||||
sw1 = GPIO_SPEC(SW1_NODE),
|
||||
sw2 = GPIO_SPEC(SW2_NODE),
|
||||
sw3 = GPIO_SPEC(SW3_NODE),
|
||||
led0 = GPIO_SPEC(LED0_NODE);
|
||||
|
||||
static const uint8_t hid_report_desc[] = HID_MOUSE_REPORT_DESC(2);
|
||||
|
||||
static uint8_t def_val[4];
|
||||
@@ -80,8 +66,6 @@ static enum usb_dc_status_code usb_status;
|
||||
#define MOUSE_BTN_RIGHT BIT(1)
|
||||
#define MOUSE_BTN_MIDDLE BIT(2)
|
||||
|
||||
|
||||
|
||||
static void status_cb(enum usb_dc_status_code status, const uint8_t *param)
|
||||
{
|
||||
usb_status = status;
|
||||
@@ -100,10 +84,10 @@ static void left_button(const struct device *gpio, struct gpio_callback *cb,
|
||||
}
|
||||
}
|
||||
|
||||
ret = gpio_pin_get(gpio, PIN0);
|
||||
ret = gpio_pin_get(gpio, sw0.pin);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to get the state of pin %u, error: %d",
|
||||
PIN0, ret);
|
||||
LOG_ERR("Failed to get the state of port %s pin %u, error: %d",
|
||||
gpio->name, sw0.pin, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +103,6 @@ static void left_button(const struct device *gpio, struct gpio_callback *cb,
|
||||
}
|
||||
}
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
|
||||
static void right_button(const struct device *gpio, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
@@ -133,10 +116,10 @@ static void right_button(const struct device *gpio, struct gpio_callback *cb,
|
||||
}
|
||||
}
|
||||
|
||||
ret = gpio_pin_get(gpio, PIN1);
|
||||
ret = gpio_pin_get(gpio, sw1.pin);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to get the state of pin %u, error: %d",
|
||||
PIN1, ret);
|
||||
LOG_ERR("Failed to get the state of port %s pin %u, error: %d",
|
||||
gpio->name, sw1.pin, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -151,19 +134,17 @@ static void right_button(const struct device *gpio, struct gpio_callback *cb,
|
||||
k_sem_give(&sem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW2_NODE, okay)
|
||||
static void x_move(const struct device *gpio, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
int ret;
|
||||
uint8_t state = status[MOUSE_X_REPORT_POS];
|
||||
|
||||
ret = gpio_pin_get(gpio, PIN2);
|
||||
ret = gpio_pin_get(gpio, sw2.pin);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to get the state of pin %u, error: %d",
|
||||
PIN2, ret);
|
||||
LOG_ERR("Failed to get the state of port %s pin %u, error: %d",
|
||||
gpio->name, sw2.pin, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -176,19 +157,17 @@ static void x_move(const struct device *gpio, struct gpio_callback *cb,
|
||||
k_sem_give(&sem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW3_NODE, okay)
|
||||
static void y_move(const struct device *gpio, struct gpio_callback *cb,
|
||||
uint32_t pins)
|
||||
{
|
||||
int ret;
|
||||
uint8_t state = status[MOUSE_Y_REPORT_POS];
|
||||
|
||||
ret = gpio_pin_get(gpio, PIN3);
|
||||
ret = gpio_pin_get(gpio, sw3.pin);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to get the state of pin %u, error: %d",
|
||||
PIN3, ret);
|
||||
LOG_ERR("Failed to get the state of port %s pin %u, error: %d",
|
||||
gpio->name, sw3.pin, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -201,30 +180,36 @@ static void y_move(const struct device *gpio, struct gpio_callback *cb,
|
||||
k_sem_give(&sem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int callbacks_configure(const struct device *gpio, uint32_t pin, int flags,
|
||||
int callbacks_configure(const struct gpio_dt_spec *spec,
|
||||
gpio_callback_handler_t handler,
|
||||
struct gpio_callback *callback, uint8_t *val)
|
||||
{
|
||||
const struct device *gpio = spec->port;
|
||||
gpio_pin_t pin = spec->pin;
|
||||
int ret;
|
||||
|
||||
if (!gpio) {
|
||||
LOG_ERR("Could not find PORT");
|
||||
return -ENXIO;
|
||||
if (gpio == NULL) {
|
||||
/* Optional GPIO is missing. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure(gpio, pin, GPIO_INPUT | flags);
|
||||
if (!device_is_ready(gpio)) {
|
||||
LOG_ERR("GPIO port %s is not ready", gpio->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure_dt(spec, GPIO_INPUT);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to configure pin %u, error: %d",
|
||||
pin, ret);
|
||||
LOG_ERR("Failed to configure port %s pin %u, error: %d",
|
||||
gpio->name, pin, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpio_pin_get(gpio, pin);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to get the state of pin %u, error: %d",
|
||||
pin, ret);
|
||||
LOG_ERR("Failed to get the state of port %s pin %u, error: %d",
|
||||
gpio->name, pin, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -233,74 +218,67 @@ int callbacks_configure(const struct device *gpio, uint32_t pin, int flags,
|
||||
gpio_init_callback(callback, handler, BIT(pin));
|
||||
ret = gpio_add_callback(gpio, callback);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to add the callback for pin %u, error: %d",
|
||||
pin, ret);
|
||||
LOG_ERR("Failed to add the callback for port %s pin %u, "
|
||||
"error: %d",
|
||||
gpio->name, pin, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpio_pin_interrupt_configure(gpio, pin, GPIO_INT_EDGE_BOTH);
|
||||
ret = gpio_pin_interrupt_configure_dt(spec, GPIO_INT_EDGE_BOTH);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to configure interrupt for pin %u, error: %d",
|
||||
pin, ret);
|
||||
LOG_ERR("Failed to configure interrupt for port %s pin %u, "
|
||||
"error: %d",
|
||||
gpio->name, pin, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
int main(void)
|
||||
{
|
||||
int ret;
|
||||
uint8_t report[4] = { 0x00 };
|
||||
const struct device *led_dev, *hid_dev;
|
||||
const struct device *hid_dev;
|
||||
|
||||
led_dev = device_get_binding(LED_PORT);
|
||||
if (led_dev == NULL) {
|
||||
LOG_ERR("Cannot get LED");
|
||||
return;
|
||||
if (!device_is_ready(led0.port)) {
|
||||
LOG_ERR("LED device %s is not ready", led0.port->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hid_dev = device_get_binding("HID_0");
|
||||
if (hid_dev == NULL) {
|
||||
LOG_ERR("Cannot get USB HID Device");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure(led_dev, LED, GPIO_OUTPUT | LED_FLAGS);
|
||||
ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to configure the LED pin, error: %d", ret);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (callbacks_configure(device_get_binding(PORT0), PIN0, PIN0_FLAGS,
|
||||
&left_button, &callback[0], &def_val[0])) {
|
||||
if (callbacks_configure(&sw0, &left_button, &callback[0],
|
||||
&def_val[0])) {
|
||||
LOG_ERR("Failed configuring left button callback.");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
|
||||
if (callbacks_configure(device_get_binding(PORT1), PIN1, PIN1_FLAGS,
|
||||
&right_button, &callback[1], &def_val[1])) {
|
||||
if (callbacks_configure(&sw1, &right_button, &callback[1],
|
||||
&def_val[1])) {
|
||||
LOG_ERR("Failed configuring right button callback.");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW2_NODE, okay)
|
||||
if (callbacks_configure(device_get_binding(PORT2), PIN2, PIN2_FLAGS,
|
||||
&x_move, &callback[2], &def_val[2])) {
|
||||
if (callbacks_configure(&sw2, &x_move, &callback[2], &def_val[2])) {
|
||||
LOG_ERR("Failed configuring X axis movement callback.");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DT_NODE_HAS_STATUS(SW3_NODE, okay)
|
||||
if (callbacks_configure(device_get_binding(PORT3), PIN3, PIN3_FLAGS,
|
||||
&y_move, &callback[3], &def_val[3])) {
|
||||
if (callbacks_configure(&sw3, &y_move, &callback[3], &def_val[3])) {
|
||||
LOG_ERR("Failed configuring Y axis movement callback.");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
usb_hid_register_device(hid_dev,
|
||||
hid_report_desc, sizeof(hid_report_desc),
|
||||
@@ -311,7 +289,7 @@ void main(void)
|
||||
ret = usb_enable(status_cb);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to enable USB");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
@@ -328,9 +306,10 @@ void main(void)
|
||||
}
|
||||
|
||||
/* Toggle LED on sent report */
|
||||
ret = gpio_pin_toggle(led_dev, LED);
|
||||
ret = gpio_pin_toggle(led0.port, led0.pin);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to toggle the LED pin, error: %d", ret);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
CONFIG_USB_DEVICE_STACK=y
|
||||
CONFIG_USB_DEVICE_HID=y
|
||||
CONFIG_USB_DEVICE_PRODUCT="Zephyr HID mouse sample"
|
||||
CONFIG_USB_DEVICE_PID=0x0007
|
||||
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
|
||||
|
||||
CONFIG_LOG=y
|
||||
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
"type": "framework",
|
||||
"optional": true,
|
||||
"owner": "platformio",
|
||||
"version": "~2.20701.0"
|
||||
"version": "~2.30400.0"
|
||||
},
|
||||
"tool-stm32duino": {
|
||||
"type": "uploader",
|
||||
|
||||
23
platform.py
23
platform.py
@@ -12,15 +12,16 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from platformio.managers.platform import PlatformBase
|
||||
|
||||
|
||||
IS_WINDOWS = sys.platform.startswith("win")
|
||||
|
||||
|
||||
class Ststm32Platform(PlatformBase):
|
||||
|
||||
def configure_default_packages(self, variables, targets):
|
||||
@@ -89,7 +90,7 @@ class Ststm32Platform(PlatformBase):
|
||||
for p in self.packages:
|
||||
if p in ("tool-cmake", "tool-dtc", "tool-ninja"):
|
||||
self.packages[p]["optional"] = False
|
||||
self.packages["toolchain-gccarmnoneeabi"]["version"] = "~1.80201.0"
|
||||
self.packages["toolchain-gccarmnoneeabi"]["version"] = "~1.120301.0"
|
||||
if not IS_WINDOWS:
|
||||
self.packages["tool-gperf"]["optional"] = False
|
||||
|
||||
@@ -110,6 +111,24 @@ class Ststm32Platform(PlatformBase):
|
||||
return PlatformBase.configure_default_packages(self, variables,
|
||||
targets)
|
||||
|
||||
def install_package(self, name, *args, **kwargs):
|
||||
pkg = super().install_package(name, *args, **kwargs)
|
||||
if name != "framework-zephyr":
|
||||
return pkg
|
||||
|
||||
if not os.path.isfile(os.path.join(pkg.path, "_pio", "state.json")):
|
||||
self.pm.log.info("Installing Zephyr project dependencies...")
|
||||
try:
|
||||
subprocess.run([
|
||||
os.path.normpath(sys.executable),
|
||||
os.path.join(pkg.path, "scripts", "platformio", "install-deps.py"),
|
||||
"--platform", self.name
|
||||
])
|
||||
except subprocess.CalledProcessError:
|
||||
self.pm.log.info("Failed to install Zephyr dependencies!")
|
||||
|
||||
return pkg
|
||||
|
||||
def get_boards(self, id_=None):
|
||||
result = PlatformBase.get_boards(self, id_)
|
||||
if not result:
|
||||
|
||||
Reference in New Issue
Block a user