Move mode specific delay outside mutex + logging (control.cpp)
potentially fix rare deadlock assuming handle loop takes mutex too fast again so changeMode never takes it
This commit is contained in:
parent
5249ac64e0
commit
c13006241e
@ -120,21 +120,55 @@ void controlledArmchair::startHandleLoop()
|
|||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
// === handle current mode ===
|
||||||
// mutex to prevent race condition with actions beeing run at mode change and previous mode still beeing executed
|
// mutex to prevent race condition with actions beeing run at mode change and previous mode still beeing executed
|
||||||
|
ESP_LOGV(TAG, "handle(): requesting mutex...");
|
||||||
if (xSemaphoreTake(handleIteration_mutex, MUTEX_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE)
|
if (xSemaphoreTake(handleIteration_mutex, MUTEX_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG, "handle(): got mutex!");
|
||||||
//--- handle current mode ---
|
//--- handle current mode ---
|
||||||
ESP_LOGV(TAG, "control loop executing... mode='%s'", controlModeStr[(int)mode]);
|
ESP_LOGV(TAG, "control loop executing... mode='%s'", controlModeStr[(int)mode]);
|
||||||
handle();
|
handle();
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "handle(): releasing mutex");
|
||||||
xSemaphoreGive(handleIteration_mutex);
|
xSemaphoreGive(handleIteration_mutex);
|
||||||
} // end mutex
|
} // end mutex
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "mutex timeout - stuck in changeMode? -> RESTART");
|
ESP_LOGE(TAG, "mutex timeout - stuck in changeMode? -> RESTART");
|
||||||
esp_restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- slow loop ---
|
// ==== run mode specific delay ===
|
||||||
|
// outsourced here to not block the mutex by just waiting
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case controlMode_t::IDLE:
|
||||||
|
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||||
|
break;
|
||||||
|
case controlMode_t::JOYSTICK:
|
||||||
|
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||||
|
break;
|
||||||
|
case controlMode_t::MASSAGE:
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
|
break;
|
||||||
|
case controlMode_t::HTTP:
|
||||||
|
// has 500ms timeout waiting for new events, thus blocks mutex...
|
||||||
|
break;
|
||||||
|
case controlMode_t::AUTO:
|
||||||
|
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||||
|
break;
|
||||||
|
case controlMode_t::ADJUST_CHAIR:
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
break;
|
||||||
|
case controlMode_t::MENU_SETTINGS:
|
||||||
|
case controlMode_t::MENU_MODE_SELECT:
|
||||||
|
vTaskDelay(500 / portTICK_PERIOD_MS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=== slow loop, timeout ===
|
||||||
// this section is run approx every 5s (+500ms)
|
// this section is run approx every 5s (+500ms)
|
||||||
if (esp_log_timestamp() - timestamp_SlowLoopLastRun > 5000)
|
if (esp_log_timestamp() - timestamp_SlowLoopLastRun > 5000)
|
||||||
{
|
{
|
||||||
@ -150,12 +184,14 @@ void controlledArmchair::startHandleLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
//---------- Handle control -----------
|
//---------- Handle control -----------
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// function that repeatedly generates motor commands and runs actions depending on the current mode
|
// function that repeatedly generates motor commands and runs actions depending on the current mode
|
||||||
void controlledArmchair::handle()
|
void controlledArmchair::handle()
|
||||||
{
|
{
|
||||||
|
//note: mode specific delays are outsourced to startHandleLoop() to not block the mutex
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
@ -166,7 +202,6 @@ void controlledArmchair::handle()
|
|||||||
|
|
||||||
//------- handle IDLE -------
|
//------- handle IDLE -------
|
||||||
case controlMode_t::IDLE:
|
case controlMode_t::IDLE:
|
||||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
|
||||||
// TODO repeatedly set motors to idle, in case driver bugs? Currently 15s motorctl timeout would have to pass
|
// TODO repeatedly set motors to idle, in case driver bugs? Currently 15s motorctl timeout would have to pass
|
||||||
#ifdef JOYSTICK_LOG_IN_IDLE
|
#ifdef JOYSTICK_LOG_IN_IDLE
|
||||||
// get joystick data and log it
|
// get joystick data and log it
|
||||||
@ -180,7 +215,6 @@ void controlledArmchair::handle()
|
|||||||
|
|
||||||
//------- handle JOYSTICK mode -------
|
//------- handle JOYSTICK mode -------
|
||||||
case controlMode_t::JOYSTICK:
|
case controlMode_t::JOYSTICK:
|
||||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
|
||||||
// get current joystick data with getData method of evaluatedJoystick
|
// get current joystick data with getData method of evaluatedJoystick
|
||||||
stickDataLast = stickData;
|
stickDataLast = stickData;
|
||||||
stickData = joystick_l->getData();
|
stickData = joystick_l->getData();
|
||||||
@ -205,7 +239,6 @@ void controlledArmchair::handle()
|
|||||||
|
|
||||||
//------- handle MASSAGE mode -------
|
//------- handle MASSAGE mode -------
|
||||||
case controlMode_t::MASSAGE:
|
case controlMode_t::MASSAGE:
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
||||||
//--- read joystick ---
|
//--- read joystick ---
|
||||||
// only update joystick data when input not frozen
|
// only update joystick data when input not frozen
|
||||||
stickDataLast = stickData;
|
stickDataLast = stickData;
|
||||||
@ -250,7 +283,6 @@ void controlledArmchair::handle()
|
|||||||
|
|
||||||
//------- handle AUTO mode -------
|
//------- handle AUTO mode -------
|
||||||
case controlMode_t::AUTO:
|
case controlMode_t::AUTO:
|
||||||
vTaskDelay(20 / portTICK_PERIOD_MS);
|
|
||||||
// generate commands
|
// generate commands
|
||||||
commands = automatedArmchair->generateCommands(&instruction);
|
commands = automatedArmchair->generateCommands(&instruction);
|
||||||
//--- apply commands to motors ---
|
//--- apply commands to motors ---
|
||||||
@ -291,7 +323,6 @@ void controlledArmchair::handle()
|
|||||||
|
|
||||||
//------- handle ADJUST_CHAIR mode -------
|
//------- handle ADJUST_CHAIR mode -------
|
||||||
case controlMode_t::ADJUST_CHAIR:
|
case controlMode_t::ADJUST_CHAIR:
|
||||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
|
||||||
//--- read joystick ---
|
//--- read joystick ---
|
||||||
stickDataLast = stickData;
|
stickDataLast = stickData;
|
||||||
stickData = joystick_l->getData();
|
stickData = joystick_l->getData();
|
||||||
@ -308,7 +339,6 @@ void controlledArmchair::handle()
|
|||||||
case controlMode_t::MENU_SETTINGS:
|
case controlMode_t::MENU_SETTINGS:
|
||||||
case controlMode_t::MENU_MODE_SELECT:
|
case controlMode_t::MENU_MODE_SELECT:
|
||||||
// nothing to do here, display task handles the menu
|
// nothing to do here, display task handles the menu
|
||||||
vTaskDelay(500 / portTICK_PERIOD_MS);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO: add other modes here
|
// TODO: add other modes here
|
||||||
@ -457,8 +487,10 @@ void controlledArmchair::changeMode(controlMode_t modeNew, bool noBeep)
|
|||||||
// mutex to wait for current handle iteration (control-task) to finish
|
// mutex to wait for current handle iteration (control-task) to finish
|
||||||
// prevents race conditions where operations when changing mode are run but old mode gets handled still
|
// prevents race conditions where operations when changing mode are run but old mode gets handled still
|
||||||
ESP_LOGI(TAG, "changeMode: waiting for current handle() iteration to finish...");
|
ESP_LOGI(TAG, "changeMode: waiting for current handle() iteration to finish...");
|
||||||
|
ESP_LOGV(TAG, "changemode(): requesting mutex...");
|
||||||
if (xSemaphoreTake(handleIteration_mutex, MUTEX_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE)
|
if (xSemaphoreTake(handleIteration_mutex, MUTEX_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE)
|
||||||
{
|
{
|
||||||
|
ESP_LOGV(TAG, "changemode(): got mutex!");
|
||||||
// copy previous mode
|
// copy previous mode
|
||||||
modePrevious = mode;
|
modePrevious = mode;
|
||||||
// store time changed (needed for timeout)
|
// store time changed (needed for timeout)
|
||||||
@ -569,6 +601,7 @@ void controlledArmchair::changeMode(controlMode_t modeNew, bool noBeep)
|
|||||||
mode = modeNew;
|
mode = modeNew;
|
||||||
|
|
||||||
// unlock mutex for control task to continue handling modes
|
// unlock mutex for control task to continue handling modes
|
||||||
|
ESP_LOGV(TAG, "changemode(): releasing mutex");
|
||||||
xSemaphoreGive(handleIteration_mutex);
|
xSemaphoreGive(handleIteration_mutex);
|
||||||
} // end mutex
|
} // end mutex
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user