So I am running an ESP32 and i currently have it set to implement 2 tasks. Core 0 is aborting due to the watch dog timer - timertask

Task1 running on core 0
Task2 running on core 1
The response from slave 1 data register 40007 failed!
The response from slave 1 data register 40008 failed!
The response from slave 1 data register 40020 failed!
The response from slave 1 data register 40021 failed!
E (13183) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (13183) task_wdt: - IDLE0 (CPU 0)
E (13183) task_wdt: Tasks currently running:
E (13183) task_wdt: CPU 0: Task1
E (13183) task_wdt: CPU 1: loopTask
E (13183) task_wdt: Aborting.
abort() was called at PC 0x400d606b on core 0
Backtrace: 0x40090bbc:0x3ffbe190 0x40090ded:0x3ffbe1b0 0x400d606b:0x3ffbe1d0 0x40084af5:0x3ffbe1f0 0x400d1585:0x3ffc79b0 0x400d19ef:0x3ffc79d0 0x400d1e85:0x3ffc79f0 0x400d2996:0x3ffc7a10 0x4008d6b9:0x3ffc7a30
Rebooting...

void setup() {
// put your setup code here, to run once:
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 9600 baud
Serial2.begin(9600);
// Modbus slave ID 1
node.begin(1, Serial2);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
Serial.begin(38400);
while (!Serial); //while not serial Wait...
delay(1500);
Serial.println("Program has Started");
for(int i=0; i<InArraySize; i++){
pinMode(iPins[i],INPUT_PULLUP); //To enable PULL-UP resistors change "INPUT" with "INPUT_PULLUP"
}
for(int i=0; i<OutArraySize; i++){
pinMode(oPins[i],OUTPUT);
}
//interrupt-tag
// start the Modbus RTU client
initTCC();
//rtc1-tag
digitalWrite(13, HIGH);
xTaskCreatePinnedToCore(
Task1code, /* Function to implement the task */
"Task1", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task */
&Task1, /* Task handle. */
0); /* Core where the task should run */
xTaskCreatePinnedToCore(
Task2code, /* Task function. */
"Task2", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task2, /* Task handle to keep track of created task */
1); /* Core where the task should run */
/**************************************Bluetooth*****************************************/
/*Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
*/
// esp_task_wdt_init(7, true); //watchdog
// esp_task_wdt_add(Task1); //watchdog
}
void Task1code( void * pvParameter)
{
Serial.print("Task1 running on core ");
Serial.println(xPortGetCoreID());
for(;;)
{
mainRoutine();
updateRegisters();
}
// esp_task_wdt_reset(); //watchdog
}
void Task2code( void * pvParameter)
{
Serial.print("Task2 running on core ");
Serial.println(xPortGetCoreID());
for(;;)
{
/**************************************Bluetooth*****************************************/
/*if (Serial.available())
{
SerialBT.write(Serial.read());
}
if (SerialBT.available())
{
Serial.write(SerialBT.read());
}
delay(20);
*/
if ((millis()-pollTemp)>pollInterval){
pollDone=true;
//using mod move (unit id ,place to store data, data target address)
//using mod move (unit id, place to store data, data target address, min value, max value)
nFile[0]=(int16_t)modMove(0x06); //hz xx.x
mainRoutine();
updateRegisters();
nFile[7]=(int16_t)modMove(0x07); //Amps xx.x
mainRoutine();
updateRegisters();
nFile[2]=(int16_t)modMoveScaled(0x13, 0, 1000); //Analog value 1 (0-1000=(0-1000) for a percentage
mainRoutine();
updateRegisters();
nFile[3]=(int16_t)modMoveScaled(0x14, 0, 1000); //Analog value 2 (200-1000)=(0-1000) for a percentage
mainRoutine();
updateRegisters();
nFile[8]=(int16_t)modMove(0x16); //DC Bus Voltage
mainRoutine();
updateRegisters();
nFile[6]=(int16_t)modMove(0xAC); //Motor Rated Current xx.x
} else {
pollDone=false;
}
if (pollDone){
pollTemp=millis();
}
if ((millis()-pollTemp2)>pollInterval2){
pollDone2=true;
Serial.print("The current setpoint setpoint is: ");
Serial.println(nFile[2]);
Serial.print("The current wakeup point setpoint is: ");
Serial.println(nFile[4]);
Serial.print("PSI at setpoint: ");
Serial.println(getBitWord(2, 0, 0));
Serial.print("PSI at wakeup point: ");
Serial.println(getBitWord(2, 0, 1));
Serial.print("Start sleep timer: ");
Serial.println(getBitWord(2, 0, 2));
Serial.print("Hz at 60: ");
Serial.println(getBitWord(2, 0, 3));
Serial.print("Torque <= 46%: ");
Serial.println(getBitWord(2, 0, 4));
Serial.print("Start fault1 timer: ");
Serial.println(getBitWord(2, 0, 5));
Serial.print("Drive Running: ");
Serial.println(getBitWord(2, 0, 7));
Serial.print("Comm Fault: ");
Serial.println(getBitWord(2, 1, 0));
Serial.print("Underload fault: ");
Serial.println(getBitWord(2, 1, 1));
Serial.print("current reset state: ");
Serial.println(!getBitWord(0, 0, 1));
Serial.print("Flosting point torque= ");
Serial.println(fFile[2]);
} else {
pollDone2=false;
}
if (pollDone2){
pollTemp2=millis();
}
}
}

Related

STM32F446's CAN transmission completed interrupt not firing :(

I'm working with the CAN Module from the STM32F446RE board which has the MCU mentioned in the title. I'm trying to transmit some data on the UART via Tera Term terminal and take this data and send it via Loopback mode and read it back. For starters I have generated the configuration from CubeMx and written some code to transmit a numerical value which the user enters to the can 'network' and when that happens I want to go into an can completed transmission ISR and print some message on the UART from there to indicate that the transfer was completed.
In the CubeMx I have configured the CAN interrupts like this:
CAN1 TX interrupt enabled
CAN1 RX interrupt enabled(because I will also want to trigger the receive interrupt after I fix this issue)
This is the part of the code(I cannot copy paste all as this is the post will become too long just ask me if I need to provide more of my code):
while (1)
{
/*keep getting what the user enters on the UART untill enter is pressed*/
while(received_data != '\r')
{
HAL_UART_Receive(&huart2,&received_data,1,HAL_MAX_DELAY);
recvd_buffer[buf_indx] = received_data;
buf_indx++;
if(buf_indx > 1)
{
buf_indx = 0;
}
}
if( recvd_buffer[0] == '1' || recvd_buffer[0] == '0')
{
received_data = 0;
buf_indx = 0;
user_data = "\n\rOK. Starting CAN transmission in interrupt mode\n\r";
len_of_data = strlen(user_data);
HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
//CAN will start sending data in non-blocking mode
CAN_Tx(recvd_buffer[0]);
recvd_buffer[0] = 0;
recvd_buffer[1] = 1;
}
else
{
recvd_buffer[0] = 0;
recvd_buffer[1] = 1;
received_data = 0;
user_data = "\n\rInvalid value. Please enter either 1 or 2\n\r";
len_of_data = strlen(user_data);
HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}
}
}
Below I have also implemented the 3 Tx mailbox transmit complete callback functions:
void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
{
uint16_t user_data = "\n\rTransmission completed mailbox_0\n\r";
uint16_t len_of_data = strlen(user_data);
HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}
void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
{
user_data = "\n\rTransmission completed mailbox_1\n\r";
uint16_t len_of_data = strlen(user_data);
HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}
void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
{
user_data = "\n\rTransmission completed mailbox_2\n\r";
uint16_t len_of_data = strlen(user_data);
HAL_UART_Transmit( &huart2, (uint8_t*)user_data, len_of_data, HAL_MAX_DELAY );
}
This is the CAN_Tx function that makes use of the CAN hal driver to send the data:
void CAN_Tx(uint8_t value)
{
uint8_t mailbox_no;
CAN_TxHeaderTypeDef can_header;
can_header.StdId = 0;
can_header.ExtId = 0;
can_header.IDE = CAN_ID_STD;
can_header.RTR = CAN_RTR_DATA;
can_header.DLC = 1;
can_header.TransmitGlobalTime = DISABLE;
HAL_CAN_AddTxMessage(&hcan1, &can_header, value, &mailbox_no);
}
I have debugged the code in main and it seems to work fine. I got no error in the Can_Tx function it returns with success. From my understanding from the datasheet of the microcontroller(secttion 30.8 - bxCAN interrupts) if the timer1 transmit interrupt is enabled than depending on which mailbox was used for transmission one of those callbacks should get executed. However that does not happen the code inside them won't get executed. Please help me understand what I'm doing wrong. Thank you!

UDP packets are dropped in OS (asio is used)

I am developing client-server application which transfers data via UDP.
I am facing the problem of dropped packets. I added socket buffer checking to detect potential overflow. Also my app checks sequence of received numbers in packets. Packets have fixed size. If free space of socket buffer is less than threshold (size of 3 packets for example) then "Critical level of buffer" message is logged. If number of packet is skipped in sequence then corresponding message is logged. There is code:
UdpServer::UdpServer(asio::io_service& io, uint16_t port, uint32_t packetSize) : CommunicationBase(io, port),
m_socket(io, asio::ip::udp::endpoint(asio::ip::address_v6::any(), m_port))
{
m_buffer = new uint8_t[packetSize];
m_packetSize = packetSize;
m_socketBufferSize = m_packetSize * 32;
m_criticalLevel = 5 * m_packetSize;
asio::ip::udp::socket::receive_buffer_size recieveBuffSize(m_socketBufferSize);
m_socket.set_option(recieveBuffSize);
}
UdpServer::~UdpServer()
{
std::free(m_buffer);
}
void UdpServer::StartReceive(std::function<void(uint8_t* buffer, uint32_t bytesCount)> receiveHandler)
{
m_onReceive = receiveHandler;
Receive();
}
inline void UdpServer::Receive()
{
m_socket.async_receive(asio::null_buffers(), [=](const boost::system::error_code& error, size_t bytesCount)
{
OnReceive(bytesCount, error);
});
}
void UdpServer::OnReceive(size_t bytesCount, const boost::system::error_code& error)
{
static uint16_t lastSendNum = 65535;
uint16_t currentNum = 0;
uint16_t diff = 0;
if (error)
{
if (error == asio::error::operation_aborted)
{
logtrace << "UDP socket reports operation aborted, terminating";
return;
}
logerror << "UDP socket error (ignoring): " << error.message();
}
else
{
asio::ip::udp::endpoint from;
boost::system::error_code receiveError;
size_t bytesRead = 0;
size_t bytesAvailable = m_socket.available();
while (bytesAvailable > 0)
{
if (m_socketBufferSize - bytesAvailable < m_criticalLevel)
{
logwarning << "Critical buffer level!";
}
bytesRead = m_socket.receive(asio::buffer(m_buffer, m_packetSize), 0, receiveError);
if (receiveError)
{
logerror << "UDP socket error: " << receiveError.message();
break;
}
currentNum = *reinterpret_cast<uint16_t*>(m_buffer);
diff = currentNum - lastSendNum;
if (diff != 1)
{
logdebug << "Chunk skipped: " << diff << ". Last " << lastSendNum << " next " << currentNum;
}
lastSendNum = currentNum;
if (m_onReceive)
{
m_onReceive(m_buffer, bytesRead);
}
bytesAvailable = m_socket.available();
}
}
Receive();
}
Even if checking of buffer status and packet processing m_onReceive are disabled and bytesAvailable > 0 replaced with true, udp packets are dropped. Speed rate is ~71 Mb/s via 1Gb Ethernet.
Windows 10 is used. Also I checked netstat -s result: no reassembly failures. Socket buffer is never being overflowed.

How to enable Bootchart in android

My current progress is as follows,
Enable Bootchart.h by
#ifndef BOOTCHART
# define BOOTCHART 1
#endif
After that I compile the code, make INIT_BOOTCHART=true kernel -j4. So after compile completes I did
1. adb root
2. adb shell
3. cd data
4. echo 120 > bootchart-start (cat bootchart-start -> 120)
5. mkdir bootchart
6. reboot bootloader
7. fastboot flash kernel kernel.img
8. reboot
Then I check the log files in inside of the data/bootchart folder. But it's empty after few minutes later also.
So I put some logs in system/core/init/init.c -> bootchart_init_action
static int bootchart_init_action(int nargs, char **args)
{
ERROR("#### JACH #### - BOOTCHART'%d':'%s'\n", 0, "bootchart_init_action -start");
bootchart_count = bootchart_init();
ERROR("#### JACH #### - BOOTCHART'%d':'%s'\n", bootchart_count, "bootchart_init_action -bootchart_count");
if (bootchart_count < 0) {
ERROR("bootcharting init failure\n");
} else if (bootchart_count > 0) {
NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
} else {
NOTICE("bootcharting ignored\n");
}
ERROR("#### JACH #### - BOOTCHART'%d':'%s'\n", 0, "bootchart_init_action -end");
return 0;
}
After compiling the above code, I saw bootchart_init() function return 0 value. Below is the log file.
<11>[ 2.814551] init: #### JACH #### - BOOTCHART'0':'bootchart_init_action -start'
<11>[ 2.814591] init: #### JACH #### - bootchart_init'0':'start'
<11>[ 2.814704] init: #### JACH #### - BOOTCHART'0':'bootchart_init_action -bootchart_count'
<11>[ 2.814721] init: #### JACH #### - BOOTCHART'0':'bootchart_init_action -end'
So bootchart_init() as follows:
#define LOG_STARTFILE "/data/bootchart-start"
int bootchart_init( void )
{
ERROR("#### JACH #### - bootchart_init'%d':'%s'\n", 0, "start");
int ret;
char buff[4];
int timeout = 0, count = 0;
buff[0] = 0;
proc_read( LOG_STARTFILE, buff, sizeof(buff) );
if (buff[0] != 0) {
timeout = atoi(buff);;
ERROR("#### JACH #### - bootchart_init'%d':'%s'\n", timeout, "timeout");
}
else {
/* when running with emulator, androidboot.bootchart=<timeout>
* might be passed by as kernel parameters to specify the bootchart
* timeout. this is useful when using -wipe-data since the /data
* partition is fresh
*/
char cmdline[1024];
char* s;
#define KERNEL_OPTION "androidboot.bootchart="
proc_read( "/proc/cmdline", cmdline, sizeof(cmdline) );
s = strstr(cmdline, KERNEL_OPTION);
if (s) {
s += sizeof(KERNEL_OPTION)-1;
timeout = atoi(s);
}
}
if (timeout == 0)
return 0;
if (timeout > BOOTCHART_MAX_TIME_SEC)
timeout = BOOTCHART_MAX_TIME_SEC;
count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS;
do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR);
file_buff_open(log_stat, LOG_STAT);
file_buff_open(log_procs, LOG_PROCS);
file_buff_open(log_disks, LOG_DISK);
/* create kernel process accounting file */
{
int fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644);
if (fd >= 0) {
close(fd);
acct( LOG_ACCT );
}
}
log_header();
ERROR("#### JACH #### - bootchart_init'%d':'%s'\n", 0, "end");
return count;
}
I guess while booting starts the above code(proc_read( LOG_STARTFILE, buff, sizeof(buff) );) has no permission to read or write data or the files partitions are not created. And also I hard coded the timeout but still bootchart_step() function are working, But log files not write in the data/bootchart folder.
But I don't know how to enable this problem. Thanks for attend my question.

setsockopt() get EBADF in mmaped netlink

Im trying to use memory map I/O netlink to transfer bulk packets from kernel to user space, and I followed a guide document from Patrick McHardy 1. However, when I try to setup the shared ring buffer in user space by using:
setsockopt(sock_fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req));
setsockopt(sock_fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req));
Both functions return -1, and the errno is 1, which means the descriptor is invalid. Im confused about that because I also referred to many other source codes and they can setup the ring successfully.
My code is almost the same as Patrick's 1:
int sock_fd = -1;
sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_DECODE);
if (sock_fd < 0)
return -1;
bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
/* init the mmap buffer */
unsigned int block_size = 16 * getpagesize();
struct nl_mmap_req req = {
.nm_block_size = block_size,
.nm_block_nr = 64,
.nm_frame_size = 16384,
.nm_frame_nr = 64 * block_size / 16384,
};
/* Configure ring parameters */
if (setsockopt(sock_fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0){
if(errno > 0)
printf("%d\n", errno);
}
if (setsockopt(sock_fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0){
if(errno > 0)
printf("%d", errno);
exit(1);
}
This code is built in Ubuntu 14.04, and kernel version is 3.13.0-74-generic.
Anyone idea about it? Thanks a lot.

modbus_read_register - Error connection timed out

We are using libmodbus library to read register values from energy meter EM6400 which supports Modbus over RTU. We are facing the following two issues.
1) We are facing an issue with modbus_read_registers API, this API returns -1 and the error message is:
ERROR Connection timed out: select.
After debugging the library, we found this issue is due to the echo of request bytes in the response message.
read() API call in _modbus_rtu_recv returns request bytes first followed by response bytes. As a result, length_to_read is calculated in compute_data_length_after_meta() based on the request bytes instead of response bytes (which contains the number of bytes read) and connection timed out issue occurs.
We tried to use both 3.0.6 and 3.1.2 libmodbus versions but same issue occurs in both the versions.
2) modbus_rtu_set_serial_mode (ctx, MODBUS_RTU_RS485) returns "BAD file descriptor".
Please confirm if there is any API call missing or any parameter is not set correctly.
Our sample code to read register value is as follows.
int main()
{
modbus_t *ctx;
uint16_t tab_reg[2] = {0,0};
float avgVLL = -1;;
int res = 0;
int rc;
int i;
struct timeval response_timeout;
uint32_t tv_sec = 0;
uint32_t tv_usec = 0;
response_timeout.tv_sec = 5;
response_timeout.tv_usec = 0;
ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'E', 8, 1);
if (NULL == ctx)
{
printf("Unable to create libmodbus context\n");
res = 1;
}
else
{
printf("created libmodbus context\n");
modbus_set_debug(ctx, TRUE);
//modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK |MODBUS_ERROR_RECOVERY_PROTOCOL);
rc = modbus_set_slave(ctx, 1);
printf("modbus_set_slave return: %d\n",rc);
if (rc != 0)
{
printf("modbus_set_slave: %s \n",modbus_strerror(errno));
}
/* Commented - Giving 'Bad File Descriptor' issue
rc = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
printf("modbus_rtu_set_serial_mode: %d \n",rc);
if (rc != 0)
{
printf("modbus_rtu_set_serial_mode: %s \n",modbus_strerror(errno));
}
*/
// This code is for version 3.0.6
modbus_get_response_timeout(ctx, &response_timeout);
printf("Default response timeout:%ld sec %ld usec \n", response_timeout.tv_sec, response_timeout.tv_usec );
response_timeout.tv_sec = 60;
response_timeout.tv_usec = 0;
modbus_set_response_timeout(ctx, &response_timeout);
modbus_get_response_timeout(ctx, &response_timeout);
printf("Set response timeout:%ld sec %ld usec \n", response_timeout.tv_sec, response_timeout.tv_usec );
/* This code is for version 3.1.2
modbus_get_response_timeout(ctx, &tv_sec, &tv_usec);
printf("Default response timeout:%d sec %d usec \n",tv_sec,tv_usec );
tv_sec = 60;
tv_usec = 0;
modbus_set_response_timeout(ctx, tv_sec,tv_usec);
modbus_get_response_timeout(ctx, &tv_sec, &tv_usec);
printf("Set response timeout:%d sec %d usec \n",tv_sec,tv_usec );
*/
rc = modbus_connect(ctx);
printf("modbus_connect: %d \n",rc);
if (rc == -1) {
printf("Connection failed: %s\n", modbus_strerror(errno));
res = 1;
}
rc = modbus_read_registers(ctx, 3908, 2, tab_reg);
printf("modbus_read_registers: %d \n",rc);
if (rc == -1) {
printf("Read registers failed: %s\n", modbus_strerror(errno));
res = 1;
}
for (i=0; i < 2; i++) {
printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
}
avgVLL = modbus_get_float(tab_reg);
printf("Average Line to Line Voltage = %f\n", avgVLL);
modbus_close(ctx);
modbus_free(ctx);
}
}
Output of this sample is as follows:
created libmodbus context
modbus_set_slave return: 0
modbus_rtu_set_serial_mode: -1
modbus_rtu_set_serial_mode: Bad file descriptor
Default response timeout:0 sec 500000 usec
Set response timeout:60 sec 0 usec
Opening /dev/ttyUSB0 at 19200 bauds (E, 8, 1)
modbus_connect: 0
[01][03][0F][44][00][02][87][0A]
Waiting for a confirmation...
ERROR Connection timed out: select
<01><03><0F><44><00><02><87><0A><01><03><04><C4><5F><43><D4><C6><7E>modbus_read_registers: -1
Read registers failed: Connection timed out
reg[0]=0 (0x0)
reg[1]=0 (0x0)
Average Line to Line Voltage = 0.000000
Issue 1) is probably a hardware issue, with "local echo" enabled in your RS-485 adapter. Local echo is sometimes used to confirm sending of data bytes on the bus. You need to disable it, or find another RS-485 adapter.
I have written about this in the documentation of my MinimalModbus Python library: Local Echo
It lists a few common ways to disable local echo in RS-485 adapters.