Platform DifferencesÂś
Understanding platform-specific differences and how to write portable code across Nexus supported platforms.
OverviewÂś
While Nexus provides a unified API across platforms, understanding platform differences helps write efficient and portable code.
Supported Platforms:
Native (Windows/Linux/macOS)
STM32F4 (Cortex-M4)
STM32H7 (Cortex-M7)
GD32 (RISC-V)
ESP32 (Xtensa LX6)
nRF52 (Cortex-M4F)
Platform ComparisonÂś
Hardware CapabilitiesÂś
Feature |
Native |
STM32F4 |
STM32H7 |
GD32 |
ESP32 |
|---|---|---|---|---|---|
CPU |
x86/ARM64 |
M4 |
M7 |
RISC-V |
LX6 |
Frequency |
Variable |
168 MHz |
480 MHz |
108 MHz |
240 MHz |
Flash |
N/A |
1 MB |
2 MB |
128 KB |
4 MB |
RAM |
GB |
192 KB |
1 MB |
32 KB |
520 KB |
FPU |
Yes |
Yes |
Yes |
No |
Yes |
DMA |
N/A |
Yes |
Yes |
Yes |
Yes |
Peripheral SupportÂś
Peripheral |
Native |
STM32F4 |
STM32H7 |
GD32 |
ESP32 |
|---|---|---|---|---|---|
GPIO |
â |
â |
â |
â |
â |
UART |
â |
â |
â |
â |
â |
SPI |
â |
â |
â |
â |
â |
I2C |
â |
â |
â |
â |
â |
ADC |
â |
â |
â |
â |
â |
PWM |
â |
â |
â |
â |
â |
CAN |
â |
â |
â |
â |
â |
Ethernet |
â |
â |
â |
â |
â |
WiFi |
â |
â |
â |
â |
â |
Bluetooth |
â |
â |
â |
â |
â |
Writing Portable CodeÂś
Platform DetectionÂś
Compile-Time Detection:
#include "nexus_config.h"
#if defined(CONFIG_PLATFORM_NATIVE)
/* Native platform code */
#elif defined(CONFIG_PLATFORM_STM32F4)
/* STM32F4 code */
#elif defined(CONFIG_PLATFORM_STM32H7)
/* STM32H7 code */
#elif defined(CONFIG_PLATFORM_GD32)
/* GD32 code */
#elif defined(CONFIG_PLATFORM_ESP32)
/* ESP32 code */
#endif
Runtime Detection:
const char* get_platform_name(void)
{
#if defined(CONFIG_PLATFORM_NATIVE)
return "Native";
#elif defined(CONFIG_PLATFORM_STM32F4)
return "STM32F4";
#elif defined(CONFIG_PLATFORM_STM32H7)
return "STM32H7";
#elif defined(CONFIG_PLATFORM_GD32)
return "GD32";
#elif defined(CONFIG_PLATFORM_ESP32)
return "ESP32";
#else
return "Unknown";
#endif
}
Abstraction PatternsÂś
Use HAL Abstractions:
/* Good: Portable code using HAL */
void blink_led(void)
{
nx_gpio_write_t* led = nx_factory_gpio_write('D', 12);
if (led) {
led->toggle(led);
nx_factory_gpio_release((nx_gpio_t*)led);
}
}
/* Bad: Platform-specific code */
void blink_led_bad(void)
{
#ifdef CONFIG_PLATFORM_STM32F4
GPIOD->ODR ^= (1 << 12);
#elif defined(CONFIG_PLATFORM_ESP32)
gpio_set_level(GPIO_NUM_12, !gpio_get_level(GPIO_NUM_12));
#endif
}
Platform-Specific Optimizations:
void fast_memcpy(void* dest, const void* src, size_t len)
{
#if defined(CONFIG_PLATFORM_STM32H7)
/* Use DMA for large transfers on STM32H7 */
if (len > 1024) {
dma_memcpy(dest, src, len);
return;
}
#endif
/* Fallback to standard memcpy */
memcpy(dest, src, len);
}
Platform-Specific FeaturesÂś
Native PlatformÂś
Simulation Features:
#ifdef CONFIG_PLATFORM_NATIVE
/* File system access */
#include <stdio.h>
void save_config(const char* filename)
{
FILE* f = fopen(filename, "w");
if (f) {
fprintf(f, "config_value=42\n");
fclose(f);
}
}
/* Network simulation */
#include <sys/socket.h>
int connect_to_server(const char* host, int port)
{
/* Standard socket API */
int sock = socket(AF_INET, SOCK_STREAM, 0);
/* ... */
return sock;
}
#endif
STM32 PlatformsÂś
STM32-Specific Features:
#if defined(CONFIG_PLATFORM_STM32F4) || defined(CONFIG_PLATFORM_STM32H7)
/* Access unique device ID */
uint32_t get_device_id(void)
{
return *(uint32_t*)0x1FFF7A10;
}
/* Use hardware CRC */
uint32_t calculate_crc32(const uint8_t* data, size_t len)
{
__HAL_RCC_CRC_CLK_ENABLE();
CRC->CR = CRC_CR_RESET;
for (size_t i = 0; i < len / 4; i++) {
CRC->DR = ((uint32_t*)data)[i];
}
return CRC->DR;
}
#endif
ESP32 PlatformÂś
ESP32-Specific Features:
#ifdef CONFIG_PLATFORM_ESP32
/* WiFi functionality */
#include "esp_wifi.h"
void connect_wifi(const char* ssid, const char* password)
{
wifi_config_t wifi_config = {
.sta = {
.ssid = "",
.password = "",
},
};
strcpy((char*)wifi_config.sta.ssid, ssid);
strcpy((char*)wifi_config.sta.password, password);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
esp_wifi_connect();
}
/* Bluetooth functionality */
#include "esp_bt.h"
void init_bluetooth(void)
{
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);
}
#endif
Performance ConsiderationsÂś
CPU PerformanceÂś
Relative Performance:
/* Benchmark results (relative to Native = 1.0) */
Platform | Integer | Float | Memory
------------|---------|-------|--------
Native | 1.00 | 1.00 | 1.00
STM32H7 | 0.15 | 0.20 | 0.10
STM32F4 | 0.08 | 0.10 | 0.08
ESP32 | 0.12 | 0.15 | 0.12
GD32 | 0.06 | N/A | 0.05
Optimization Strategies:
/* Adjust algorithm based on platform */
void process_data(const uint8_t* data, size_t len)
{
#ifdef CONFIG_PLATFORM_NATIVE
/* Use complex algorithm on powerful platform */
advanced_processing(data, len);
#else
/* Use simpler algorithm on embedded platforms */
basic_processing(data, len);
#endif
}
Memory ConstraintsÂś
Memory-Aware Code:
/* Adjust buffer sizes based on platform */
#if defined(CONFIG_PLATFORM_NATIVE)
#define BUFFER_SIZE 65536
#elif defined(CONFIG_PLATFORM_STM32H7)
#define BUFFER_SIZE 8192
#elif defined(CONFIG_PLATFORM_STM32F4)
#define BUFFER_SIZE 2048
#elif defined(CONFIG_PLATFORM_GD32)
#define BUFFER_SIZE 512
#endif
static uint8_t buffer[BUFFER_SIZE];
Dynamic Allocation:
void* allocate_buffer(size_t size)
{
#ifdef CONFIG_PLATFORM_GD32
/* Limited RAM - check carefully */
if (size > 1024) {
LOG_ERROR("Allocation too large for GD32");
return NULL;
}
#endif
return osal_malloc(size);
}
Timing and DelaysÂś
Tick ResolutionÂś
Platform Tick Rates:
/* Typical tick rates */
Platform | Tick Rate | Resolution
------------|-----------|------------
Native | 1000 Hz | 1 ms
STM32F4 | 1000 Hz | 1 ms
STM32H7 | 1000 Hz | 1 ms
ESP32 | 100 Hz | 10 ms
GD32 | 1000 Hz | 1 ms
Portable Timing:
/* Use OSAL for portable delays */
void delay_ms(uint32_t ms)
{
osal_task_delay(ms);
}
/* High-resolution timing when needed */
uint32_t get_microseconds(void)
{
#if defined(CONFIG_PLATFORM_NATIVE)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
#else
/* Use hardware timer */
return hal_timer_get_us();
#endif
}
Interrupt HandlingÂś
Interrupt PrioritiesÂś
Platform Differences:
/* STM32: 16 priority levels (0-15, lower = higher priority) */
#ifdef CONFIG_PLATFORM_STM32F4
#define IRQ_PRIORITY_HIGHEST 0
#define IRQ_PRIORITY_HIGH 4
#define IRQ_PRIORITY_NORMAL 8
#define IRQ_PRIORITY_LOW 12
#define IRQ_PRIORITY_LOWEST 15
#endif
/* ESP32: 7 priority levels (1-7, higher = higher priority) */
#ifdef CONFIG_PLATFORM_ESP32
#define IRQ_PRIORITY_HIGHEST 7
#define IRQ_PRIORITY_HIGH 5
#define IRQ_PRIORITY_NORMAL 3
#define IRQ_PRIORITY_LOW 2
#define IRQ_PRIORITY_LOWEST 1
#endif
Portable Interrupt Configuration:
void configure_interrupt(int irq_num, int priority)
{
#if defined(CONFIG_PLATFORM_STM32F4)
NVIC_SetPriority(irq_num, priority);
NVIC_EnableIRQ(irq_num);
#elif defined(CONFIG_PLATFORM_ESP32)
esp_intr_alloc(irq_num, priority, isr_handler, NULL, NULL);
#endif
}
Power ManagementÂś
Sleep ModesÂś
Platform Sleep Modes:
typedef enum {
POWER_MODE_RUN,
POWER_MODE_SLEEP,
POWER_MODE_STOP,
POWER_MODE_STANDBY,
} power_mode_t;
void enter_low_power_mode(power_mode_t mode)
{
#if defined(CONFIG_PLATFORM_STM32F4)
switch (mode) {
case POWER_MODE_SLEEP:
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
break;
case POWER_MODE_STOP:
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
break;
case POWER_MODE_STANDBY:
HAL_PWR_EnterSTANDBYMode();
break;
}
#elif defined(CONFIG_PLATFORM_ESP32)
switch (mode) {
case POWER_MODE_SLEEP:
esp_light_sleep_start();
break;
case POWER_MODE_STOP:
esp_deep_sleep_start();
break;
}
#endif
}
Testing Across PlatformsÂś
Unit TestingÂś
Platform-Specific Tests:
#ifdef CONFIG_PLATFORM_NATIVE
TEST(PlatformTest, NativeFeatures) {
/* Test native-specific features */
EXPECT_TRUE(file_system_available());
}
#endif
#ifdef CONFIG_PLATFORM_STM32F4
TEST(PlatformTest, STM32Features) {
/* Test STM32-specific features */
uint32_t device_id = get_device_id();
EXPECT_NE(device_id, 0);
}
#endif
Cross-Platform Tests:
TEST(PortableTest, GPIOOperations) {
/* Test works on all platforms */
nx_gpio_write_t* gpio = nx_factory_gpio_write('A', 0);
ASSERT_NE(gpio, nullptr);
gpio->write(gpio, 1);
EXPECT_EQ(gpio->read(gpio), 1);
nx_factory_gpio_release((nx_gpio_t*)gpio);
}
Best PracticesÂś
Use HAL Abstractions * Prefer HAL APIs over direct register access * Use factory pattern for device creation * Release resources properly
Handle Platform Differences * Use compile-time detection * Provide fallbacks * Document platform-specific code
Test on Target Hardware * Native testing is not sufficient * Test on actual hardware * Verify timing and performance
Consider Resource Constraints * Adjust buffer sizes * Optimize for memory * Profile on target
Document Platform Requirements * Specify minimum requirements * Document platform-specific features * Provide porting guide
See AlsoÂś
Platform Guides - Platform-Specific Guides
Porting Guide - Porting Guide
Performance Optimization - Performance Optimization
Best Practices - Best Practices