ESP32 reboots constantly due to "flash read err, 1000" - esp32

Folks, I couldn't decide if this is on or off-topic, but it feels related to programming.
I've an ESP32 board, embedded into a NodeMCU. I've connected an UART2USB serial monitor directly to the ESP32's RX-TX, and initially this was printed onto serial console after poweron:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0x00
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0008,len:8
load:0x3fff0010,len:3480
load:0x40078000,len:7804
ho 0 tail 12 room 4
load:0x40080000,len:252
entry 0x40080034
I (46) boot: ESP-IDF v2.0-3-gbef9896 2nd stage bootloader
I followed Espressif's instructions to build the simplest helloworld program:
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
void app_main(void)
{
printf("Hello world!\n");
/* Print chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
printf("silicon revision %d, ", chip_info.revision);
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
for (int i = 10; i >= 0; i--) {
printf("Restarting in %d seconds...\n", i);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}
Also, I did successfully (I believe) compiled and flashed (without errors) this hello world example to ESP32.
After that however, this is printed onto serial monitor:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun 8 2016 00:22:57
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun 8 2016 00:22:57
RTCWDT_RTC_RESET keeps repeating. Only stops when I cut the power.
As I said, I couldn't decide about "on-topicness" of this question, because I'm not sure if this problematic behavior is some kind of fault in "helloworld" example, or coming from somewhere else.
Update
I might accidentally erased the bootloader, so I did a make flash.
This created a bootloader.bin in the build folder, which I tried to flash, but this doesn't change anything.
I'm flashing with https://github.com/espressif/esp-serial-flasher.

Related

How I can get peak memory of a process on Mac OS?

In linux, when a process is running, I can check its current memory usage and historically peak memory usage by looking into /proc/self/status. Are there similar files in mac?
In mac, I found that vmmap pid gives a lot info about memory usage, but it seems peek memory usage of the pid is not monitored. May I ask if anyone could help me with any command?
A program can use the Mach API to get its own memory statistics. For example:
#include <stdio.h>
#include <mach/mach.h>
#include <stdlib.h>
int main(void)
{
kern_return_t ret;
mach_task_basic_info_data_t info;
mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
ret = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count);
if (ret != KERN_SUCCESS || count != MACH_TASK_BASIC_INFO_COUNT)
{
fprintf(stderr, "task_info failed: %d\n", ret);
exit(EXIT_FAILURE);
}
printf("resident size max: %llu (0x%08llx) bytes\n",
(unsigned long long)info.resident_size_max,
(unsigned long long)info.resident_size_max);
return 0;
}
Alternatively, you can run your program under Instruments, with the Allocations template, to observe its memory usage. (Xcode itself also has memory gauges, but I don't recall off-hand if it shows peak usage.)

ESP32 failing to detect PN532 NFC module

I've been struggling for the past few days to get the Elechouse PN532 V3 module working with an ESP32 over I2C. The PN532 module itself works fine with a Raspberry Pi.
This is the circuit (not actually using SparkFun ESP32 board, just for reference)
And this is the code I'm trying to run
#include <Wire.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
PN532_I2C pn532i2c(Wire);
PN532 nfc(pn532i2c);
void setup(void) {
Serial.begin(115200);
Serial.println("Hello!");
Wire.begin(18, 19);
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
// Set the max number of retry attempts to read from a card
// This prevents us from waiting forever for a card, which is
// the default behaviour of the PN532.
nfc.setPassiveActivationRetries(0xFF);
// configure board to read RFID tags
nfc.SAMConfig();
Serial.println("Waiting for an ISO14443A card");
}
void loop(void) {
boolean success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
// Wait for an ISO14443A type cards (Mifare, etc.). When one is found
// 'uid' will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
if (success) {
Serial.println("Found a card!");
Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
Serial.print("UID Value: ");
for (uint8_t i=0; i < uidLength; i++)
{
Serial.print(" 0x");Serial.print(uid[i], HEX);
}
Serial.println("");
// Wait 1 second before continuing
delay(1000);
}
else
{
// PN532 probably timed out waiting for a card
Serial.println("Timed out waiting for a card");
}
}
And finally the serial output: Didn't find PN53X board
Any ideas what I'm doing wrong?
EDIT: libraries im using https://github.com/elechouse/PN532 and the ESP32 dev board is a Wemos Lolin32 Lite clone.
I don't have any of this hardware to verify this, but from 'PN532-PN532_HSU\NDEF\README.md'
For the Adafruit Shield using I2C
#include <Wire.h>
#include <PN532_I2C.h>
#include <PN532.h>
#include <NfcAdapter.h>
PN532_I2C pn532_i2c(Wire);
NfcAdapter nfc = NfcAdapter(pn532_i2c);
Try using the above in your code? I'd also suggest you review the PN532 I2C examples in more depth. The PN532 I2C library code defines a 'wakeup' function:
void PN532_I2C::wakeup()
{
delay(500); // wait for all ready to manipulate pn532
}
The comment makes me believe the device may require a significant delay (500ms) before it's ready to talk.
Best of luck.
sda and scl are 21 and 22
also make sure that you changed mode to I2C (those jumpers on PN532 module):
doc - page 3
I have this now working with an M5STACK grey core, the common issue was the I2C bus would lock up on a reset or re program. Use a spare I/O pin and connect to the PN532 reset pin, hold this low on boot, initialize I2C bus then drive reset high after 100mS problem solved no more bus conflicts.

How to execute a piece of kernel code on all CPUs?

I'm trying to make a kernel module to enable FOP compatibility mode for x87 FPU. This is done via setting bit 2 in IA32_MISC_ENABLE MSR. Here's the code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("10110111");
MODULE_DESCRIPTION("Module to enable FOPcode compatibility mode");
MODULE_VERSION("0.1");
static int __init fopCompat_init(void)
{
unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Before trying to set FOP_COMPAT, IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
wrmsrl(MSR_IA32_MISC_ENABLE,misc_enable|MSR_IA32_MISC_ENABLE_X87_COMPAT);
misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Tried to set FOP_COMPAT. Result: IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is now %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
return 0;
}
static void __exit fopCompat_exit(void)
{
const unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Quitting FOP-compat with IA32_MISC_ENABLE=%llx\n",misc_enable);
if(!(misc_enable & MSR_IA32_MISC_ENABLE_X87_COMPAT))
printk(KERN_INFO "NOTE: seems some CPUs still have to be set up, "
"or compatibility mode will work inconsistently\n");
printk(KERN_INFO "\n");
}
module_init(fopCompat_init);
module_exit(fopCompat_exit);
It seems to work, but on multiple insmod/rmmod cycles I sometimes get dmesg output that the compatibility mode wasn't still enabled, although it was immediately after doing wrmsr. After some thinking I realized that it's because the module code was executed on different logical CPUs (I have Core i7 with 4 cores*HT=8 logical CPUs), so I had a 1/8 chance of getting "enabled" print on doing rmmod. After repeating the cycle for about 20 times I got consistent "enabled" prints, and my userspace application happily works with it.
So now my question is: how can I make my code execute on all logical CPUs present on the system, so as to enable compatibility mode for all of them?
For execute code on every CPU use on_each_cpu function.
Signature:
int on_each_cpu(void (*func) (void *info), void *info, int wait)
Description:
Call a function on all processors.
If wait parameter is non-zero, it waits for function's completion on all CPUs.
Function func shouldn't sleep, but whole on_each_cpu() call shouldn't be done in atomic context.

EEPROM in AVR doesn't work

I'm a beginner in C language. I'm trying to operate on EEPROM memory in my ATmega 8 and ATtiny2313.
Based on this tutorial I've created the following codes:
1) writes a number to place 5 in uC's eeprom
#define F_CPU 1000000UL
#include <avr/eeprom.h>
int main()
{
number=5;
eeprom_update_byte (( uint8_t *) 5, number );
while (1);
{
}
}
2) blinks the LED n times, where n is the number read from place 5 in eeprom
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
int main()
{
DDRB=0xFF;
_delay_ms(1000);
int number;
number=eeprom_read_byte (( uint8_t *) 5) ;
for (int i=0; i<number; i++) //blinking 'number' times
{
PORTB |= (1<<PB3);
_delay_ms(100);
PORTB &= (0<<PB3);
_delay_ms(400);
}
while (1);
{
}
}
The second program blinks the led many times, and it's never the amount which is supposed to be in eeprom. What's the problem? This happens in both atmega8 and attiny2313.
EDIT:
Console results after compilation of the first program:
18:01:55 **** Incremental Build of configuration Release for project eeprom ****
make all
Invoking: Print Size
avr-size --format=avr --mcu=attiny2313 eeprom.elf
AVR Memory Usage
Device: attiny2313
Program: 102 bytes (5.0% Full)
(.text + .data + .bootloader)
Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)
Finished building: sizedummy
18:01:56 Build Finished (took 189ms)
That is one of the every time failures for beginners :-)
If you compile simply with avr-gcc <source> -o <out> you will get the wrong results here, because you need optimization! The write procedure MUST be optimized to fulfil the correct write access! So please use '-Os' or '-O3' for compiling with avr-gcc!
If you have no idea if your problem comes from read or write the eeprom, read your eeprom data with avarice/avrdude or similar tools.
The next pitfall can be, that you erase your eeprom section if you program your flash. So please have a look what your programmer really do! A full chip erase erases the eeprom as well.
Next pitfall: What fuses you have set? You are running with the expected clock rate? Maybe you have programmed internal clock and your outside crystal seems to be working with wrong speed?
Another one: Just have a look for the fuses again! JTAG pins switched off? Maybe you see only JTAG flickering :-)
Please add the compiler and programming commands to your question!

Capturing packets on Windows 7

I am trying to capture all of transferred packets on a computer. My code works fine in Windows XP but it only captures outgoing packets on Windows 7 and cannot see incoming packets.
Here is a version of the code which just calculate the size of received packets (it seems big but most of it is just definitions). This code works correctly on Windows XP but nothing happens on Windows 7 (it stuck at recvfrom) (the code is complete and you could give a try on Win7):
#include <Winsock2.h>
#include <Mstcpip.h>
#include <iostream>
#include <string>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
struct SIP4HEADER
{
u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits)
u_char tos; // Type of service
u_short tlen; // Total length
u_short ident; // Identification
u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; // Time to live
u_char proto; // Protocol
u_short crc; // Header checksum
u_long saddr; // Source address
u_long daddr; // Destination address
u_int op_pad; // Option + Padding
};
// Error handling parts is removed for clarity
void main()
{
WSAData wsa={0};
WSAStartup(MAKEWORD(2,2),&wsa);
string strIPAddress;
cout << "Enter a local IP address to monitor: ";
cin >> strIPAddress;
SOCKET ListenSocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
sockaddr_in sa_in;
sa_in.sin_family = AF_INET;
sa_in.sin_addr.s_addr = inet_addr( strIPAddress.c_str() ); //My local IP address
sa_in.sin_port = htons(0);
bind(ListenSocket,(SOCKADDR *) &sa_in, sizeof(sa_in));
int rcv=RCVALL_IPLEVEL;
DWORD b=0;
WSAIoctl(ListenSocket,SIO_RCVALL,&rcv,sizeof(rcv),0,0,&b,0,0);
char buf[2000];
SIP4HEADER* ih = (SIP4HEADER*)buf;
DWORD ReceivedKBytes = 0;
DWORD t = 0;
while( recvfrom(ListenSocket,buf,_countof(buf),0,NULL,NULL)!=-1 )
{
if(sa_in.sin_addr.s_addr == ih->daddr)
t += ntohs(ih->tlen) ;
// update each 20KB
if(t > 20*1024)
{
t=0;
ReceivedKBytes += 20;
cout << "Received KBs: " << ReceivedKBytes << endl;
}
}
}
The only thing made me suspect was this article on MSDN who says:
A call to the bind function with a raw
socket for the IPPROTO_TCP protocol is
not allowed
but i am using IPPROTO_IP, and bind function documentation also says:
The bind function may also be used to
bind to a raw socket (the socket was
created by calling the socket function
with the type parameter set to
SOCK_RAW)
So it seems this is not the problem. Despite this, I don't get any error from calling bind and other functions in this code. I also omitted calling bind function which causes recvfrom make error 10022 Invalid argument. I also replaced IPPROTO_IP with IPPROTO_TCP but it doesn't help neither.
I am not sure whether I am doing it right or not, but this code works without any problem on Windows XP. Anyway, I am looking for a way to get received and sent packets related to a local IP address on Windows XP/7.
Also:
I am running this code on privileged (admin) mode in Windows 7.
The Winpcap or other third-party libraries is not an available option for me.
I had the same problem. Turned out it was Windows 7 Firewall that stopped the sniffer from seeing inbound data. Turned it off and finally, the code worked.
I run your code on my Win7 and it works. I do see following lines printed out:
Received KBs: 20
Received KBs: 40
Received KBs: 60
Received KBs: 80
Received KBs: 100
Probably check your firewall?

Resources