Subdirectory provided by Embedded Artists
Dependencies: DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src
Dependents: lpc4088_displaymodule_hello_world_Sept_2018
Fork of DMSupport by
Revision 34:fc366bab393f, committed 2015-03-09
- Comitter:
- embeddedartists
- Date:
- Mon Mar 09 11:15:56 2015 +0100
- Parent:
- 33:8a0a99d54bf8
- Child:
- 35:d45a38606a7f
- Commit message:
- - Added size guards in InternalEEPROM
- Added documentation in missing classes
- Added option to redirect RtosLog to USBSerial (a USB Device Serial port)
- Moved the mbed_mac_address function from the SDK to the BIOS
Changed in this revision
--- a/Bios/BiosLoader.cpp Thu Feb 19 14:41:14 2015 +0100 +++ b/Bios/BiosLoader.cpp Mon Mar 09 11:15:56 2015 +0100 @@ -57,7 +57,7 @@ #define SUPPORTED_BIOS_MASK 0xff0000 // only look at the Major component #define SUPPORTED_VERSION(__ver) (((__ver)&SUPPORTED_BIOS_MASK) == SUPPORTED_BIOS_VER) -#define MAC_IN_SDK +//#define MAC_IN_SDK /****************************************************************************** * Local variables
--- a/DMBoard.cpp Thu Feb 19 14:41:14 2015 +0100 +++ b/DMBoard.cpp Mon Mar 09 11:15:56 2015 +0100 @@ -35,6 +35,10 @@ #if defined(DM_BOARD_USE_USB_DEVICE) && defined(DM_BOARD_USE_USB_HOST) #error The hardware supports either USB Device or USB Host - not both at the same time #endif + +#if defined(DM_BOARD_USE_USBSERIAL_IN_RTOSLOG) && !defined(DM_BOARD_USE_USB_DEVICE) + #error Cannot use USBSerial in RtosLog without DM_BOARD_USE_USB_DEVICE +#endif #if defined(DM_BOARD_USE_TOUCH) && !defined(DM_BOARD_USE_DISPLAY) #error Cannot have touch controller without a display!
--- a/FileSystems/RAMFileSystem.cpp Thu Feb 19 14:41:14 2015 +0100 +++ b/FileSystems/RAMFileSystem.cpp Mon Mar 09 11:15:56 2015 +0100 @@ -15,9 +15,11 @@ */ #include "RAMFileSystem.h" -#include "mbed_debug.h" +#include "DMBoard.h" + -#define RAMFS_DBG 0 +#define RAMFS_DBG(...) +//#define RAMFS_DBG(...) DMBoard::instance().logger()->isr_printf(__VA_ARGS__) #define SECTOR_SIZE 512 @@ -29,13 +31,13 @@ } int RAMFileSystem::disk_initialize() { - debug_if(RAMFS_DBG, "init RAM fs\n"); + RAMFS_DBG("init RAM fs\n"); status = 0; //OK return status; } int RAMFileSystem::disk_write(const uint8_t *buffer, uint64_t sector, uint8_t count) { - debug_if(RAMFS_DBG, "write to sector(s) %llu..%llu\n", sector, sector+count); + RAMFS_DBG("write to sector(s) %llu..%llu\n", sector, sector+count); if ((sector+count-1) >= disk_sectors()) { return 1; } @@ -45,7 +47,7 @@ } int RAMFileSystem::disk_read(uint8_t *buffer, uint64_t sector, uint8_t count) { - debug_if(RAMFS_DBG, "read from sector(s) %llu..%llu\n", sector, sector+count); + RAMFS_DBG("read from sector(s) %llu..%llu\n", sector, sector+count); if ((sector+count-1) >= disk_sectors()) { return 1; } @@ -55,14 +57,14 @@ } int RAMFileSystem::disk_status() { - debug_if(RAMFS_DBG, "disk status %d\n", status); + RAMFS_DBG("disk status %d\n", status); return status; } int RAMFileSystem::disk_sync() { return 0; } uint64_t RAMFileSystem::disk_sectors() { - debug_if(RAMFS_DBG, "returning fs has %u sectors\n", memSize/SECTOR_SIZE); + RAMFS_DBG("returning fs has %u sectors\n", memSize/SECTOR_SIZE); return memSize/SECTOR_SIZE; }
--- a/Memory/InternalEEPROM.cpp Thu Feb 19 14:41:14 2015 +0100 +++ b/Memory/InternalEEPROM.cpp Mon Mar 09 11:15:56 2015 +0100 @@ -152,6 +152,14 @@ uint32_t pageAddr = addr/EEPROM_PAGE_SIZE; uint32_t readOffset = (addr & (EEPROM_PAGE_SIZE - 1)); uint32_t readSize = EEPROM_PAGE_SIZE - readOffset; + + // Prevent reading past the end of the memory + if (addr >= EEPROM_MEMORY_SIZE) { + return 0; + } + if ((size + addr) > EEPROM_MEMORY_SIZE) { + size = EEPROM_MEMORY_SIZE - addr; + } powerUp(); @@ -181,6 +189,14 @@ uint32_t writeOffset = (addr & (EEPROM_PAGE_SIZE - 1)); uint32_t writeSize = EEPROM_PAGE_SIZE - writeOffset; + // Prevent writing past the end of the memory + if (addr >= EEPROM_MEMORY_SIZE) { + return 0; + } + if ((size + addr) > EEPROM_MEMORY_SIZE) { + size = EEPROM_MEMORY_SIZE - addr; + } + powerUp(); // Read and store data in buffer @@ -202,17 +218,3 @@ } return numWritten; } - -//void InternalEEPROM::erasePage(uint32_t pageAddr) -//{ -// powerUp(); -// -// clearInterrupt(EEPROM_INT_ENDOFRW); -// setCmd(EEPROM_CMD_32BITS_WRITE); -// setAddr(pageAddr, 0); -// for (int i = 0; i < EEPROM_PAGE_SIZE; i+=4) { -// LPC_EEPROM->WDATA = 0; -// waitForInterrupt(EEPROM_INT_ENDOFRW); -// } -// eraseOrProgramPage(pageAddr); -//}
--- a/Memory/InternalEEPROM.h Thu Feb 19 14:41:14 2015 +0100 +++ b/Memory/InternalEEPROM.h Mon Mar 09 11:15:56 2015 +0100 @@ -42,9 +42,36 @@ */ void init(); + /** Put the internal EEPROM in a low power state + */ void powerDown(); + /** Reads size bytes from offset addr + * + * Note that this function will power up the EEPROM so it is + * recommended to call powerDown() when finished reading. + * + * @param addr the offset to read from + * @param data buffer to store the read data in + * @param size number of bytes to read + * + * @returns + * The number of bytes read + */ int read(uint32_t addr, uint8_t* data, uint32_t size); + + /** Writes size bytes to offset addr + * + * Note that this function will power up the EEPROM so it is + * recommended to call powerDown() when finished writing. + * + * @param addr the offset to write to + * @param data the data to write + * @param size number of bytes to write + * + * @returns + * The number of bytes written + */ int write(uint32_t addr, const uint8_t* data, uint32_t size); /** Returns the size (in bytes) of the internal EEPROM @@ -54,20 +81,6 @@ */ uint32_t memorySize() { return EEPROM_MEMORY_SIZE; } - /** Returns the size of a page (in bytes) of the internal EEPROM - * - * @returns - * The page size in bytes - */ - //uint32_t pageSize() { return EEPROM_PAGE_SIZE; } - - /** Returns the number of pages in the internal EEPROM - * - * @returns - * The number of pages - */ - //uint32_t numPages() { return EEPROM_NUM_PAGES; } - private: bool _initialized;
--- a/Registry.h Thu Feb 19 14:41:14 2015 +0100 +++ b/Registry.h Mon Mar 09 11:15:56 2015 +0100 @@ -70,10 +70,56 @@ */ RegistryError load(); + /** Sets (or replaces if existing) the value for the key + * + * The key/value parameters are copied so it is ok to free them + * after calling this function. + * + * @param key the key to create or update + * @param val the value to store for the key + * + * @returns + * Ok on success + * An error code on failure + */ RegistryError setValue(const char* key, const char* val); + + /** Gets (if any) the the value for the key + * + * If Ok is returned then pVal will point to allocated memory + * that must be deallocated with free() by the caller. + * + * @param key the key to look for + * @param pVal will hold the value if successful + * + * @returns + * Ok on success + * NoSuchKeyError if there is no value for the key + * An error code on failure + */ RegistryError getValue(const char* key, char** pVal); + + /** Retrieves the key-value pair at the specified index + * + * If Ok is returned then pKey and pVal will point to allocated + * memory that must be deallocated with free() by the caller. + * + * @param pos the index to look for + * @param pKey will hold the key if successful + * @param pVal will hold the value if successful + * + * @returns + * Ok on success + * An error code on failure + */ RegistryError entryAt(int pos, char** pKey, char** pVal); + + /** Returns the number of key-value pairs in the registry + * + * @returns the number of key-value pairs + */ int numEntries() { return _numEntries; } + RegistryError registerListener(); /** Stores the registry in the internal EEPROM
--- a/RtosLog.cpp Thu Feb 19 14:41:14 2015 +0100 +++ b/RtosLog.cpp Mon Mar 09 11:15:56 2015 +0100 @@ -58,6 +58,12 @@ * Public Functions *****************************************************************************/ +#if defined(DM_BOARD_USE_USBSERIAL_IN_RTOSLOG) + RtosLog::RtosLog() : + _sem(NumMessages), _serial(), _thr(NULL) + { + } +#else RtosLog::RtosLog() : _sem(NumMessages), _serial(USBTX, USBRX), _thr(NULL) { @@ -68,6 +74,7 @@ _serial.baud(115200); #endif } +#endif RtosLog::~RtosLog() { @@ -124,3 +131,46 @@ return ret; } +int RtosLog::isr_printf(const char* format, ...) +{ + // The pool has no "wait for free message" so we use a Sempahore + // to keep track of the number of free messages and, if needed, + // block the caller until a message is free + int available = _sem.wait(0); + if (available <= 0) { + // no free messages and it is not good to wait in an ISR so + // we discard the message + return 0; + } + + // Allocate a null terminated message. Will always succeed due to + // the semaphore above + message_t *message = _mpool.calloc(); + + // Write the callers formatted message + std::va_list args; + va_start(args, format); + int ret = vsnprintf(message->msg, MessageLen, format, args); + va_end(args); + + // If the entire message could not fit in the preallocated buffer + // then allocate a new one and try again. + if (ret > MessageLen) { + message->ptr = (char*)malloc(ret + 1); + if (message->ptr != NULL) { + va_start(args, format); + ret = vsnprintf(message->ptr, ret + 1, format, args); + va_end(args); + } + } + + // Send message + _queue.put(message); + + // Note that the Semaphore is not released here, that is done after + // the message has been processed and released into the pool by + // logTask() + //_sem.release(); + + return ret; +}
--- a/RtosLog.h Thu Feb 19 14:41:14 2015 +0100 +++ b/RtosLog.h Mon Mar 09 11:15:56 2015 +0100 @@ -21,6 +21,10 @@ #include "rtos.h" #include "dm_board_config.h" +#if defined(DM_BOARD_USE_USBSERIAL_IN_RTOSLOG) + #include "USBSerial.h" +#endif + /** * All threads can independantly call the printf function in the RtosLog class * without risk of getting the output tangled up. @@ -53,11 +57,40 @@ RtosLog(); ~RtosLog(); - /** Starts the logger thread + /** Starts the logger thread, called from DMBoard::instance().init() */ void init(); + /** Printf that works in an RTOS + * + * This function will create a string from the specified format and + * optional extra arguments and put it into a message that the RtosLog + * thread will write to the log. + * + * Note that if the underlying queue is full then this function + * will block until an entry becomes available. This is required to + * make sure that all printf calls actually get printed. If this happens + * too often then increase the priority of the RtosLog thread or reduce + * the number of printed messages. + * + * @param format format string + * @param ... optional extra arguments + */ int printf(const char* format, ...); + + /** Printf that works in an RTOS + * + * This function will create a string from the specified format and + * optional extra arguments and put it into a message that the RtosLog + * thread will write to the log. + * + * Note that if the underlying queue is full then this function + * discards the message and returns immediately. + * + * @param format format string + * @param ... optional extra arguments + */ + int isr_printf(const char* format, ...); private: @@ -69,7 +102,11 @@ MemoryPool<message_t, NumMessages> _mpool; Queue<message_t, NumMessages> _queue; Semaphore _sem; +#if defined(DM_BOARD_USE_USBSERIAL_IN_RTOSLOG) + USBSerial _serial; +#else Serial _serial; +#endif Thread* _thr; static void logTask(void const* args);
--- a/dm_board_config.h.txt Thu Feb 19 14:41:14 2015 +0100 +++ b/dm_board_config.h.txt Mon Mar 09 11:15:56 2015 +0100 @@ -29,10 +29,10 @@ // #define DM_BOARD_USE_TOUCH // #define DM_BOARD_USE_ETHERNET #define DM_BOARD_USE_FAST_UART +// #define DM_BOARD_USE_USBSERIAL_IN_RTOSLOG // #define DM_BOARD_DISABLE_STANDARD_PRINTF // #define DM_BOARD_ENABLE_MEASSURING_PINS -// #define DM_BOARD_BIOS_DEVELOPMENT -#define DM_BOARD_USE_REGISTRY -#define DM_BOARD_USE_BUILTIN_IMAGES +// #define DM_BOARD_USE_REGISTRY +// #define DM_BOARD_USE_BUILTIN_IMAGES #endif