Skip to content

Commit

Permalink
psu and scpi thread synchronisation
Browse files Browse the repository at this point in the history
  • Loading branch information
mvladic committed Jul 16, 2019
1 parent 7496768 commit e5e2c5b
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 54 deletions.
20 changes: 19 additions & 1 deletion src/eez/apps/psu/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ osThreadDef(g_psuTask, mainLoop, osPriorityNormal, 0, 1024);

osThreadId g_psuTaskHandle;

#define PSU_QUEUE_SIZE 10

osMessageQDef(g_psuMessageQueue, PSU_QUEUE_SIZE, uint32_t);
osMessageQId g_psuMessageQueueId;

bool onSystemStateChanged() {
if (g_systemState == eez::SystemState::BOOTING) {
if (g_systemStatePhase == 0) {
Expand All @@ -48,6 +53,7 @@ bool onSystemStateChanged() {
#endif
boot();

g_psuMessageQueueId = osMessageCreate(osMessageQ(g_psuMessageQueue), NULL);
g_psuTaskHandle = osThreadCreate(osThread(g_psuTask), nullptr);
}
}
Expand All @@ -69,7 +75,19 @@ void mainLoop(const void *) {
}

void oneIter() {
tick();
osEvent event = osMessageGet(g_psuMessageQueueId, 0);
if (event.status == osEventMessage) {
uint32_t message = event.value.v;
uint32_t type = PSU_QUEUE_MESSAGE_TYPE(message);
uint32_t param = PSU_QUEUE_MESSAGE_PARAM(message);
if (type == PSU_QUEUE_MESSAGE_TYPE_CHANGE_POWER_STATE) {
changePowerState(param ? true : false);
} else if (type == PSU_QUEUE_MESSAGE_TYPE_RESET) {
reset();
}
} else {
tick();
}
}

} // namespace psu
Expand Down
13 changes: 13 additions & 0 deletions src/eez/apps/psu/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,22 @@

#pragma once

#include <cmsis_os.h>

namespace eez {
namespace psu {

bool onSystemStateChanged();

extern osThreadId g_psuTaskHandle;
extern osMessageQId g_psuMessageQueueId;

#define PSU_QUEUE_MESSAGE_TYPE_CHANGE_POWER_STATE 1
#define PSU_QUEUE_MESSAGE_TYPE_RESET 2

#define PSU_QUEUE_MESSAGE(type, param) (((param) << 4) | (type))
#define PSU_QUEUE_MESSAGE_TYPE(message) ((message) & 0xF)
#define PSU_QUEUE_MESSAGE_PARAM(param) ((message) >> 4)

}
} // namespace eez
25 changes: 23 additions & 2 deletions src/eez/apps/psu/list_program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include <scpi/scpi.h>

#include <eez/scpi/scpi.h>

#include <eez/apps/psu/channel_dispatcher.h>
#include <eez/apps/psu/list_program.h>
#include <eez/apps/psu/trigger.h>
Expand All @@ -34,6 +36,9 @@
#define CONF_COUNTER_THRESHOLD_IN_SECONDS 5

namespace eez {

using namespace scpi;

namespace psu {
namespace list {

Expand Down Expand Up @@ -203,8 +208,16 @@ int checkLimits(int iChannel) {
return 0;
}

bool loadList(Channel &channel, const char *filePath, int *err) {
bool loadList(int iChannel, const char *filePath, int *err) {
#if OPTION_SD_CARD
if (osThreadGetId() != g_scpiTaskHandle) {
strcpy(&g_listFilePath[iChannel][0], filePath);
osMessagePut(g_scpiMessageQueueId, SCPI_QUEUE_MESSAGE(SCPI_QUEUE_MESSAGE_TARGET_NONE, SCPI_QUEUE_MESSAGE_TYPE_LOAD_LIST, iChannel), osWaitForever);
return true;
}

Channel &channel = Channel::get(iChannel);

if (sd_card::g_testResult != TEST_OK) {
*err = SCPI_ERROR_MASS_STORAGE_ERROR;
return false;
Expand Down Expand Up @@ -325,8 +338,16 @@ bool loadList(Channel &channel, const char *filePath, int *err) {
#endif
}

bool saveList(Channel &channel, const char *filePath, int *err) {
bool saveList(int iChannel, const char *filePath, int *err) {
#if OPTION_SD_CARD
if (osThreadGetId() != g_scpiTaskHandle) {
strcpy(&g_listFilePath[iChannel][0], filePath);
osMessagePut(g_scpiMessageQueueId, SCPI_QUEUE_MESSAGE(SCPI_QUEUE_MESSAGE_TARGET_NONE, SCPI_QUEUE_MESSAGE_TYPE_SAVE_LIST, iChannel), osWaitForever);
return true;
}

Channel &channel = Channel::get(iChannel);

if (sd_card::g_testResult != TEST_OK) {
*err = SCPI_ERROR_MASS_STORAGE_ERROR;
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/eez/apps/psu/list_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ bool areVoltageAndCurrentListLengthsEquivalent(Channel &channel);

int checkLimits(int iChannel);

bool loadList(Channel &channel, const char *filePath, int *err);
bool saveList(Channel &channel, const char *filePath, int *err);
bool loadList(int iChannel, const char *filePath, int *err);
bool saveList(int iChannel, const char *filePath, int *err);

void executionStart(Channel &channel);

Expand Down
4 changes: 2 additions & 2 deletions src/eez/apps/psu/profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void recallChannelsFromProfile(Parameters *profile, int location) {
char filePath[MAX_PATH_LENGTH];
getChannelProfileListFilePath(channel, location, filePath);
int err;
if (list::loadList(channel, filePath, &err)) {
if (list::loadList(channel.index - 1, filePath, &err)) {
if (location == 0) {
list::setListsChanged(channel, false);
}
Expand Down Expand Up @@ -384,7 +384,7 @@ void fillProfile(Parameters *pProfile, int location, const char *name,
char filePath[MAX_PATH_LENGTH];
getChannelProfileListFilePath(channel, location, filePath);
if (list::areListLengthsEquivalent(channel)) {
list::saveList(channel, filePath, NULL);
list::saveList(channel.index - 1, filePath, NULL);
profile.channels[i].flags.listSaved = 1;
} else {
sd_card::deleteFile(filePath, NULL);
Expand Down
26 changes: 13 additions & 13 deletions src/eez/apps/psu/psu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <eez/system.h>

#include <eez/apps/psu/init.h>
#include <eez/apps/psu/serial_psu.h>

#if OPTION_ETHERNET
Expand Down Expand Up @@ -92,8 +93,6 @@ static uint32_t g_powerDownTime;

static MaxCurrentLimitCause g_maxCurrentLimitCause;

static int g_changePowerStateOnNextTick; // -1: do not change, 0: change to power down, 1: change to power up

RLState g_rlState = RL_STATE_LOCAL;

bool g_rprogAlarm = false;
Expand Down Expand Up @@ -602,6 +601,11 @@ bool isPowerUp() {
}

bool changePowerState(bool up) {
if (osThreadGetId() != g_psuTaskHandle) {
osMessagePut(g_psuMessageQueueId, PSU_QUEUE_MESSAGE(PSU_QUEUE_MESSAGE_TYPE_CHANGE_POWER_STATE, up ? 1 : 0), osWaitForever);
return true;
}

if (up == g_powerIsUp)
return true;

Expand All @@ -618,14 +622,14 @@ bool changePowerState(bool up) {
// auto recall channels parameters from profile
profile::Parameters profile;
int location;
auto x = loadAutoRecallProfile(&profile, &location);
auto recall = loadAutoRecallProfile(&profile, &location);

if (!powerUp()) {
return false;
}

// auto recall channels parameters from profile
if (x) {
if (recall) {
for (int i = 0; i < temp_sensor::NUM_TEMP_SENSORS; ++i) {
memcpy(&temperature::sensors[i].prot_conf, profile.temp_prot + i,
sizeof(temperature::ProtectionConfiguration));
Expand Down Expand Up @@ -653,10 +657,6 @@ bool changePowerState(bool up) {
return true;
}

void scheduleChangePowerState(bool up) {
g_changePowerStateOnNextTick = up ? 1 : 0;
}

void powerDownBySensor() {
if (g_powerIsUp) {
#if OPTION_DISPLAY
Expand All @@ -680,6 +680,11 @@ void powerDownBySensor() {
////////////////////////////////////////////////////////////////////////////////

bool reset() {
if (osThreadGetId() != g_psuTaskHandle) {
osMessagePut(g_psuMessageQueueId, PSU_QUEUE_MESSAGE(PSU_QUEUE_MESSAGE_TYPE_RESET, 0), osWaitForever);
return true;
}

if (psuReset()) {
profile::save();
return true;
Expand Down Expand Up @@ -714,11 +719,6 @@ void onProtectionTripped() {
void tick() {
++g_mainLoopCounter;

if (g_changePowerStateOnNextTick != -1) {
changePowerState(g_changePowerStateOnNextTick ? true : false);
g_changePowerStateOnNextTick = -1;
}

uint32_t tick_usec = micros();

static uint32_t lastTickList = 0;
Expand Down
1 change: 0 additions & 1 deletion src/eez/apps/psu/psu.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ bool powerUp();
void powerDown();
bool isPowerUp();
bool changePowerState(bool up);
void schedulePowerDown();
void powerDownBySensor();

bool reset();
Expand Down
4 changes: 2 additions & 2 deletions src/eez/apps/psu/scpi/mmem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ scpi_result_t scpi_cmd_mmemoryLoadList(scpi_t *context) {
}

int err;
if (!list::loadList(*channel, filePath, &err)) {
if (!list::loadList(channel->index - 1, filePath, &err)) {
SCPI_ErrorPush(context, err);
return SCPI_RES_ERR;
}
Expand Down Expand Up @@ -705,7 +705,7 @@ scpi_result_t scpi_cmd_mmemoryStoreList(scpi_t *context) {
addExtension(filePath, LIST_EXT);

int err;
if (!list::saveList(*channel, filePath, &err)) {
if (!list::saveList(channel->index - 1, filePath, &err)) {
SCPI_ErrorPush(context, err);
return SCPI_RES_ERR;
}
Expand Down
30 changes: 14 additions & 16 deletions src/eez/apps/psu/sd_card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,33 +316,31 @@ bool upload(const char *filePath, void *param,
return result;
}

static File file;

bool download(const char *filePath, bool truncate, const void *buffer, size_t size, int *err) {
if (sd_card::g_testResult != TEST_OK) {
if (err)
*err = SCPI_ERROR_MASS_STORAGE_ERROR;
return false;
}

if (truncate) {
if (!file.open(filePath, FILE_OPEN_APPEND | FILE_WRITE)) {
if (err)
*err = SCPI_ERROR_FILE_NAME_NOT_FOUND;
return false;
}
File file;

if (truncate && !file.truncate(0)) {
if (err)
*err = SCPI_ERROR_MASS_STORAGE_ERROR;
return false;
}
}
if (!file.open(filePath, FILE_OPEN_APPEND | FILE_WRITE)) {
if (err)
*err = SCPI_ERROR_FILE_NAME_NOT_FOUND;
return false;
}

size_t written = file.write((const uint8_t *)buffer, size);
if (truncate && !file.truncate(0)) {
file.close();
if (err)
*err = SCPI_ERROR_MASS_STORAGE_ERROR;
return false;
}

size_t written = file.write((const uint8_t *)buffer, size);

//file.close();
file.close();

if (written != size) {
if (err)
Expand Down
2 changes: 1 addition & 1 deletion src/eez/apps/psu/trigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void onTriggerFinished(Channel &channel) {
channel_dispatcher::setVoltage(channel, 0);
channel_dispatcher::setCurrent(channel, 0);
channel_dispatcher::outputEnable(channel, false);
scheduleChangePowerState(false);
changePowerState(false);
break;
}
}
Expand Down
1 change: 0 additions & 1 deletion src/eez/libs/sd_fat/stm32/sd_fat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ void File::sync() {
}

void File::print(float value, int numDecimalDigits) {
// TODO: test this
char buffer[32];
sprintf(buffer, "%.*f", numDecimalDigits, value);
write((uint8_t *)buffer, strlen(buffer));
Expand Down
22 changes: 18 additions & 4 deletions src/eez/platform/simulator/cmsis_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@

#ifdef __EMSCRIPTEN__
#define MAX_THREADS 100

static struct {
struct Thread {
const osThreadDef_t *thread_def;
void *argument;
} g_threads[MAX_THREADS];
};

static Thread g_threads[MAX_THREADS];
Thread *g_currentThread;
#endif

osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) {
#ifdef EEZ_PLATFORM_SIMULATOR_WIN32
DWORD threadId;
return CreateThread(NULL, thread_def->stacksize, (LPTHREAD_START_ROUTINE)thread_def->pthread,
CreateThread(NULL, thread_def->stacksize, (LPTHREAD_START_ROUTINE)thread_def->pthread,
argument, 0, &threadId);
return threadId;
#elif defined(__EMSCRIPTEN__)
for (int i = 0; i < MAX_THREADS; ++i) {
if (!g_threads[i].thread_def) {
Expand All @@ -41,10 +44,21 @@ osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) {
#endif
}

osThreadId osThreadGetId() {
#ifdef EEZ_PLATFORM_SIMULATOR_WIN32
return GetCurrentThreadId();
#elif defined(__EMSCRIPTEN__)
return g_currentThread;
#else
return pthread_self();
#endif
}

#ifdef __EMSCRIPTEN__
void eez_system_tick() {
for (int i = 0; i < MAX_THREADS; ++i) {
if (g_threads[i].thread_def) {
g_currentThread = &g_threads[i];
g_threads[i].thread_def->pthread(g_threads[i].argument);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/eez/platform/simulator/cmsis_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ typedef struct os_thread_def {
const osThreadDef_t os_thread_def_##name = { #name, (os_thread_func_##name), (priority), \
(instances), (stacksz) }

typedef void *osThreadId;
typedef uint32_t osThreadId;
#else

#include <pthread.h>
Expand All @@ -63,6 +63,8 @@ typedef pthread_t osThreadId;

osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument);

osThreadId osThreadGetId();

osStatus osKernelStart(void);

osStatus osDelay(uint32_t millisec);
Expand Down
Loading

0 comments on commit e5e2c5b

Please sign in to comment.