-
Notifications
You must be signed in to change notification settings - Fork 878
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b3a4b87
commit dab8d04
Showing
19 changed files
with
716 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) | ||
|
||
add_executable(pico_freertos_httpd_nosys | ||
pico_freertos_httpd.c | ||
) | ||
target_compile_definitions(pico_freertos_httpd_nosys PRIVATE | ||
WIFI_SSID=\"${WIFI_SSID}\" | ||
WIFI_PASSWORD=\"${WIFI_PASSWORD}\" | ||
) | ||
target_include_directories(pico_freertos_httpd_nosys PRIVATE | ||
${CMAKE_CURRENT_LIST_DIR} | ||
${CMAKE_CURRENT_LIST_DIR}/.. # for our common FreeRTOSConfig | ||
${CMAKE_CURRENT_LIST_DIR}/../.. # for our common lwipopts | ||
${PICO_LWIP_CONTRIB_PATH}/apps/httpd | ||
) | ||
target_link_libraries(pico_freertos_httpd_nosys | ||
pico_cyw43_arch_lwip_threadsafe_background | ||
pico_lwip_http | ||
pico_lwip_mdns | ||
pico_stdlib | ||
FreeRTOS-Kernel-Heap4 # FreeRTOS kernel and dynamic heap | ||
pico_freertos_httpd_content | ||
) | ||
pico_add_extra_outputs(pico_freertos_httpd_nosys) | ||
|
||
add_executable(pico_freertos_httpd_sys | ||
pico_freertos_httpd.c | ||
) | ||
target_compile_definitions(pico_freertos_httpd_sys PRIVATE | ||
WIFI_SSID=\"${WIFI_SSID}\" | ||
WIFI_PASSWORD=\"${WIFI_PASSWORD}\" | ||
NO_SYS=0 # don't want NO_SYS (generally this would be in your lwipopts.h) | ||
LWIP_SOCKET=1 # we need the socket API (generally this would be in your lwipopts.h) | ||
) | ||
target_include_directories(pico_freertos_httpd_sys PRIVATE | ||
${CMAKE_CURRENT_LIST_DIR} | ||
${CMAKE_CURRENT_LIST_DIR}/.. # for our common FreeRTOSConfig | ||
${CMAKE_CURRENT_LIST_DIR}/../.. # for our common lwipopts | ||
${PICO_LWIP_CONTRIB_PATH}/apps/httpd | ||
) | ||
target_link_libraries(pico_freertos_httpd_sys | ||
pico_cyw43_arch_lwip_sys_freertos | ||
pico_lwip_http | ||
pico_lwip_mdns | ||
pico_stdlib | ||
FreeRTOS-Kernel-Heap4 # FreeRTOS kernel and dynamic heap | ||
pico_freertos_httpd_content | ||
) | ||
pico_add_extra_outputs(pico_freertos_httpd_sys) | ||
|
||
pico_add_library(pico_freertos_httpd_content NOFLAG) | ||
pico_set_lwip_httpd_content(pico_freertos_httpd_content INTERFACE | ||
${CMAKE_CURRENT_LIST_DIR}/content/404.html | ||
${CMAKE_CURRENT_LIST_DIR}/content/index.shtml | ||
${CMAKE_CURRENT_LIST_DIR}/content/test.shtml | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#ifndef FREERTOS_CONFIG_H | ||
#define FREERTOS_CONFIG_H | ||
|
||
// This example uses a common include to avoid repetition | ||
#include "FreeRTOSConfig_examples_common.h" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<html> | ||
<head> | ||
<title>Pico httpd example</title> | ||
</head> | ||
<body> | ||
<h1>Pico httpd example</h1> | ||
<h2>404 - Page not found</h2> | ||
<p>Sorry, the page you are requesting was not found on this server. </p> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<html> | ||
<head> | ||
<title>Pico httpd example</title> | ||
</head> | ||
<body> | ||
<h1>Pico httpd example</h1> | ||
<p><!--#welcome--></p> | ||
<p>Uptime is <!--#uptime--> seconds</p> | ||
<p><a href="/?test">CGI test</a></p> | ||
<p>Led is <!--#ledstate--> click <a href="/?toggleled">here</a> to toggle the led | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<html> | ||
<head> | ||
<title>Pico cgi test</title> | ||
</head> | ||
<body> | ||
<h1>Pico cgi test</h1> | ||
<p><table><!--#table--></table></p> | ||
<p>Test result: <!--#status--></p> | ||
<p><a href="/">Go back</a></p> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#ifndef _LWIPOPTS_H | ||
#define _LWIPOPTS_H | ||
|
||
// Generally you would define your own explicit list of lwIP options | ||
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html) | ||
// | ||
// This example uses a common include to avoid repetition | ||
#include "lwipopts_examples_common.h" | ||
|
||
// The following is needed to test mDns | ||
#define LWIP_MDNS_RESPONDER 1 | ||
#define LWIP_IGMP 1 | ||
#define LWIP_NUM_NETIF_CLIENT_DATA 1 | ||
#define MDNS_RESP_USENETIF_EXTCALLBACK 1 | ||
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 3) | ||
#define MEMP_NUM_TCP_PCB 12 | ||
|
||
// Enable cgi and ssi | ||
#define LWIP_HTTPD_CGI 1 | ||
#define LWIP_HTTPD_SSI 1 | ||
#define LWIP_HTTPD_SSI_MULTIPART 1 | ||
|
||
#if !NO_SYS | ||
#define TCPIP_THREAD_STACKSIZE 2048 // mDNS needs more stack | ||
#define DEFAULT_THREAD_STACKSIZE 1024 | ||
#define DEFAULT_RAW_RECVMBOX_SIZE 8 | ||
#define TCPIP_MBOX_SIZE 8 | ||
#define LWIP_TIMEVAL_PRIVATE 0 | ||
|
||
// not necessary, can be done either way | ||
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 | ||
#endif | ||
|
||
#define HTTPD_FSDATA_FILE "pico_fsdata.inc" | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
/** | ||
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
#include "pico/cyw43_arch.h" | ||
#include "pico/stdlib.h" | ||
|
||
#include "lwip/ip4_addr.h" | ||
#include "lwip/apps/mdns.h" | ||
#include "lwip/init.h" | ||
#include "lwip/apps/httpd.h" | ||
|
||
#include "FreeRTOS.h" | ||
#include "task.h" | ||
|
||
void httpd_init(void); | ||
|
||
static absolute_time_t wifi_connected_time; | ||
static bool led_on = false; | ||
|
||
#ifndef RUN_FREERTOS_ON_CORE | ||
#define RUN_FREERTOS_ON_CORE 0 | ||
#endif | ||
|
||
#define TEST_TASK_PRIORITY ( tskIDLE_PRIORITY + 1UL ) | ||
|
||
#if LWIP_MDNS_RESPONDER | ||
static void srv_txt(struct mdns_service *service, void *txt_userdata) | ||
{ | ||
err_t res; | ||
LWIP_UNUSED_ARG(txt_userdata); | ||
|
||
res = mdns_resp_add_service_txtitem(service, "path=/", 6); | ||
LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return); | ||
} | ||
#endif | ||
|
||
// Return some characters from the ascii representation of the mac address | ||
// e.g. 112233445566 | ||
// chr_off is index of character in mac to start | ||
// chr_len is length of result | ||
// chr_off=8 and chr_len=4 would return "5566" | ||
// Return number of characters put into destination | ||
static size_t get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest_in) { | ||
static const char hexchr[16] = "0123456789ABCDEF"; | ||
uint8_t mac[6]; | ||
char *dest = dest_in; | ||
assert(chr_off + chr_len <= (2 * sizeof(mac))); | ||
cyw43_hal_get_mac(idx, mac); | ||
for (; chr_len && (chr_off >> 1) < sizeof(mac); ++chr_off, --chr_len) { | ||
*dest++ = hexchr[mac[chr_off >> 1] >> (4 * (1 - (chr_off & 1))) & 0xf]; | ||
} | ||
return dest - dest_in; | ||
} | ||
|
||
static const char *cgi_handler_test(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { | ||
if (!strcmp(pcParam[0], "test")) { | ||
return "/test.shtml"; | ||
} else if (strcmp(pcParam[0], "toggleled") == 0) { | ||
led_on = !led_on; | ||
cyw43_gpio_set(&cyw43_state, 0, led_on); | ||
} | ||
return "/index.shtml"; | ||
} | ||
|
||
static tCGI cgi_handlers[] = { | ||
{ "/", cgi_handler_test }, | ||
{ "/index.shtml", cgi_handler_test }, | ||
}; | ||
|
||
// Note that the buffer size is limited by LWIP_HTTPD_MAX_TAG_INSERT_LEN, so use LWIP_HTTPD_SSI_MULTIPART to return larger amounts of data | ||
u16_t ssi_example_ssi_handler(int iIndex, char *pcInsert, int iInsertLen | ||
#if LWIP_HTTPD_SSI_MULTIPART | ||
, uint16_t current_tag_part, uint16_t *next_tag_part | ||
#endif | ||
) { | ||
size_t printed; | ||
switch (iIndex) { | ||
case 0: { /* "status" */ | ||
printed = snprintf(pcInsert, iInsertLen, "Pass"); | ||
break; | ||
} | ||
case 1: { /* "welcome" */ | ||
printed = snprintf(pcInsert, iInsertLen, "Hello from Pico"); | ||
break; | ||
} | ||
case 2: { /* "uptime" */ | ||
uint64_t uptime_s = absolute_time_diff_us(wifi_connected_time, get_absolute_time()) / 1e6; | ||
printed = snprintf(pcInsert, iInsertLen, "%"PRIu64, uptime_s); | ||
break; | ||
} | ||
case 3: { // "ledstate" | ||
printed = snprintf(pcInsert, iInsertLen, "%s", led_on ? "ON" : "OFF"); | ||
break; | ||
} | ||
#if LWIP_HTTPD_SSI_MULTIPART | ||
case 4: { /* "table" */ | ||
printed = snprintf(pcInsert, iInsertLen, "<tr><td>This is table row number %d</td></tr>", current_tag_part + 1); | ||
// Leave "next_tag_part" unchanged to indicate that all data has been returned for this tag | ||
if (current_tag_part < 9) { | ||
*next_tag_part = current_tag_part + 1; | ||
} | ||
break; | ||
} | ||
#endif | ||
default: { /* unknown tag */ | ||
printed = 0; | ||
break; | ||
} | ||
} | ||
return (u16_t)printed; | ||
} | ||
|
||
// Be aware of LWIP_HTTPD_MAX_TAG_NAME_LEN | ||
static const char * ssi_tags[] = { | ||
"status", | ||
"welcome", | ||
"uptime", | ||
"ledstate", | ||
"table", | ||
}; | ||
|
||
void main_task(__unused void *params) { | ||
if (cyw43_arch_init()) { | ||
printf("failed to initialise\n"); | ||
return; | ||
} | ||
|
||
cyw43_arch_enable_sta_mode(); | ||
|
||
char hostname[sizeof(CYW43_HOST_NAME) + 4]; | ||
memcpy(&hostname[0], CYW43_HOST_NAME, sizeof(CYW43_HOST_NAME) - 1); | ||
get_mac_ascii(CYW43_HAL_MAC_WLAN0, 8, 4, &hostname[sizeof(CYW43_HOST_NAME) - 1]); | ||
hostname[sizeof(hostname) - 1] = '\0'; | ||
netif_set_hostname(&cyw43_state.netif[CYW43_ITF_STA], hostname); | ||
|
||
printf("Connecting to WiFi...\n"); | ||
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { | ||
printf("failed to connect.\n"); | ||
exit(1); | ||
} else { | ||
printf("Connected.\n"); | ||
} | ||
|
||
wifi_connected_time = get_absolute_time(); | ||
|
||
#if LWIP_MDNS_RESPONDER | ||
mdns_resp_init(); | ||
printf("mdns host name %s.local\n", hostname); | ||
#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 2 | ||
mdns_resp_add_netif(&cyw43_state.netif[CYW43_ITF_STA], hostname); | ||
mdns_resp_add_service(&cyw43_state.netif[CYW43_ITF_STA], "picow_freertos_httpd", "_http", DNSSD_PROTO_TCP, 80, srv_txt, NULL); | ||
#else | ||
mdns_resp_add_netif(&cyw43_state.netif[CYW43_ITF_STA], hostname, 60); | ||
mdns_resp_add_service(&cyw43_state.netif[CYW43_ITF_STA], "picow_freertos_httpd", "_http", DNSSD_PROTO_TCP, 80, 60, srv_txt, NULL); | ||
#endif | ||
#endif | ||
|
||
printf("\nReady, running httpd at %s\n", ip4addr_ntoa(netif_ip4_addr(netif_list))); | ||
httpd_init(); | ||
|
||
http_set_cgi_handlers(cgi_handlers, LWIP_ARRAYSIZE(cgi_handlers)); | ||
http_set_ssi_handler(ssi_example_ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags)); | ||
|
||
while(true) { | ||
vTaskDelay(100); | ||
} | ||
|
||
#if LWIP_MDNS_RESPONDER | ||
mdns_resp_remove_netif(&cyw43_state.netif[CYW43_ITF_STA]); | ||
#endif | ||
|
||
cyw43_arch_deinit(); | ||
} | ||
|
||
void vLaunch( void) { | ||
TaskHandle_t task; | ||
xTaskCreate(main_task, "TestMainThread", configMINIMAL_STACK_SIZE, NULL, TEST_TASK_PRIORITY, &task); | ||
|
||
#if NO_SYS && configUSE_CORE_AFFINITY && configNUM_CORES > 1 | ||
// we must bind the main task to one core (well at least while the init is called) | ||
// (note we only do this in NO_SYS mode, because cyw43_arch_freertos | ||
// takes care of it otherwise) | ||
vTaskCoreAffinitySet(task, 1); | ||
#endif | ||
|
||
/* Start the tasks and timer running. */ | ||
vTaskStartScheduler(); | ||
} | ||
|
||
int main( void ) | ||
{ | ||
stdio_init_all(); | ||
|
||
/* Configure the hardware ready to run the demo. */ | ||
const char *rtos_name; | ||
#if ( portSUPPORT_SMP == 1 ) | ||
rtos_name = "FreeRTOS SMP"; | ||
#else | ||
rtos_name = "FreeRTOS"; | ||
#endif | ||
|
||
#if ( portSUPPORT_SMP == 1 ) && ( configNUM_CORES == 2 ) | ||
printf("Starting %s on both cores:\n", rtos_name); | ||
vLaunch(); | ||
#elif ( RUN_FREE_RTOS_ON_CORE == 1 ) | ||
printf("Starting %s on core 1:\n", rtos_name); | ||
multicore_launch_core1(vLaunch); | ||
while (true); | ||
#else | ||
printf("Starting %s on core 0:\n", rtos_name); | ||
vLaunch(); | ||
#endif | ||
return 0; | ||
} |
Oops, something went wrong.