"malloc assert!" in interrupt routine
"malloc assert!" in interrupt routine
Postby FrenkR » Sat Dec 27, 2014 9:52 pm
Hi,
I have following scenario. I have defined one "os_task" and GPIO interrupt routine. In interrupt routine, I have dynamically allocated memory for my structure) using os_zalloc(sizeof(mystruct)). After filling structure, I am posting message to a task(system_os_post()), with pointer to structure casted as uint32_t parameter. In a os_task routine, I would read allocated structure and free memory.
If I cast only pointer to uint32_t and send this pointer to os_task, I am getting "malloc assert!" error and module is reset. If I free memory inside interrupt routine then is ok. (It looks like memory allocation inside interrupt routine is done correctly, problem is that system somehow trace pointers and because pointer to this sturcture is "casted" to uint32_t(parameter type in system_os_post is os_param_t par), then it looses reference and reports "malloc assert!".
Is there some other way to allocate memory/fill struct and then send pointer to the allocated mem via system_os_post()? Memory strutct is then deallocated inside os_task handler routine.
Rgds,
Frenk
[/code]
I have following scenario. I have defined one "os_task" and GPIO interrupt routine. In interrupt routine, I have dynamically allocated memory for my structure) using os_zalloc(sizeof(mystruct)). After filling structure, I am posting message to a task(system_os_post()), with pointer to structure casted as uint32_t parameter. In a os_task routine, I would read allocated structure and free memory.
If I cast only pointer to uint32_t and send this pointer to os_task, I am getting "malloc assert!" error and module is reset. If I free memory inside interrupt routine then is ok. (It looks like memory allocation inside interrupt routine is done correctly, problem is that system somehow trace pointers and because pointer to this sturcture is "casted" to uint32_t(parameter type in system_os_post is os_param_t par), then it looses reference and reports "malloc assert!".
Is there some other way to allocate memory/fill struct and then send pointer to the allocated mem via system_os_post()? Memory strutct is then deallocated inside os_task handler routine.
Rgds,
Frenk
[/code]
Re: "malloc assert!" in interrupt routine
Postby FrenkR » Tue Dec 30, 2014 7:13 am
user_main.c
if os_free() is commented in interrupt routine and uncommented in "task" routine, "malloc assert" error is reported on UART1(debug). Pointer to a GPIO structure cannot be forwarded as (casted) "event->par" arg.
Code: Select all
#include "osapi.h"
#include "user_interface.h"
#include "driver/uart.h"
#include "user_config.h"
#include "eagle_soc.h"
#include "ets_sys.h"
#include "gpio.h"
#include "mem.h"
static volatile os_timer_t tmrSstart;
os_event_t user_procTaskQueue[user_procTaskQueueLen];
//Main code function
static void ICACHE_FLASH_ATTR
loop(os_event_t *events)
{
os_printf("Task sig=%u, par=%u!\r\n",events->sig, events->par);
GPIOState * _gpioState = (GPIOState *)(events->par);
// if os_free() is uncommented in iw_GPIO_handler routine, you must comment this line.
os_free(_gpioState);
os_printf("Task executed and memory disposed!\r\n");
}
static void ICACHE_FLASH_ATTR
startTask(void *arg){
system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);
}
// GPIO interrupt handler:store local data and start task
static void ICACHE_FLASH_ATTR
iw_GPIO_handler(int8_t key){
GPIOState * _gpioState = (GPIOState *)os_zalloc(sizeof(GPIOState));
uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
uint32_t rtc_now = system_get_rtc_time();
_gpioState->GPIOState = gpio_status;
_gpioState->RtcTime = rtc_now;
// activate task
system_os_post(user_procTaskPrio, 0, (uint32_t)_gpioState);
// if you uncomment following line, "memalloc assert" error will be removed
//os_free(_gpioState);
// clear pending interrupts
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
}
//Init function
void ICACHE_FLASH_ATTR
user_init()
{
uart_init(BIT_RATE_115200, BIT_RATE_115200);
os_delay_us(1000);
uart0_sendStr("Start!\r\n");
//Start os task
system_os_task(loop, user_procTaskPrio, user_procTaskQueue, user_procTaskQueueLen);
// set interrupt routine
// start first run with timer(otherwise doesn't work?)
ETS_GPIO_INTR_DISABLE();
// GPIO12 interrupt handler
ETS_GPIO_INTR_ATTACH(iw_GPIO_handler, 12);
// pin 13 setup
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13); // select pin to GPIO 13 mode
GPIO_DIS_OUTPUT(13); // set pin to "input" mode
PIN_PULLDWN_DIS(PERIPHS_IO_MUX_MTCK_U); // disable pullodwn
PIN_PULLUP_EN(PERIPHS_IO_MUX_MTCK_U); // pull - up pin
// interrupt on GPIO 13
gpio_pin_intr_state_set(GPIO_ID_PIN(13), GPIO_PIN_INTR_LOLEVEL); // Interrupt on any GPIO13 edge
// Enable gpio interrupts
ETS_GPIO_INTR_ENABLE();
}
if os_free() is commented in interrupt routine and uncommented in "task" routine, "malloc assert" error is reported on UART1(debug). Pointer to a GPIO structure cannot be forwarded as (casted) "event->par" arg.
Re: "malloc assert!" in interrupt routine
Postby jackon » Wed Dec 31, 2014 11:05 am
Do you use push button?
It will cause too many interrupts, and user_procTaskQueueLen is limited, so system_os_post will not be able to post all events to your task.
Then os_free will not be called in your loop function, 'malloc assert' happened.
I modify your iw_GPIO_handler, as follow:
system_os_post will return false while send queue is full, the attachment is patch for 0.9.5(b1).
Try and give me feedback.
It will cause too many interrupts, and user_procTaskQueueLen is limited, so system_os_post will not be able to post all events to your task.
Then os_free will not be called in your loop function, 'malloc assert' happened.
I modify your iw_GPIO_handler, as follow:
Code: Select all
// GPIO interrupt handler:store local data and start task
static void iw_GPIO_handler(int8_t key)
{
GPIOState * _gpioState = (GPIOState *)os_zalloc(sizeof(GPIOState));
os_printf("heap size %d\n", system_get_free_heap_size());
uint32_t gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
uint32_t rtc_now = system_get_rtc_time();
_gpioState->GPIOState = gpio_status;
_gpioState->RtcTime = rtc_now;
// activate task
if (system_os_post(user_procTaskPrio, 0, (uint32_t)_gpioState) == false) {
os_free(_gpioState);
}
// if you uncomment following line, "memalloc assert" error will be removed
//os_free(_gpioState);
// clear pending interrupts
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
}
system_os_post will return false while send queue is full, the attachment is patch for 0.9.5(b1).
Try and give me feedback.
- Attachments
-
- patch_for_0.9.5(b1).zip
- (31.35 KiB) Downloaded 454 times
Who is online
Users browsing this forum: No registered users and 91 guests
Login
Newbies Start Here
Are you new to ESP8266?
Unsure what to do?
Dunno where to start?
Start right here!
Latest SDK
Documentation
Complete listing of the official ESP8266 related documentation release by ESPRESSIF!
Must read here!
- All times are UTC+08:00
- Top
- Delete all board cookies
About Us
Espressif Systems is a fabless semiconductor company providing cutting-edge low power WiFi SoCs and wireless solutions for wireless communications and Internet of Things applications. We are the manufacturer of ESP8266EX.