* [simulation] Hardening: Fix some potential crashes & 26 memory leaks, improve LCD performance. * [simpgmspace] Init trims; Make sure `REa` is really defined (to match board files). * [simpgmspace][opentxsimulator] Verify current running state before start/stop; Move rotary enc. init. * [simpgmspace][LcdWidget] Improve performance by moving LCD content change check to lcdRefresh() & limiting LcdWidget refresh time to 60 fps max. * [simueeprom] Ensure thread could be started, set default running state to false. * [simufatfs] Fix paths report trace. * [eepromimportexport] Fix memory leaks resulting from import debugging scheme being used. * [customdebug] Introduce new scheme for custom debug output in compliance with Qt recommendations (see docs for QLoggingCategory). * [opentxeeprom] Fix extra conversion table cache elements being created and also not properly deleted (and hence leaking). * [opentxinterface] Unregister EEpromInterfaces in unregisterOpenTxFirmwares(); * [storage] Unregister storage factories on exit (fixes leak); create virtual StorageFormat/StorageFactory destructors (prevents warnings). * [helpers] GVarGroup now emits own signal, no need to pass ModelPanel pointer (removes dependency on modeledit.h) * [DebugOutput] Clear simulator trace hook before exiting (prevent possible issues); Fix leak and possible bad QString allocations when reading from buffer; Fix leak with combo box event filter. * [TelemetrySimulator] Fix leak by deleting LogPlaybackController object on exit; Only set up data fields once; convert timers to static. * [build] Consolidate all Companion/Simulator shared items in `common` library to reduce build time/etc (node & edge still remain awkward). * [simulatorwidget] Delete removed spacer object (previously-forgotten "26th" leak). * [DebugOutput] Fix stray trailing characters issue with new text buffer allocation (from previous commit); Increase maximum buffer sizes to better accommodate slower systems. * Cosmetics.
187 lines
4.3 KiB
C++
187 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) OpenTX
|
|
*
|
|
* Based on code named
|
|
* th9x - http://code.google.com/p/th9x
|
|
* er9x - http://code.google.com/p/er9x
|
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
|
*
|
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "opentx.h"
|
|
|
|
const char * eepromFile = NULL;
|
|
FILE * fp = NULL;
|
|
|
|
uint32_t eeprom_pointer;
|
|
uint8_t * eeprom_buffer_data;
|
|
volatile int32_t eeprom_buffer_size;
|
|
bool eeprom_read_operation;
|
|
|
|
bool eeprom_thread_running = false;
|
|
|
|
#if defined(EEPROM_SIZE)
|
|
uint8_t eeprom[EEPROM_SIZE];
|
|
#else
|
|
uint8_t * eeprom = NULL;
|
|
#endif
|
|
|
|
sem_t * eeprom_write_sem;
|
|
|
|
void eepromReadBlock (uint8_t * buffer, size_t address, size_t size)
|
|
{
|
|
assert(size);
|
|
|
|
if (fp) {
|
|
// TRACE("EEPROM read (pos=%d, size=%d)", pointer_eeprom, size);
|
|
if (fseek(fp, address, SEEK_SET) < 0)
|
|
perror("error in fseek");
|
|
if (fread(buffer, size, 1, fp) <= 0)
|
|
perror("error in fread");
|
|
}
|
|
else {
|
|
memcpy(buffer, &eeprom[address], size);
|
|
}
|
|
}
|
|
|
|
void eepromSimuWriteBlock(uint8_t * buffer, size_t address, size_t size)
|
|
{
|
|
assert(size);
|
|
|
|
if (fp) {
|
|
// TRACE("EEPROM write (pos=%d, size=%d)", pointer_eeprom, size);
|
|
if (fseek(fp, address, SEEK_SET) < 0)
|
|
perror("error in fseek");
|
|
if (fwrite(buffer, size, 1, fp) <= 0)
|
|
perror("error in fwrite");
|
|
}
|
|
else {
|
|
memcpy(&eeprom[address], buffer, size);
|
|
}
|
|
}
|
|
|
|
volatile uint8_t eepromTransferComplete = 1;
|
|
void * eeprom_thread_function(void *)
|
|
{
|
|
while (!sem_wait(eeprom_write_sem)) {
|
|
if (!eeprom_thread_running)
|
|
return NULL;
|
|
assert(eeprom_buffer_size);
|
|
if (eeprom_read_operation) {
|
|
eepromReadBlock(eeprom_buffer_data, eeprom_pointer, eeprom_buffer_size);
|
|
}
|
|
else {
|
|
eepromSimuWriteBlock(eeprom_buffer_data, eeprom_pointer, eeprom_buffer_size);
|
|
}
|
|
eepromTransferComplete = 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8_t eepromReadStatus()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
uint8_t eepromIsTransferComplete()
|
|
{
|
|
return eepromTransferComplete;
|
|
}
|
|
|
|
void eepromTransmitData(uint32_t address, uint8_t * buffer, uint32_t size, bool read)
|
|
{
|
|
eeprom_pointer = address;
|
|
eeprom_buffer_data = buffer;
|
|
eeprom_buffer_size = size;
|
|
eeprom_read_operation = read;
|
|
eepromTransferComplete = 0;
|
|
sem_post(eeprom_write_sem);
|
|
}
|
|
|
|
#if defined(EEPROM_BLOCK_SIZE)
|
|
void eepromBlockErase(uint32_t address)
|
|
{
|
|
static uint8_t erasedBlock[EEPROM_BLOCK_SIZE]; // can't be on the stack!
|
|
memset(erasedBlock, 0xff, sizeof(erasedBlock));
|
|
eepromTransmitData(address, erasedBlock, EEPROM_BLOCK_SIZE, false);
|
|
}
|
|
#endif
|
|
|
|
void eepromStartRead(uint8_t * buffer, size_t address, size_t size)
|
|
{
|
|
assert(size);
|
|
eepromTransmitData(address, buffer, size, true);
|
|
}
|
|
|
|
void eepromStartWrite(uint8_t * buffer, size_t address, size_t size)
|
|
{
|
|
assert(size);
|
|
eepromTransmitData(address, buffer, size, false);
|
|
}
|
|
|
|
void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size)
|
|
{
|
|
eepromStartWrite(buffer, address, size);
|
|
|
|
while (!eepromIsTransferComplete()) {
|
|
#if defined(GTESTS)
|
|
sleep(0/*ms*/);
|
|
#else
|
|
sleep(1/*ms*/);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
pthread_t eeprom_thread_pid;
|
|
|
|
void StartEepromThread(const char * filename)
|
|
{
|
|
eepromFile = filename;
|
|
if (eepromFile) {
|
|
fp = fopen(eepromFile, "rb+");
|
|
if (!fp)
|
|
fp = fopen(eepromFile, "wb+");
|
|
if (!fp)
|
|
perror("error in fopen");
|
|
}
|
|
|
|
#ifdef __APPLE__
|
|
eeprom_write_sem = sem_open("eepromsem", O_CREAT, S_IRUSR | S_IWUSR, 0);
|
|
#else
|
|
eeprom_write_sem = (sem_t *)malloc(sizeof(sem_t));
|
|
sem_init(eeprom_write_sem, 0, 0);
|
|
#endif
|
|
|
|
if (!pthread_create(&eeprom_thread_pid, NULL, &eeprom_thread_function, NULL))
|
|
eeprom_thread_running = true;
|
|
else
|
|
perror("Could not create eeprom thread.");
|
|
}
|
|
|
|
void StopEepromThread()
|
|
{
|
|
eeprom_thread_running = false;
|
|
sem_post(eeprom_write_sem);
|
|
pthread_join(eeprom_thread_pid, NULL);
|
|
|
|
#ifdef __APPLE__
|
|
sem_close(eeprom_write_sem);
|
|
#else
|
|
sem_destroy(eeprom_write_sem);
|
|
free(eeprom_write_sem);
|
|
#endif
|
|
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|