123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- // Common code for all backends
- #include "platform.h"
- #include "common.h"
- #include <string.h>
- #include <stdio.h>
- void cmn_platform_init(void)
- {
- }
- // ****************************************************************************
- // Internal flash support functions
- #if defined(__ESP8266__)
- // This symbol must be exported by the linker command file and must reflect the
- // TOTAL size of flash used by the eLua image (not only the code and constants,
- // but also .data and whatever else ends up in the eLua image). FS will start
- // at the next usable (aligned to a flash sector boundary) address after
- // flash_used_size.
- extern char _flash_used_end[];
- #elif defined(__ESP32__)
- /* This symbol must be exported by the linker command file and contain the
- * size of all the sections packed into the irom0_flash.bin file, in order
- * for us to find the end of used flash.
- */
- extern char _irom0_bin_min_sz[];
- #endif
- // Helper function: find the flash sector in which an address resides
- // Return the sector number, as well as the start and end address of the sector
- static uint32_t flashh_find_sector( uint32_t address, uint32_t *pstart, uint32_t *pend )
- {
- #ifdef INTERNAL_FLASH_SECTOR_SIZE
- // All the sectors in the flash have the same size, so just align the address
- uint32_t sect_id = address / INTERNAL_FLASH_SECTOR_SIZE;
- if( pstart )
- *pstart = sect_id * INTERNAL_FLASH_SECTOR_SIZE ;
- if( pend )
- *pend = ( sect_id + 1 ) * INTERNAL_FLASH_SECTOR_SIZE - 1;
- return sect_id;
- #else // #ifdef INTERNAL_FLASH_SECTOR_SIZE
- // The flash has blocks of different size
- // Their size is decribed in the INTERNAL_FLASH_SECTOR_ARRAY macro
- const uint32_t flash_sect_size[] = INTERNAL_FLASH_SECTOR_ARRAY;
- uint32_t total = 0, i = 0;
- while( ( total <= address ) && ( i < sizeof( flash_sect_size ) / sizeof( uint32_t ) ) )
- total += flash_sect_size[ i ++ ];
- if( pstart )
- *pstart = ( total - flash_sect_size[ i - 1 ] );
- if( pend )
- *pend = total - 1;
- return i - 1;
- #endif // #ifdef INTERNAL_FLASH_SECTOR_SIZE
- }
- uint32_t platform_flash_get_sector_of_address( uint32_t addr )
- {
- return flashh_find_sector( addr, NULL, NULL );
- }
- uint32_t platform_flash_get_num_sectors(void)
- {
- #ifdef INTERNAL_FLASH_SECTOR_SIZE
- return INTERNAL_FLASH_SIZE / INTERNAL_FLASH_SECTOR_SIZE;
- #else // #ifdef INTERNAL_FLASH_SECTOR_SIZE
- const uint32_t flash_sect_size[] = INTERNAL_FLASH_SECTOR_ARRAY;
- return sizeof( flash_sect_size ) / sizeof( uint32_t );
- #endif // #ifdef INTERNAL_FLASH_SECTOR_SIZE
- }
- uint32_t platform_flash_get_first_free_block_address( uint32_t *psect )
- {
- #if defined(__ESP8266__)
- // Round the total used flash size to the closest flash block address
- uint32_t start, end, sect;
- NODE_DBG("_flash_used_end:%08x\n", (uint32_t)_flash_used_end);
- if(_flash_used_end>0){ // find the used sector
- sect = flashh_find_sector( platform_flash_mapped2phys ( (uint32_t)_flash_used_end - 1), NULL, &end );
- if( psect )
- *psect = sect + 1;
- return end + 1;
- }else{
- sect = flashh_find_sector( 0, &start, NULL ); // find the first free sector
- if( psect )
- *psect = sect;
- return start;
- }
- #elif defined(__ESP32__)
- uint32_t flash_offs = IROM0_START_FLASH_ADDR + (uint32_t)_irom0_bin_min_sz;
- uint32_t sect =
- (flash_offs + INTERNAL_FLASH_SECTOR_SIZE-1)/INTERNAL_FLASH_SECTOR_SIZE;
- ++sect; /* compensate for various headers not counted in _irom0_bin_min_sz */
- if (psect)
- *psect = sect;
- return sect * INTERNAL_FLASH_SECTOR_SIZE;
- #endif
- }
- uint32_t platform_flash_write( const void *from, uint32_t toaddr, uint32_t size )
- {
- #ifndef INTERNAL_FLASH_WRITE_UNIT_SIZE
- return platform_s_flash_write( from, toaddr, size );
- #else // #ifindef INTERNAL_FLASH_WRITE_UNIT_SIZE
- uint32_t temp, rest, ssize = size;
- unsigned i;
- char tmpdata[ INTERNAL_FLASH_WRITE_UNIT_SIZE ];
- const uint8_t *pfrom = ( const uint8_t* )from;
- const uint32_t blksize = INTERNAL_FLASH_WRITE_UNIT_SIZE;
- const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1;
- // Align the start
- if( toaddr & blkmask )
- {
- rest = toaddr & blkmask;
- temp = toaddr & ~blkmask; // this is the actual aligned address
- // memcpy( tmpdata, ( const void* )temp, blksize );
- platform_s_flash_read( tmpdata, temp, blksize );
- for( i = rest; size && ( i < blksize ); i ++, size --, pfrom ++ )
- tmpdata[ i ] = *pfrom;
- platform_s_flash_write( tmpdata, temp, blksize );
- if( size == 0 )
- return ssize;
- toaddr = temp + blksize;
- }
- // The start address is now a multiple of blksize
- // Compute how many bytes we can write as multiples of blksize
- rest = size & blkmask;
- temp = size & ~blkmask;
- // Program the blocks now
- if( temp )
- {
- platform_s_flash_write( pfrom, toaddr, temp );
- toaddr += temp;
- pfrom += temp;
- }
- // And the final part of a block if needed
- if( rest )
- {
- // memcpy( tmpdata, ( const void* )toaddr, blksize );
- platform_s_flash_read( tmpdata, toaddr, blksize );
- for( i = 0; size && ( i < rest ); i ++, size --, pfrom ++ )
- tmpdata[ i ] = *pfrom;
- platform_s_flash_write( tmpdata, toaddr, blksize );
- }
- return ssize;
- #endif // #ifndef INTERNAL_FLASH_WRITE_UNIT_SIZE
- }
- uint32_t platform_flash_read( void *to, uint32_t fromaddr, uint32_t size )
- {
- #ifndef INTERNAL_FLASH_READ_UNIT_SIZE
- return platform_s_flash_read( to, fromaddr, size );
- #else // #ifindef INTERNAL_FLASH_READ_UNIT_SIZE
- uint32_t temp, rest, ssize = size;
- unsigned i;
- char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ] __attribute__ ((aligned(INTERNAL_FLASH_READ_UNIT_SIZE)));
- uint8_t *pto = ( uint8_t* )to;
- const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE;
- const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1;
- // Align the start
- if( fromaddr & blkmask )
- {
- rest = fromaddr & blkmask;
- temp = fromaddr & ~blkmask; // this is the actual aligned address
- platform_s_flash_read( tmpdata, temp, blksize );
- for( i = rest; size && ( i < blksize ); i ++, size --, pto ++ )
- *pto = tmpdata[ i ];
- if( size == 0 )
- return ssize;
- fromaddr = temp + blksize;
- }
- // The start address is now a multiple of blksize
- // Compute how many bytes we can read as multiples of blksize
- rest = size & blkmask;
- temp = size & ~blkmask;
- // Program the blocks now
- if( temp )
- {
- platform_s_flash_read( pto, fromaddr, temp );
- fromaddr += temp;
- pto += temp;
- }
- // And the final part of a block if needed
- if( rest )
- {
- platform_s_flash_read( tmpdata, fromaddr, blksize );
- for( i = 0; size && ( i < rest ); i ++, size --, pto ++ )
- *pto = tmpdata[ i ];
- }
- return ssize;
- #endif // #ifndef INTERNAL_FLASH_READ_UNIT_SIZE
- }
|