Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
Operating system
Development tools
Security and connectivity
Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
Zoltan Hudak.
3
replies
Hello Angus,
I'm not sure, but I think the issue could result from the assumption that the size of a pointer is two bytes:
struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
struct elem *next;
char dummy[FREEMEM_CELL-2];
};
However, it is rather four bytes. So try:
struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
struct elem *next;
char dummy[FREEMEM_CELL-sizeof(struct elem*)];
};
or
struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
struct elem *next;
char dummy[FREEMEM_CELL-4];
};
and see how it works.
Zoltan Hudak wrote: Hello Angus,
I'm not sure, but I think the issue could result from the assumption that the size of a pointer is two bytes:
struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
struct elem *next;
char dummy[FREEMEM_CELL-2];
};
However, it is rather four bytes. So try:
struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
struct elem *next;
char dummy[FREEMEM_CELL-sizeof(struct elem*)];
};
or
struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */
struct elem *next;
char dummy[FREEMEM_CELL-4];
};
and see how it works.
Hi Zoltan,
Thanks for your reply. While it may have been outputting the wrong memory value, it seems that the thread hangs before it can output the next value. I can't therefore tell if memory is the issue or not, but thanks for pointing this out.
I'm sending {Command:{L1:3}}\n, and the *scanf* is waiting for the *\n* to complete a read of the buffer. The only other time I've seen this hang behaviour is when using *gets* and its waiting to fill the buffer before continuing. Anyone see any reason a *\n* might not be getting through?
Hello Angus,
Nice project! Try to avoid scanf and make the ISR as short as possible by moving the logics from ISR to the main function. For example:
//...
RawSerial pc(USBTX, USBRX);
//...
void Rx_interrupt()
{
int i = 0;
char c = 0;
while pc.readable() {
c = pc.getc();
Buffer[i++]= c;
if ((i == 18) || (c == '\n'))
break;
}
if (c == '\n') {
Buffer[i - 1] = 0; // mark the end of a C-style string (replace '\n' with null char)
status = 1; // flag that a complete command has been received
}
}
int main()
{
//...
while (true) {
if (status == 1) {
// new command received
status = 0; // reset the flag for next use in ISR
if (strcmp(Buffer, "{Command:{L1:3}}") == 0) {
//...
pc.printf("\r\n{Data:{Led1:%.3f,Led2:%.3f,Led3:%.3f,Led4:%.3f,Heater:%.3f,Temp:%.3f,Lux:%.1f,hPa:%04.2f,Hum:%2.2f}}",1-led1.read(), 1-led2.read(), 1-led3.read(), 1-led4.read(), 1-heater.read(), temp.read(), Lux.lux(), sensor.getPressure(), sensor.getHumidity());
pc.printf("\r\n{Free Memory:%d}", FreeMem());
}
}
}
This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.
Hi All,
I'm working with OS2 and the Nucleo-F411RE. Seeing a strange thread hang on a Serial::RxIrq where the received event hangs the main thread and the LED being turned on/off in the method gets 'stuck' between states (flickering). I have buttons on InterruptIn which remain functional during the hang.
I'm not sure why, but the number of receives before a hang is random. At first I thought the number of 'strcmp' functions could be using up memory, so I output the 'free RAM' value to check that, and it appears unchanged at 109700 Bytes, so no runaway buffers. Anyone have any ideas? See below code and video of the problem.
main.cpp
#include "mbed.h" #include "LM75B.h" #include "TSL2561.h" #include "BME280.h" #include <stdio.h> #include <stdlib.h> #define FREEMEM_CELL 100 bool _debug = true; Serial pc(USBTX, USBRX); void Rx_interrupt(); char Buffer[20]; DigitalOut status(LED1); LM75B temp(PB_9, PB_8); TSL2561 Lux(PB_9, PB_8); BME280 sensor(PB_4, PA_8); PwmOut led1(D6); PwmOut led2(D4); PwmOut led3(D3); PwmOut led4(D2); float led1OnValue = 0.6f; float led2OnValue = 0.6f; float led3OnValue = 0.6f; float led4OnValue = 0.6f; PwmOut heater(PA_1); float heaterOnValue = 0.0f; InterruptIn btn1(PA_9, PullUp); InterruptIn btn2(PC_4, PullUp); InterruptIn btn3(PB_6, PullUp); InterruptIn btn4(PA_7, PullUp); bool btn1Pressed = false; bool btn2Pressed = false; bool btn3Pressed = false; bool btn4Pressed = false; void btnCheck(); void btn1Event(); void btn2Event(); void btn3Event(); void btn4Event(); struct elem { /* Definition of a structure that is FREEMEM_CELL bytes in size.) */ struct elem *next; char dummy[FREEMEM_CELL-2]; }; int FreeMem(void) { int counter; struct elem *head, *current, *nextone; current = head = (struct elem*) malloc(sizeof(struct elem)); if (head == NULL) return 0; /*No memory available.*/ counter = 0; // __disable_irq(); do { counter++; current->next = (struct elem*) malloc(sizeof(struct elem)); current = current->next; } while (current != NULL); /* Now counter holds the number of type elem structures we were able to allocate. We must free them all before returning. */ current = head; do { nextone = current->next; free(current); current = nextone; } while (nextone != NULL); // __enable_irq(); return counter*FREEMEM_CELL; } int main() { pc.baud(9600); status = 0; led1.period(0.003f); led2.period(0.003f); led3.period(0.003f); led4.period(0.003f); heater.period(0.003f); led1 = led1OnValue; led2 = led2OnValue; led3 = led3OnValue; led4 = led4OnValue; heater = 1.0f; btn1.rise(&btn1Event); btn2.rise(&btn2Event); btn3.rise(&btn3Event); btn4.rise(&btn4Event); pc.attach(&Rx_interrupt, Serial::RxIrq); while (true) { pc.printf("\r\n{Data:{Led1:%.3f,Led2:%.3f,Led3:%.3f,Led4:%.3f,Heater:%.3f,Temp:%.3f,Lux:%.1f,hPa:%04.2f,Hum:%2.2f}}",1-led1.read(), 1-led2.read(), 1-led3.read(), 1-led4.read(), 1-heater.read(), temp.read(), Lux.lux(), sensor.getPressure(), sensor.getHumidity()); pc.printf("\r\n{Free Memory:%d}", FreeMem()); wait(0.5); } } void btn1Event() { if(btn1.read() == 0) { if(btn1Pressed == false) { wait(0.2); if(btn1.read() == 0) { if(led4 == led4OnValue) { led4 = 1.0f; } else { led4 = led4OnValue; } btn1Pressed = true; } } } else { btn1Pressed = false; } } void btn2Event() { if(btn2.read() == 0) { if(btn2Pressed == false) { wait(0.2); if(btn2.read() == 0) { if(led3 == led3OnValue) { led3 = 1.0f; } else { led3 = led3OnValue; } btn2Pressed = true; } } } else { btn2Pressed = false; } } void btn3Event() { if(btn3.read() == 0) { if(btn3Pressed == false) { wait(0.2); if(btn3.read() == 0) { if(led2 == led2OnValue) { led2 = 1.0f; } else { led2 = led2OnValue; } btn3Pressed = true; } } } else { btn3Pressed = false; } } void btn4Event() { if(btn4.read() == 0) { if(btn4Pressed == false) { wait(0.2); if(btn4.read() == 0) { if(led1 == led1OnValue) { led1 = 1.0f; } else { led1 = led1OnValue; } btn4Pressed = true; } } } else { btn4Pressed = false; } } void Rx_interrupt() { status = 1; pc.scanf("%17s",Buffer); if(strcmp(Buffer, "{Command:{L1:3}}") == 0) { if(led1 == led1OnValue) { led1 = 1.0f; } else { led1 = led1OnValue; } } else if(strcmp(Buffer, "{Command:{L1:0}}") == 0) { led1 = 1.0f; } else if(strcmp(Buffer, "{Command:{L1:1}}") == 0) { led1 = led1OnValue; } else if(strcmp(Buffer, "{Command:{L2:3}}") == 0) { if(led2 == led2OnValue) { led2 = 1.0f; } else { led2 = led2OnValue; } } else if(strcmp(Buffer, "{Command:{L2:0}}") == 0) { led2 = 1.0f; } else if(strcmp(Buffer, "{Command:{L2:1}}") == 0) { led2 = led2OnValue; } else if(strcmp(Buffer, "{Command:{L3:3}}") == 0) { if(led3 == led3OnValue) { led3 = 1.0f; } else { led3 = led3OnValue; } } else if(strcmp(Buffer, "{Command:{L3:0}}") == 0) { led3 = 1.0f; } else if(strcmp(Buffer, "{Command:{L3:1}}") == 0) { led3 = led3OnValue; } status = 0; }