|
NetBurner 3.5.7
PDF Version |
This document provides the memory map and locations of reference materials for those who wish to add additional hardware to their NetBurner device.
The SOMRT1061 uses the NXP i.MX RT1061 microprocessor. The reference manual and datasheet provide in-depth information on the microprocessor, including register settings, bus configuration and timing information. It is located in the <nburn_install>\docs\NXP directory of your NetBurner installation.
Definitions for the MIMXRT1061 can be found at arch/cortex-m7/cpu/MIMXRT10xx/include/MIMXRT1061.h
The datasheet for the SOMRT1061 module includes information on connectors, signal names, and operational parameters. It is located on the SOMRT1061 product page under Documents and Downloads.
An Excel spreadsheet of pin assignments is also available under the same Datasheet link.
Finally, NetBurner has created an interactive Pin Configurator tool which is available online as well as in your NNDK installation under <nburn_install>\docs\NetBurner\Platform\PinConfigurator
You may also find pinconstant.h to be a useful reference.
The DEV-SOMRT1061 development board schematic is located in the <nburn_install>\docs\NetBurner\platform\Schematics directory. This schematic can be used for design ideas in your own hardware implementation for power, RS-232, RS-485, and SD Flash card implementation.
The SOMRT1061 uses the NXP i.MX RT1061 microcontroller. The reference manual and datasheet provide in-depth information on the processor, including register settings, bus configuration and timing information. The reference manual is located in the <nburn_install>\docs\NXP directory of your NetBurner installation.
The SOMRT1061 uses an 8 MB SPI NOR flash (Winbond W25Q64JVXGIM) connected via the LPSPI3 peripheral. The flash is managed by EFFS-STD (Embedded Flash File System - Standard), which provides a structured file system with FAT-like directory and file operations.
Unlike older NetBurner platforms that use fixed compile-time memory regions (COMPCODEFLAGS) to partition flash between application firmware and file storage, the SOMRT1061 uses a dynamic partition table stored at sector 0 of the SPI flash. This partition table defines how the flash is divided, and all persistent data — including the application firmware image — is stored as files within the EFFS file system.
| File | Purpose |
|---|---|
arch/cortex-m7/cpu/MIMXRT10xx/include/effs_pt.h | Partition table and EFFS config struct definitions |
arch/cortex-m7/cpu/MIMXRT10xx/source/EffsStd.cpp | Flash driver implementation and mount_std_fs() |
arch/cortex-m7/cpu/MIMXRT10xx/source/nbpart.cpp | Partition table operations and Hamming ECC |
platform/SOMRT1061/source/hal_storage.cpp | HAL storage layer (config, certs, app, user params) |
platform/SOMRT1061/include/hal_platdefs.h | Maximum storage size constants |
nbrtos/include/file/fsf.h | EFFS-STD API macros |
nbrtos/include/file/fsm.h | FS_SPACE struct definition |
The 8 MB SPI flash has the following logical layout:
By default, a single EFFS partition spans from sector 1 to the end of flash, and is marked as bootable. The partition table sector (sector 0) is reserved and not part of any partition.
Important**: On the SOMRT1061, the application firmware image is stored as a versioned file (A:/sys/files/app.xNN) inside the EFFS file system. There is no separate raw flash region for the application image as on older platforms.
The partition table is defined in effs_pt.h and occupies the first sector of SPI flash.
Partition types**: PARTITION_TYPE_EFFS (0x25) is the only type used by the NetBurner system. Other types (FAT12, FAT16, NTFS, Linux) are defined but reserved for future use.
MSB encoding**: When sectorCount or firstSector values exceed 2^23, the MSB is set and the value is encoded as (2^(exponent+4)) * mantissa, enabling representation of very large flash devices.
The partition table is protected by Hamming code checksums. Each 31-byte block of the table has an 8-bit checksum stored in the csums[] array. On read, validatePartitionTable() uses hamming_validateOrFix() to detect and correct single-bit errors. This protects against flash bit-rot and ensures the partition table remains valid over the device lifetime.
All functions are in nbpart.cpp:
| Function | Purpose |
|---|---|
getPartitionTable(pt) | Read partition table from flash address 0 and validate |
createPartitionTable(pt, sectorLenExp, totalSectors) | Initialize an empty partition table |
createPartitionEntry(pt, pte, startSector, sectorCount, type, bootable) | Create a new partition entry |
createPartition(pt, pte) | Insert a partition entry (overlap-checked, sorted) |
deletePartition(pt, partIdx) | Remove a partition entry |
writePartitionTable(pt) | Compute checksums and write to flash |
showPartitionTable(pt) | Debug print of partition table contents |
Each EFFS partition stores its configuration in an Effs_Cfg struct at the first sector of the partition.
Default configuration** (created by createDefaultFilesystem() in EffsStd.cpp):
| Parameter | Value | Meaning |
|---|---|---|
sSizeExp | 10 | 1 KB sectors |
blSizeExp | 15 | 32 KB blocks (erase unit) |
dSizeExp | 15 | 32 KB for FAT + directory |
cacheSizeExp | 10 | 1 KB write cache |
maxblock | (calculated) | partitionSize / 32KB |
The maxblock value determines how many 32 KB blocks are available for file data storage within the partition. For the default single-partition configuration on 8 MB flash, this is approximately 244 blocks (after subtracting the partition table sector and EFFS metadata blocks).
The EFFS file system is initialized automatically during the boot process, before UserMain() is called. Applications do not need to call any initialization functions.
After mounting, hal_bootPt is set to the index of the first bootable partition, and fs_chdrive(hal_bootPt) sets it as the default drive.
Each partition is backed by a set of four flash operation callbacks, registered in fs_phy_AF() (EffsStd.cpp:297):
ReadFlash(data, block, blockrel, datalen) — Read data from a flash blockWriteFlash(data, block, relsector, size, relpos) — Write data to flash (with bounds checking)EraseFlash(block) — Erase a 32 KB blockVerifyFlash(data, block, relsector, size, relpos) — Verify written data matchesAll operations translate logical block/sector addresses to physical flash addresses using:
Bounds checking ensures no operation can read or write outside the partition's address range.
Since EFFS requires separate callback function pointers per drive, EffsStd.cpp generates 8 sets of wrapper functions (EraseFlash_0 through EraseFlash_7, etc.) that forward to a common implementation with the drive number as a parameter.
The HAL storage layer (hal_storage.cpp) manages four categories of system data as versioned files in the A:/sys/files/ directory:
| Storage Area | File Pattern | Max Size | Purpose |
|---|---|---|---|
HalStore_Config | config.xNN | 128 KB | JSON system configuration |
HalStore_Cert | certs.xNN | 2 MB | SSL/TLS certificate store |
HalStore_UserParams | usrparam.xNN | 16 KB | Application user parameters |
HalStore_App | app.xNN | 32 MB | Firmware application image |
Each file has a .xNN suffix where NN is a two-digit hex sequence number (00-FF). When a new version is saved:
HalStorage_FindLastVer() scans for the highest existing sequence numberlastVer + 127 (opposite side of the circular sequence)This versioning scheme provides safe atomic updates: if a write is interrupted (e.g., power loss), the previous version remains intact and will be loaded on the next boot.
Previous file versions are cleaned up by FlashErasePrevVersions(), which runs in the idle task (OSTaskIdle) approximately 2 seconds after boot. It keeps only the 2 most recent versions of each file type and deletes older ones.
| Function | Purpose |
|---|---|
HalStorage_Save(area, pData, len, offset) | Write a complete file (creates new version) |
HalStorage_SavePartial(area, pData, len, offset) | Write partial data at an offset |
HalStorage_Read(area, pData, len, offset) | Read from the latest version |
HalStorage_Prepare(area, len, offset) | Open file for writing (with space management) |
HalStorage_Finalize(area) | Close an open file handle |
HalStorage_Erase(area, len, offset) | Delete all versions of a file |
HalStorage_GetAllocated(area) | Get total usable space (free + used) |
HalStorage_RemainingSpace(area) | Get free space on the boot partition |
HalStorage_GetMaxAllocation(area) | Get per-area maximum size limit |
Use fs_getfreespace() to get current space statistics for any mounted drive:
The FS_SPACE struct is defined in nbrtos/include/file/fsm.h:
Maximum storage sizes per area are defined in platform/SOMRT1061/include/hal_platdefs.h:
| Constant | Value | Description |
|---|---|---|
PLAT_STORAGE_MAX_CONFIG_SIZE | 0x20000 (128 KB) | Maximum config file size |
PLAT_STORAGE_MAX_USERPARAMS_SIZE | 0x4000 (16 KB) | Maximum user params size |
PLAT_STORAGE_MAX_CERTSTORE_SIZE | 0x200000 (2 MB) | Maximum certificate store size |
PLAT_STORAGE_MAX_APP_SIZE | 0x2000000 (32 MB) | Maximum application image size |
PLAT_STORAGE_MAX_FILESYS_SIZE | 0x1F00000 (31 MB) | Maximum file system size |
Note: The MAX_APP_SIZE and MAX_FILESYS_SIZE values are logical maximums. The physical flash is 8 MB, so actual usable space is limited by the flash capacity minus partition table overhead and EFFS metadata (~64 KB).
| Region | Size |
|---|---|
| Partition table (sector 0) | 4 KB |
| Effs_Cfg (partition sector 0) | 4 KB |
| EFFS metadata (FAT + directory) | ~64 KB |
| Usable file storage | **~7.9 MB** |
The usable storage is shared between all files: system files (config, certs, app image, user params) and any application-created files.
Applications and the system share the same EFFS file system on the boot partition. There is no need to create a separate file system for application data.
Directory layout on the boot partition:**
A:/sys/files/ directly. This directory is managed exclusively by the HAL storage layer. Use the SaveUserParameters() / GetUserParameters() API for persistent application settings, or the HAL storage API for other areas.Use standard EFFS-STD API for application files. Applications can freely create directories and files anywhere outside of A:/sys/:
mount_std_fs() runs during HardwareInit(), before UserMain() is called. Applications do not need to call EffsStart() or any other initialization function.FS_MULTI structures, and the fsm_* wrapper functions (which the fs_* macros resolve to) handle per-task locking internally. Multiple tasks can safely perform file operations concurrently.Check available space before large writes. Since all data shares the same partition, a large application file could consume space needed for firmware updates or config saves. Use fs_getfreespace() to check:
Applications can create additional EFFS partitions on the SPI flash, but this is not required for most use cases. The single default partition is sufficient for the vast majority of applications.
The examples/PlatformSpecific/SOMRT1061/EFFS_MultiPart/ example demonstrates the full process:
BuildFileTrees())fs_unmountdrive() and free allocated memorysectorCount and create a new PartitionEntry for the second partitionAppFlash.EraseChip()writePartitionTable()createDefaultFilesystem()fs_mountdrive() and format with fs_format()After creation, the second partition is accessed as a separate drive:
Warning**: Creating a second partition requires erasing the entire flash chip. All existing data must be backed up to RAM first and restored afterward. This operation is destructive and should only be done during initial device provisioning or with careful data migration.
The SOMRT1061's partition-table approach is fundamentally different from the fixed-region approach used by older NetBurner platforms (MOD5441X, NANO54415, SB800EX, MODM7AE70, SBE70LC).
| Feature | SOMRT1061 | MOD5441X / NANO54415 & SB800EX |
|---|---|---|
| Flash Type | SPI NOR (8 MB) | Parallel NOR (32 MB) / SPI NOR (8 MB) |
| Partitioning | Dynamic partition table at sector 0 | Fixed COMPCODEFLAGS compile-time regions |
| App Image Storage | Stored as file in EFFS (A:/sys/files/app.xNN) | Dedicated raw flash region |
| Config/Certs | Versioned files in EFFS (*.xNN) | Dedicated flash sectors or EFFS files |
| Block Size | 32 KB (configurable per partition) | 128 KB (MOD5441X), 4 KB (NANO54415 & SB800EX) |
| Sector Size | 1 KB (configurable per partition) | 1 KB |
| Max Partitions | 8 | 1 |
| Error Protection | Hamming codes on partition table and Effs_Cfg | None |
| FS Initialization | Automatic in HardwareInit() (before UserMain()) | Application must call EffsStart() |
| FS Source Files | Built into platform library | Copied from examples/_common/EFFS/STD/ |
EffsStart() call needed. On SOMRT1061, the file system is mounted before UserMain() runs. On older platforms, applications must explicitly call EffsStart("TaskName") to initialize and mount the file system.examples/_common/EFFS/STD/ (e.g., effsStdFlashDrv.cpp, fs_main.cpp, effs_std.cpp). On SOMRT1061, all flash driver and mounting code is part of the platform library.COMPCODEFLAGS. Older platforms use COMPCODEFLAGS in the makefile to define the boundary between application code and file system regions. On SOMRT1061, this mechanism is not used — the partition table handles all flash region management.PLAT_HAS_FILESYSTEM flag is always set.At power-up or reset, the application is decompressed from Flash memory to PSRAM, verified by checksum, and execution begins. If the checksum fails or the application crashes, the device will reboot to the Configuration Server to facilitate a recovery by downloading a new application.
If the application causes an issue in which continuous traps occur, or the state of the system is such the Configuration Server cannot run, a recovery hardware jumper procedure can be used to reset the device.
There can be a maximum of 7 serial port configured on the device. Note that each signal pin on the microprocessor can be configured for up to 5 different functions, so to achieve the maximum number of serial ports some peripheral functions will be unavailable.
Please refer to the Open All Serial Ports example for hardware and software port mapping: Open All UARTs. Port number mapping for software API calls is defined in SOMRT1061/include/serial_platdefs.h in the <nburn_install>\platform folder.
Routing signals for the SOMRT1061 can be broken down into a hierarchy of priorities and requirements. These are based around signal integrity of various flavors and application needs.
The following signals are considered 'routing critical', meaning that if you intend to use them, they must be routed to spec:
In the case of the ENET signals, they must be routed as "100 ohm differential" (and ideally a nominal 50 ohm single ended impedance) signals within the TX or RX pairs. The USB data signals must be routed as "90 ohm differential" (and ideally 45 ohm single ended). While the signals are differential, care should be taken to not route high power signals in a manner that would strongly couple to these signals and interfere with the them. Beyond this, avoid vias if possible for these, as they will introduce impedance discontinuities (i.e. reflect some power and introduce additional dispersion), and length match within the pairs as close as possible (ideally < 100mil). Obviously, the connected cables will introduce their own variability with the length matching, but the closer your routing, the better the noise immunity at install.
Next, are the 'performance critical' signals, where the feature would still work, but to differring levels of performance based on routing. These are:
The SD_B0 and AD_B1 signals are routed on the bottom layer of the module, and thus will be directly over the top layer of your carrier PCB, with no additional copper between them. In the case of the SD_B0 signals, routing highspeed signals across the southwest corner of the module has potential to introduce issues when operating at high speeds with memory cards. If high speed signals must be routed under them without an isolating plane layer, they should be routed in an east/west direction relative to the module.
In the case of the AD_B1 signals, the concern is primarily regarding additional introduced noise into the analog measurements. While using the onboard ADC of a processor on a module is never going to yield the precision and accuracy of a dedicated, precision, ADC on a thermally and mechanically isolated portion of the PCB with it's own dedicated low noise power supply, it's still possible to have it perform better or worse depending on external coupling. Therefore, the AD_B1 signals that are used for analog sampling should be isolated as much as possible from high power sources of noise, and those signals affected by/carrying high power noise should not be routed under the Southwest portion of the module.
Finally, the EMC signals contain the External Databus, which if used, will be again sensitive to noise, and thus high power noise sources should be kept away from these when serving as a databus. Of additional note is that the signals involved with the databus have been length tuned for placement of timing sensitive devices towards the northwest of the module, such that the signals exiting nearer to pin 1 are longer on the SOM than those exiting further away. It should be noted that some of the databus signals are routed on the bottom layer of the module and previous comments about signal integrity apply.
Name | Length (mil) EMC_13 | 1027.567 EMC_14 | 996.629 EMC_7 | 839.663 EMC_6 | 826.247 EMC_5 | 820.025 EMC_26 | 810.646 EMC_35 | 810.511 EMC_9 | 809.71 EMC_23 | 809.706 EMC_1 | 808.191 EMC_10 | 806.277 EMC_0 | 805.844 EMC_4 | 803.84 EMC_2 | 801.904 EMC_24 | 800.075 EMC_3 | 799.877 EMC_8 | 799.083 EMC_11 | 796.457 EMC_41 | 791.704 EMC_25 | 790.139 EMC_40 | 778.25 EMC_36 | 773.609 EMC_17 | 766.04 EMC_12 | 762.951 EMC_31 | 755.219 EMC_39 | 750.712 EMC_29 | 750.198 EMC_33 | 746.296 EMC_18 | 744.48 EMC_16 | 743.689 EMC_34 | 742.535 EMC_30 | 742.226 EMC_27 | 735.4 EMC_37 | 716.469 EMC_28 | 709.312 EMC_15 | 705.513 EMC_38 | 702.911 EMC_19 | 690.108 EMC_20 | 684.383 EMC_32 | 683.317
So, all that said, can you route signals directly underneath the SOMRT1061? Absolutely! But care should be taken when doing so. East/west is generally better than north/south, as most of the signals on the bottom layer of the SOMRT1061 are running in a north/south direction given the location of the processor. They are referenced to the ground plane present on the module, which does introduce some fun when looking at the return path and the ground pins, but basic GPIO isn't really a concern.