//----------------------------------------------------------------------------
///
///
///
//----------------------------------------------------------------------------


#include <fosh/command.h>
#include <stdio.h>
#include <time.h>       // time.h, localtime, strftime
#include <string.h>     // strncpy
#include <sys/time.h>   // settimeofday
#include <stdlib.h>      // atoi
#include <lepto/lepto.h>   // address_t

#ifdef STM32
   //#include <arena/platform.h>
   #include <biwak/rtc.hpp>
   #include <biwak/flash.h>
#else
   #include <sys/types.h>      // uint64_t
#endif

class CCommandMem: public CCommand
{
   public:
      CCommandMem(const char *_name)
         :CCommand( _name, "   mem: information about memory\n" )
      {}
      virtual int exec(int argc, const char *argv[]) const;
      virtual void printHelp() const;
};


extern char end asm("end") __attribute__((unused)); // And of application flash; heap_low will follow
extern char absolute_start asm("absolute_start") __attribute__((unused));
extern char _estack asm("_estack") __attribute__((unused));
extern char heap_low asm("heap_low") __attribute__((unused));
extern char heap_top asm("heap_top") __attribute__((unused));
extern char stack_top asm("stack_top") __attribute__((unused));

extern char _sidata asm("_sidata") __attribute__((unused));
extern char _sdata asm("_sdata") __attribute__((unused));
extern char _edata asm("_edata") __attribute__((unused));
extern char _sbss asm("_sbss") __attribute__((unused));
extern char _ebss asm("_ebss") __attribute__((unused));
extern char *heap_end;

extern char _eflash asm("_eflash") __attribute__((unused));
extern char _sflash asm("_sflash") __attribute__((unused));
extern char _start_user_flash asm("_start_user_flash") __attribute__((unused));


int CCommandMem::exec(int argc, const char *argv[]) const /* virtual */
{
   register char * stack_ptr asm ("sp");
   printf("Data start:     %p\n", &_sdata);

   // Linux app has no _edata
   #if defined ( STM32 )
      printf("Data end:       %p\n", &_edata);
   #endif

   //printf("Flash start:0x%08X\n", (int)&_sflash);
   //printf("start user ram:  0x%08X\n", (int)&_user_heap_stack);

   printf("Heap low:       %p\n", &heap_low);
   printf("Heap top:       %p\n", &heap_top);
   #if defined ( STM32 )
   printf("Heap cr. end:   %p\n", heap_end);
   #endif
   //printf("Heap max size:  0x%08X\n", (address_t)&heap_top - (address_t)&heap_low );
   //printf("Heap avail.:    0x%08X\n", (address_t)&heap_top - (address_t)&heap_end );
   printf("Stack Ptr:      %p\n", (void *)stack_ptr);
   printf("\n");
   printf("Flash start:    %p\n", &_sflash);
   printf("Flash end:      %p\n", &_eflash);
   printf("User flash:     %p\n", &_start_user_flash);
   /*
   if(pf.flash)
   {
      printf("Page Size:      %p\n", (void * )pf.flash[0]->pageSize());
   }
   */
   return( 0 );
}


const CCommand *createInstance_mem()
{
   return( new CCommandMem("mem") );
}


STTERM_COMMAND(mem);


//---fin----------------------------------------------------------------------
