mirror of
https://github.com/jeelabs/esp-link.git
synced 2026-03-06 09:16:47 +01:00
switched uC console to ajax with auto-refresh
This commit is contained in:
@@ -6,14 +6,89 @@
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<p>The Microcontroller console shows the last 1024 characters received from UART0, to which
|
||||
a microcontroller is typically attached.</p>
|
||||
<pre class="console">
|
||||
%console%
|
||||
</pre>
|
||||
<p>The Microcontroller console shows the last 1024 characters
|
||||
received from UART0, to which a microcontroller is typically attached.</p>
|
||||
<p>
|
||||
<a class="pure-button button-primary" href="#">Reset µC</a>
|
||||
Baud:
|
||||
<a href="#" class="pure-button">57600</a>
|
||||
<a href="#" class="pure-button">115200</a>
|
||||
<a href="#" class="pure-button">230400</a>
|
||||
<a href="#" class="pure-button">460800</a>
|
||||
</p>
|
||||
<pre class="console" id="console"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="ui.js"></script>
|
||||
<script type="text/javascript">
|
||||
function loadJSON(url, okCb, errCb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = handleEv;
|
||||
|
||||
function handleEv() {
|
||||
try {
|
||||
//console.log("handleEv", xhr.readyState);
|
||||
if(xhr.readyState < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(xhr.status !== 200) {
|
||||
//console.log("handleEv error cb");
|
||||
errCb(xhr);
|
||||
return;
|
||||
}
|
||||
|
||||
// all is well
|
||||
if(xhr.readyState === 4) {
|
||||
//console.log("handleEv success cb");
|
||||
okCb(xhr, JSON.parse(xhr.responseText));
|
||||
}
|
||||
} catch(e) {return;}
|
||||
}
|
||||
|
||||
xhr.open('GET', url, true);
|
||||
xhr.send('');
|
||||
}
|
||||
|
||||
function fetchText(delay) {
|
||||
el = document.getElementById("console");
|
||||
if (el.textEnd == undefined) {
|
||||
el.textEnd = 0;
|
||||
el.innerHTML = "";
|
||||
}
|
||||
window.setTimeout(function() {
|
||||
loadJSON("/console?start=" + el.textEnd, updateText, retryLoad);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
function updateText(xhr, resp) {
|
||||
el = document.getElementById("console");
|
||||
|
||||
delay = 3000;
|
||||
if (el == null || resp == null) {
|
||||
//console.log("updateText got null response? xhr=", xhr);
|
||||
} else if (resp.len == 0) {
|
||||
//console.log("updateText got no new text");
|
||||
} else {
|
||||
console.log("updateText got", resp.len, "chars at", resp.start);
|
||||
if (resp.start > el.textEnd) {
|
||||
el.innerHTML = el.innerHTML.concat("\r\n<missing lines\r\n");
|
||||
}
|
||||
el.innerHTML = el.innerHTML.concat(resp.text);
|
||||
el.textEnd = resp.start + resp.len;
|
||||
delay = 500;
|
||||
}
|
||||
fetchText(delay);
|
||||
}
|
||||
|
||||
function retryLoad(xhr) {
|
||||
fetchText(1000);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
fetchText(100);
|
||||
}
|
||||
</script>
|
||||
</body></html>
|
||||
|
||||
@@ -68,6 +68,10 @@ body {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.button-primary {
|
||||
background-color: #99f;
|
||||
}
|
||||
|
||||
/* Text console */
|
||||
pre.console {
|
||||
background-color: #663300;
|
||||
|
||||
@@ -6,27 +6,34 @@
|
||||
// Microcontroller console capturing the last 1024 characters received on the uart so
|
||||
// they can be shown on a web page
|
||||
|
||||
// Buffer to hold concole contents.
|
||||
// Invariants:
|
||||
// - console_rd==console_wr <=> buffer empty
|
||||
// - *console_rd == next char to read
|
||||
// - *console_wr == next char to write
|
||||
// - 0 <= console_xx < BUF_MAX
|
||||
// - (console_wr+1)%BUF_MAX) == console_rd <=> buffer full
|
||||
#define BUF_MAX (1024)
|
||||
static char console_buf[BUF_MAX];
|
||||
static int console_wr, console_rd;
|
||||
static int console_pos; // offset since reset of console_rd position
|
||||
static int console_pos; // offset since reset of buffer
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
console_write(char c) {
|
||||
int wr = (console_wr+1)%BUF_MAX;
|
||||
if (wr == console_rd) {
|
||||
console_buf[console_wr] = c;
|
||||
console_wr = (console_wr+1) % BUF_MAX;
|
||||
if (console_wr == console_rd) {
|
||||
// full, we write anyway and loose the oldest char
|
||||
console_rd = (console_rd+1) % BUF_MAX; // full, eat first char
|
||||
console_pos++;
|
||||
}
|
||||
console_buf[console_wr] = c;
|
||||
console_wr = wr;
|
||||
}
|
||||
|
||||
// return previous character in console, 0 if at start
|
||||
static char ICACHE_FLASH_ATTR
|
||||
console_prev(void) {
|
||||
if (console_wr == console_rd) return 0;
|
||||
return console_buf[(console_wr+1+BUF_MAX)%BUF_MAX];
|
||||
return console_buf[(console_wr-1+BUF_MAX)%BUF_MAX];
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
@@ -35,22 +42,76 @@ console_write_char(char c) {
|
||||
console_write(c);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
jsonHeader(HttpdConnData *connData, int code) {
|
||||
httpdStartResponse(connData, code);
|
||||
httpdHeader(connData, "Content-Type", "application/json");
|
||||
httpdEndHeaders(connData);
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR
|
||||
ajaxConsole(HttpdConnData *connData) {
|
||||
char buff[2048];
|
||||
int len; // length of text in buff
|
||||
int console_len = (console_wr+BUF_MAX-console_rd) % BUF_MAX; // num chars in console_buf
|
||||
int start = 0; // offset onto console_wr to start sending out chars
|
||||
|
||||
jsonHeader(connData, 200);
|
||||
|
||||
// figure out where to start in buffer based on URI param
|
||||
len = httpdFindArg(connData->getArgs, "start", buff, sizeof(buff));
|
||||
if (len > 0) {
|
||||
start = atoi(buff);
|
||||
if (start < console_pos) {
|
||||
start = 0;
|
||||
} else if (start >= console_pos+console_len) {
|
||||
start = console_len;
|
||||
} else {
|
||||
start = start - console_pos;
|
||||
}
|
||||
}
|
||||
|
||||
// start outputting
|
||||
len = os_sprintf(buff, "{\"len\":%d, \"start\":%d, \"text\": \"",
|
||||
console_len-start, console_pos+start);
|
||||
|
||||
int rd = (console_rd+start) % BUF_MAX;
|
||||
while (len < 2040 && rd != console_wr) {
|
||||
uint8_t c = console_buf[rd];
|
||||
if (c == '\\' || c == '"') {
|
||||
buff[len++] = '\\';
|
||||
buff[len++] = c;
|
||||
} else if (c < ' ') {
|
||||
len += os_sprintf(buff+len, "\\u%04x", c);
|
||||
} else {
|
||||
buff[len++] = c;
|
||||
}
|
||||
rd = (rd + 1) % BUF_MAX;
|
||||
}
|
||||
os_strcpy(buff+len, "\"}"); len+=2;
|
||||
httpdSend(connData, buff, len);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
//===== Display a web page with the console
|
||||
int ICACHE_FLASH_ATTR
|
||||
tplConsole(HttpdConnData *connData, char *token, void **arg) {
|
||||
if (token==NULL) return HTTPD_CGI_DONE;
|
||||
char buff[256];
|
||||
|
||||
/*
|
||||
if (os_strcmp(token, "console") == 0) {
|
||||
if (console_wr > console_rd) {
|
||||
httpdSend(connData, console_buf+console_rd, console_wr-console_rd);
|
||||
} else if (console_rd != console_wr) {
|
||||
httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd);
|
||||
httpdSend(connData, console_buf, console_wr);
|
||||
} else {
|
||||
httpdSend(connData, "<buffer empty>", -1);
|
||||
}
|
||||
} else if (os_strcmp(token, "topnav")==0) {
|
||||
printNav(buff);
|
||||
httpdSend(connData, buff, -1);
|
||||
} else if (os_strcmp(token, "head")==0) {
|
||||
*/
|
||||
if (os_strcmp(token, "head")==0) {
|
||||
printHead(connData);
|
||||
} else {
|
||||
httpdSend(connData, "Unknown\n", -1);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
void consoleInit(void);
|
||||
void ICACHE_FLASH_ATTR console_write_char(char c);
|
||||
int ajaxConsole(HttpdConnData *connData);
|
||||
int tplConsole(HttpdConnData *connData, char *token, void **arg);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#include <esp8266.h>
|
||||
#include "uart.h"
|
||||
#include "cgi.h"
|
||||
#include "console.h"
|
||||
|
||||
// Microcontroller console capturing the last 1024 characters received on the uart so
|
||||
// they can be shown on a web page
|
||||
|
||||
// Buffer to hold concole contents.
|
||||
// Invariants:
|
||||
// - console_rd==console_wr <=> buffer empty
|
||||
// - *console_rd == next char to read
|
||||
// - *console_wr == next char to write
|
||||
// - 0 <= console_xx < BUF_MAX
|
||||
// - (console_wr+1)%BUF_MAX) == console_rd <=> buffer full
|
||||
#define BUF_MAX (1024)
|
||||
static char console_buf[BUF_MAX];
|
||||
static int console_wr, console_rd;
|
||||
static int console_pos; // offset since reset of buffer
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
console_write(char c) {
|
||||
console_buf[console_wr] = c;
|
||||
console_wr = (console_wr+1) % BUF_MAX;
|
||||
if (console_wr == console_rd) {
|
||||
// full, we write anyway and loose the oldest char
|
||||
console_rd = (console_rd+1) % BUF_MAX; // full, eat first char
|
||||
console_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
// return previous character in console, 0 if at start
|
||||
static char ICACHE_FLASH_ATTR
|
||||
console_prev(void) {
|
||||
if (console_wr == console_rd) return 0;
|
||||
return console_buf[(console_wr-1+BUF_MAX)%BUF_MAX];
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
console_write_char(char c) {
|
||||
if (c == '\n' && console_prev() != '\r') console_write('\r');
|
||||
console_write(c);
|
||||
}
|
||||
|
||||
//===== Display a web page with the console
|
||||
int ICACHE_FLASH_ATTR
|
||||
tplConsole(HttpdConnData *connData, char *token, void **arg) {
|
||||
if (token==NULL) return HTTPD_CGI_DONE;
|
||||
|
||||
if (os_strcmp(token, "console") == 0) {
|
||||
if (console_wr > console_rd) {
|
||||
httpdSend(connData, console_buf+console_rd, console_wr-console_rd);
|
||||
} else if (console_rd != console_wr) {
|
||||
httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd);
|
||||
httpdSend(connData, console_buf, console_wr);
|
||||
} else {
|
||||
httpdSend(connData, "<buffer empty>", -1);
|
||||
}
|
||||
} else if (os_strcmp(token, "head")==0) {
|
||||
printHead(connData);
|
||||
} else {
|
||||
httpdSend(connData, "Unknown\n", -1);
|
||||
}
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR consoleInit() {
|
||||
console_wr = 0;
|
||||
console_rd = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ HttpdBuiltInUrl builtInUrls[]={
|
||||
{"/help.tpl", cgiEspFsTemplate, tplCounter},
|
||||
{"/log.tpl", cgiEspFsTemplate, tplLog},
|
||||
{"/console.tpl", cgiEspFsTemplate, tplConsole},
|
||||
{"/console", ajaxConsole, NULL},
|
||||
|
||||
//Routines to make the /wifi URL and everything beneath it work.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user