8000 Updated to track PRs for various print definitions. Cleaned up comments · esp8266/Arduino@f438e02 · GitHub
[go: up one dir, main page]

Skip to content

Commit f438e02

Browse files
committed
Updated to track PRs for various print definitions. Cleaned up comments
1 parent ad03e16 commit f438e02

File tree

4 files changed

+71
-86
lines changed

4 files changed

+71
-86
lines changed

cores/esp8266/umm_malloc/isr_safe_printf.cpp

Lines changed: 2 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,6 @@
66
*
77
* Still researching options for printing.
88
*/
9-
10-
/*
11-
Printing from the malloc routines is tricky. Since a print library
12-
might call *alloc. Then recusion may follow as each error call may fail
13-
into another error and so on.
14-
15-
Objective: To be able to print "last gasp" diagnostic messages
16-
when interrupts are disabled and w/o availability of heap resources.
17-
18-
Considerations:
19-
* can be called from ISR
20-
* can be called from malloc code, cannot use malloc
21-
* can be called from malloc code that was called from an ISR
22-
* can be called from with in a critical section, eg. xt_rsil(15);
23-
* this may be effectively the same as being called from an ISR?
24-
25-
Knowns:
26-
* ets_printf - For RTOS SDK they replaced this function with one in the SDK.
27-
Most of the problems I can see with ets_printf center around not being
28-
able to maintain a port to thread context. That is you cannot have one
29-
thread using one port while another thread uses the other. In the no OS
30-
case we cannot have one area of code using one port and another area of
31-
code using the other port. Most of the ROM printf functions are not built
32-
to support this kind of usage. Things get especially dangerous when you
33-
try to use the ...external_printf stuff.
34-
* ets_vprintf - by itself is safe.
35-
* newlibc printf - not safe - lives in flash.
36-
* newlibc snprintf - not safe - lives in flash.
37-
* builtin putc1 print function - Is installed when you use
38-
ets_install_uart_printf. Which calls ets_install_putc1. The selection of UART
39-
is performed by calling uart_buff_switch with 0 for UART0 and 1 for UART1.
40-
This should work for our purpose here, if handled as follows:
41-
* call uart_buff_switch at each printf call to reselect UART
42-
* use a stack buffer to hold a copy the PROGMEM string to print from.
43-
* use ets_vprintf for printing with putc1 function.
44-
* os_printf_plus looks interesting. It is in IRAM. If no heap is available it
45-
will use up to 64 bytes of stack space to copy a PROGMEM fmt for printing.
46-
Issues:
47-
* Printing is turned off by system_set_os_print
48-
* putc1 needs to be in IRAM - this is a uart.cpp issue
49-
* Need to force system_get_free_heap_size to return 0 during critical periods.
50-
* won't work for umm_info it prints over 64 characters.
51-
* along with umm_info there are other debug messages that exceed 64 characters.
52-
53-
Research TODO, Unknowns:
54-
* Is there a problem with the ROM "serial print functions"?
55-
Rtos SDK does not use them. igrr also didn't use them in ...postmortem.
56-
See "ets_printf" above.
57-
58-
*/
59-
609
#include <stdio.h>
6110
#include <string.h>
6211
#include <pgmspace.h>
@@ -66,36 +15,8 @@ extern "C" {
6615

6716
#if defined(DEBUG_ESP_ISR)
6817

69-
int _isr_safe_printf_P(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
70-
// Note, _isr_safe_printf_P will not handle additional string arguments in
71-
// PROGMEM. Only the 1st parameter, fmt, is supported in PROGMEM.
72-
#define ISR_PRINTF(fmt, ...) _isr_safe_printf_P(PSTR(fmt), ##__VA_ARGS__)
73-
#define ISR_PRINTF_P(fmt, ...) _isr_safe_printf_P(fmt, ##__VA_ARGS__)
74-
75-
// Boot ROM _putc1, ignores CRs and sends CR/LF for LF, newline.
76-
// Always returns character sent.
77-
typedef int (*fp_putc_t)(int);
78-
#define _rom_putc1 ((fp_putc_t)0x40001dcc)
79-
80-
void uart_buff_switch(uint8_t);
81-
8218
int _isr_safe_printf_P(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
8319
int ICACHE_RAM_ATTR _isr_safe_printf_P(const char *fmt, ...) {
84-
85-
//C This #ifdef block is obsolete if the PR for ets_putc UART selection is approved.
86-
#ifdef DEBUG_ESP_PORT
87-
#define VALUE(x) __STRINGIFY(x)
88-
// Preprocessor and compiler together will optimize away the if.
89-
if (strcmp("Serial1", VALUE(DEBUG_ESP_PORT)) == 0) {
90-
uart_buff_switch(1U);
91-
} else {
92-
uart_buff_switch(0U);
93-
}
94-
#else
95-
uart_buff_switch(0U); // Side effect, clears RX FIFO
96-
#endif
97-
//C - end
98-
9920
/*
10021
To use ets_strlen() and ets_memcpy() safely with PROGMEM, flash storage,
10122
the PROGMEM address must be word (4 bytes) aligned. The destination
@@ -109,10 +30,11 @@ int ICACHE_RAM_ATTR _isr_safe_printf_P(const char *fmt, ...) {
10930
ets_memcpy(ram_buf, fmt, buf_len);
11031
va_list argPtr;
11132
va_start(argPtr, fmt);
112-
int result = ets_vprintf(_rom_putc1, ram_buf, argPtr);
33+
int result = ets_vprintf(ets_uart_putc1, ram_buf, argPtr);
11334
va_end(argPtr);
11435
return result;
11536
}
37+
11638
#endif
< 292D code>11739

11840
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef ISR_SAFE_PRINTF_H
2+
#define ISR_SAFE_PRINTF_H
3+
#include <stdio.h>
4+
#include <string.h>
5+
#include <pgmspace.h>
6+
7+
extern "C" {
8+
/*
9+
ISR Safe to call for debugging. Not really safe to use all the time. The
10+
problem is going over 10us with interrupts disabled. It takes 86.8us to send
11+
one 8 bit character with start and stop bit at 115200 bps.
12+
*/
13+
int _isr_safe_printf_P(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
14+
// Note, _isr_safe_printf_P will not handle additional string arguments in
15+
// PROGMEM. Only the 1st parameter, fmt, is supported in PROGMEM.
16+
#define ISR_PRINTF(fmt, ...) _isr_safe_printf_P(PSTR(fmt), ##__VA_ARGS__)
17+
#define ISR_PRINTF_P(fmt, ...) _isr_safe_printf_P(fmt, ##__VA_ARGS__)
18+
}
19+
20+
#endif

cores/esp8266/umm_malloc/umm_malloc.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* Renamed to umm_malloc.cpp
4343
*
4444
* Added `extern "C" { ...b};` around code.
45-
45+
*
4646
* Surround DBGLOG_LEVEL with #ifndef... Now defined value in umm_malloc_cfg.h
4747
*
4848
* umm_free() - moved critical section to start after safe calculations.
@@ -86,6 +86,11 @@
8686
*
8787
* Globally change across all files %i to %d: umm_info.c, umm_malloc.c,
8888
*
89+
* Added a #ifdef BUILD_UMM_MALLOC_C fence to prevent Arduino IDE from building
90+
* the various .c files that are #included into umm_malloc.cpp. They are
91+
* normally enabled by #define <feature name> in umm_malloc_cfg.h. In this
92+
* case it builds fine; however, if the define is global, the IDE will try and
93+
* build the .c by itself.
8994
*
9095
* Notes,
9196
*
@@ -128,7 +133,45 @@
128133
* may have been an accident during code cleanup.
129134
*
130135
*/
136+
/* This block will be used for the PR description:
137+
138+
This updates the heap management library, umm_malloc, to the current upstream
139+
version at https://github.com/rhempel/umm_malloc. Some reorganizing and new code
140+
was needed to use the new version.
141+
142+
This is a list of note worthy changes:
143+
144+
UMM_POISON - now has a lite option as well as the previous intensive check
145+
option. The code for running the full poison test at the call of the various
146+
alloc functions was removed in the upstream version. In this port the missing
147+
code was added to heap.cpp and umm_local.cpp.
148+
* UMM_POISON - appears to have been partially changed to UMM_POISON_CHECK,
149+
I treat it as depricated and used UMM_POISON_CHECK, when needed.
150+
However, the Arduino Core's references to UMM_POISON were replaced with
151+
UMM_POISON_CHECK_LITE.
152+
* UMM_POISON_CHECK_LITE - Less intense, it just checks poison on active
153+
neighboring allocations.
154+
* UMM_POISON_CHECK - Full heap intensive check of poison
155+
156+
UMM_INFO_PRINT - This new define makes building UMM_INFO with printing
157+
capability, optional. When umm_info(NULL, true) is used to print a debug view of
158+
heap information to the debug port, it has to walk the heap and print out
159+
information, while in a critical section. This requires that the print function
160+
be able to print w/o doing malloc calls and from an IRQ disabled context. It
161+
also requires more IRAM to handle printing. Without this define
162+
`umm_info(NULL, true)` will not print.
163+
* UMM_INFO_PRINT is enabled as part of selecting `Debug port: "Serial" or
164+
* "Serial1"`. To make available all the time use '-D UMM_INFO_PRINT`.
165+
166+
A cautionary note, on the use of UMM_INTEGRITY_CHECK, UMM_POISON_CHECK, and
167+
UMM_INFO_PRINT. All of these run with IRQs disabled, for periods that can go
168+
into 100's of us. With umm_info(NULL, true) that may go into seconds, depending
169+
on the serial interface speed and the number of memory allocations present. Use
170+
UMM_INTEGRITY_CHECK, UMM_POISON_CHECK, and UMM_INFO_PRINT sparingly.
171+
If you want to see numbers for the disabled time, explore using
172+
UMM_CRITICAL_METRICS in umm_malloc_cfg.h.
131173
174+
*/
132175

133176
/*
134177
* Added for using with Arduino ESP8266 and handling renameing to umm_malloc.cpp

cores/esp8266/umm_malloc/umm_malloc_cfg.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <debug.h>
1212
#include <pgmspace.h>
13+
#include "isr_safe_printf.h"
1314

1415
#ifdef __cplusplus
1516
extern "C" {
@@ -566,11 +567,10 @@ static inline void _critical_exit(UMM_TIME_STAT *p, uint32_t *saved_ps) {
566567
#define DEBUG_ESP_ISR
567568
#endif
568569

569-
int _isr_safe_printf_P(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
570-
// Note, _isr_safe_printf_P will not handle additional string arguments in
570+
// Note, ISR_PRINTF_P will not handle additional string arguments in
571571
// PROGMEM. Only the 1st parameter, fmt, is supported in PROGMEM.
572-
#define DBGLOG_FUNCTION(fmt, ...) _isr_safe_printf_P(PSTR(fmt), ##__VA_ARGS__)
573-
#define DBGLOG_FUNCTION_P(fmt, ...) _isr_safe_printf_P(fmt, ##__VA_ARGS__)
572+
#define DBGLOG_FUNCTION(fmt, ...) ISR_PRINTF(fmt, ##__VA_ARGS__)
573+
#define DBGLOG_FUNCTION_P(fmt, ...) ISR_PRINTF_P(fmt, ##__VA_ARGS__)
574574
#else
575575
#define DBGLOG_FUNCTION(fmt, ...) do { (void)fmt; } while(false)
576576
#define DBGLOG_FUNCTION_P(fmt, ...) do { (void)fmt; } while(false)
@@ -668,7 +668,7 @@ void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line);
668668
/*
669669
Problem, I would like to report the file and line number with the umm poison
670670
event as close as possible to the event. The #define method works for malloc,
671-
calloc, and realloc those names are not as generic as free. A #define free
671+
calloc, and realloc those names are not as generic as "free". A #define free
672672
captures too much. Classes with methods called free are included :(
673673
Inline functions would report the address of the inline function in the .h
674674
not where they are called.

0 commit comments

Comments
 (0)
0