Simpleword Documentation

website·Indexed 29 days ago

https://simpleword.bid/

Searchable website documentation for Simpleword from https://simpleword.bid/.

Tokens
7.3K
Snippets
23
Records
44
Agent score
50%

What's inside Simpleword Documentation

  1. Implement move semantics with rvalue references

    Rvalue references (&&) bind to temporary objects (rvalues) that are about to be destroyed. They enable Move Semantics, allowing a program to 'steal' resources (like heap memory) from a temporary object instead of copying them.

    Implementation:

    • Move Constructor: Transfers ownership of resources from the source object to the new object and nulls out the source's pointers to prevent double-deletion.
    • Move Assignment Operator: Releases current resources and transfers ownership from the source.
    • std::move(): A cast that converts an lvalue to an rvalue reference, enabling the use of move constructors/assignment operators.
    class MyString {
    public:
        char* _data;
        size_t _len;
    
        // Move Constructor
        MyString(MyString&& other) noexcept 
            : _data(other._data), _len(other._len) {
            other._data = nullptr; // Prevent double-free
            other._len = 0;
        }
    
        // Move Assignment
        MyString& operator=(MyString&& other) noexcept {
            if (this != &other) {
                delete[] _data;
                _data = other._data;
                _len = other._len;
                other._data = nullptr;
                other._len = 0;
            }
            return *this;
        }
    };
    
    MyString str1 = "example";
    MyString str2 = std::move(str1); // str1's resources moved to str2
  2. Understand SPI communication fundamentals

    SPI (Serial Peripheral Interface) is a synchronous, full-duplex communication protocol. It uses a dedicated clock line (SCL) to synchronize data transfer.

    Key characteristics include:

    • Full-Duplex: Simultaneous data transmission and reception via two separate lines (MOSI and MISO).
    • Master-Slave Architecture: The Master controls the clock and selects which Slave to communicate with using Chip Select (CS) lines.
    • Wiring for Master:
      • MOSI (Master Out Slave In): Output from the master.
      • MISO (Master In Slave Out): Input to the master.
    • Slave Selection: The Master uses CS lines to enable specific slaves. Typically, a CS line is active-low (0 selects the slave, 1 deselects it), replacing the need for start/stop signals used in protocols like I2C.
  3. Understand DMA (Direct Memory Access) fundamentals

    DMA is a hardware module in microcontrollers that allows peripherals (such as ADC, DAC, USART, SPI, I2C) to transfer data directly to and from memory (SRAM, Flash) without CPU intervention. This reduces CPU load and increases data throughput and efficiency.

    Supported transmission directions include:

    • Peripheral to Memory (e.g., ADC sampling to RAM)
    • Memory to Peripheral (e.g., RAM to USART)
    • Memory to Memory (e.g., copying data between RAM regions)
  4. Compare Parallel and Serial Communication

    Parallel communication uses multiple wires to transmit data simultaneously, offering higher speeds but consuming more resources (pins) and being more susceptible to signal interference. Serial communication (e.g., UART, SPI, I2C) transmits data sequentially over a single line, which is slower but more stable and resource-efficient.
  5. Implement resource management using RAII

    RAII (Resource Acquisition Is Initialization) is a core C++ pattern where resource lifecycle is tied to object lifetime. Resources are acquired during object construction and released during destruction. This prevents memory and resource leaks. Common applications include smart pointers, std::lock_guard, and file streams (std::fstream).
  6. Extend the lifetime of temporary objects using rvalue references

    In C++, binding a temporary object (an rvalue) to an rvalue reference extends the lifetime of that temporary object until the rvalue reference itself goes out of scope.
    std::string&& rref_str = std::string("temporary");
    // The temporary object "temporary" has its lifetime extended until rref_str goes out of scope
    std::cout << rref_str << std::endl;
  7. Perform perfect forwarding in C++ templates

    Perfect forwarding allows a template function to pass an argument to another function while preserving its value category (whether it was an lvalue or an rvalue). This is achieved using forwarding references (also known as universal references) and std::forward.
    template<typename T>
    void relay(T&& arg) {
        // std::forward preserves the lvalue/rvalue nature of arg
        some_other_function(std::forward<T>(arg));
    }
  8. Choose a DMA transmission mode

    DMA controllers support different modes depending on the data flow requirements:

    • Normal Mode: The DMA stops after the specified amount of data is transferred. Best for one-time fixed-length transfers.
    • Circular Mode: The DMA automatically restarts from the beginning address after completing a transfer. Ideal for continuous data streams, such as continuous ADC sampling.
    • Double Buffer Mode: Uses two buffers so the DMA can fill one while the CPU processes the other, reducing data loss in high-real-time scenarios (supported on some MCUs).
  9. Use =delete to disable specific functions or constructors

    The = delete specifier disables a specific function, preventing it from being called. Common use cases include:

    • Preventing object copying: Delete the copy constructor and copy assignment operator.
    • Restricting object creation: Delete the default constructor to force the use of parameterized constructors.
    • Preventing unwanted type conversions: Delete constructors that take specific parameter types.
    • Implementing Singletons: Disable copy and move operations to ensure only one instance exists.
    class Test {
    public:
        // Disable move construction
        Test(const Test &&) = delete;
        
        // Example: To prevent copying in a Singleton
        // Test(const Test&) = delete;
        // Test& operator=(const Test&) = delete;
    };
  10. Synchronize I2C data transmission and reception

    To ensure data integrity and correct identification of bits (e.g., distinguishing between '111000' and '10'), I2C uses the SCL line for synchronization:

    • Data on the SDA line must be modified (changed to 0 or 1) while the SCL line is low.
    • The slave reads the data on the SDA line while the SCL line is high. The value read is the state established during the preceding low-level period of SCL.
  11. Parse JSON strings and map values to C++ types

    To convert a JSON-formatted string into a nlohmann::json object, use json::parse(). To extract specific values from a JSON object into C++ variables or class members, use the .get<T>() template method, where T is the target data type (e.g., int, float, std::string).
    #include <nlohmann/json.hpp>
    using json = nlohmann::json;
    
    struct TempHumi {
        int id;
        float temp;
        float humi;
    };
    
    void processJson(const std::string &jsonString) {
        // Parse string to JSON object
        json j = json::parse(jsonString);
    
        // Map JSON values to a C++ object
        TempHumi th;
        th.id = j["id"].get<int>();
        th.temp = j["temp"].get<float>();
        th.humi = j["humi"].get<float>();
    }
  12. Implement PWM control for STM32 using TIM2

    This implementation configures TIM2 to generate a 1KHz PWM signal on GPIOA Pin 0. It includes a set of wrapper functions to start/stop the PWM signal and adjust the duty cycle using either raw pulse values or percentages.

    Key Configuration Details:

    • Clock Source: Internal
    • Prescaler: 71 (resulting in 1MHz timer clock if system clock is 72MHz)
    • Period (ARR): 999 (resulting in 1KHz frequency)
    • PWM Mode: PWM Mode 1
    • Output Pin: GPIOA Pin 0 (Alternate Function Push-Pull)

    Important Note: Ensure the HAL is properly configured so that the TIM_HandleTypeDef (htim2) is correctly located and initialized.

    /* Header File: tim.h */
    #ifndef __TIM_H__
    #define __TIM_H__
    
    #include "main.h"
    
    extern TIM_HandleTypeDef htim2;
    
    void MX_TIM2_Init(void);
    void PWM_Start(void);
    void PWM_Stop(void);
    void PWM_Set_Pulse_Value(uint16_t pulse);
    void PWM_Set_DutyCycle_Percent(float duty_percent);
    uint16_t PWM_Get_Current_Pulse(void);
    float PWM_Get_Current_DutyCycle_Percent(void);
    
    #endif
    /* Implementation File: tim.c */
    #include "tim.h"
    
    TIM_HandleTypeDef htim2;
    
    void MX_TIM2_Init(void) {
        TIM_OC_InitTypeDef sConfigOC = {0};
    
        htim2.Instance = TIM2;
        htim2.Init.Prescaler = 71;
        htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
        htim2.Init.Period = 999;
        htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
        htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    
        HAL_TIM_Base_Init(&htim2);
        
        TIM_ClockConfigTypeDef sClockSourceConfig = {0};
        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
        HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);
    
        HAL_TIM_PWM_Init(&htim2);
    
        sConfigOC.OCMode = TIM_OCMODE_PWM1;
        sConfigOC.Pulse = 0;
        sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
        sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
        HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
    
        HAL_TIM_MspPostInit(&htim2);
        PWM_Start();
    }
    
    void HAL_TIM_MspPostInit(TIM_HandleTypeDef *timHandle) {
        if (timHandle->Instance == TIM2) {
            __HAL_RCC_GPIOA_CLK_ENABLE();
            GPIO_InitTypeDef GPIO_InitStruct = {0};
            GPIO_InitStruct.Pin = GPIO_PIN_0;
            GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
            GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
            HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
        }
    }
    
    void PWM_Start(void) { HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); }
    void PWM_Stop(void) { HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1); }
    
    void PWM_Set_Pulse_Value(uint16_t pulse) {
        if (pulse > 999) pulse = 999;
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pulse);
    }
    
    void PWM_Set_DutyCycle_Percent(float duty_percent) {
        if (duty_percent < 0) duty_percent = 0;
        if (duty_percent > 100) duty_percent = 100;
        uint16_t pulse = (uint16_t)(duty_percent * 999.0f / 100.0f);
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pulse);
    }