ESP32 zahada C

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Neděle Červenec 16 14:22:13 CEST 2023


Ted zkoumam nejaky kod, (nekoukejte na funkcnost, to ted neni dulezite) 
a nechapu, proc linkeru nevadi za nejakych okolnosti, ze jsou ve 2 
souborech identicke globalni funkce. ESP-IDGF je 5.0.3

Tak jak to je, se to bez reci prelozi.

Pokud prejmenuju jednu funkci (init v souboru mcp9804_spy.c) tak vznikne 
chyba, kterou bych cekal i v predchozim stavu

D:/tst/____/unity_fixture_test/components/temperature/mcp9804.c:37: 
multiple definition of `mcp9804_get_temperature'; 
esp-idf/temperature/libtemperature.a(mcp9804_spy.c.obj):D:/tst/____/unity_fixture_test/components/temperature/mcp9804_spy.c:24: 
first defined here

Kdyz ji prejmenuju jen v souboru mcp9804.c je to zase OK.


Je to nejaka zamerna featura nebo cim to je? Jedine, co me napada, ze 
linker najde vsechny funkce ve prvnim modulu a tim padem se uz na druhy 
ani nediva, ale stejne nevim, jestli je to vlastnost, nebo chyba linkeru...

------------- další část ---------------
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#include <esp_log.h>
#include "mcp9804_spy.h"
#include "mcp9804_common.h"

static const char *TAG = "mcp9804_spy";

static uint8_t i2c_register_address;
static uint16_t i2c_returned_value;

void test(void)
{
    
}


void mcp9804_init(void)
{
    i2c_register_address = 0; 
    i2c_returned_value = 0;
}

float mcp9804_get_temperature(void)
{
    int16_t temperature_raw = i2c_returned_value;

    return convert_temperature(temperature_raw);
}

void i2c_readRegister_ExpectAndReturn(uint8_t reg_addr, uint16_t value)
{
    i2c_register_address = reg_addr;
    i2c_returned_value = value;
}
------------- další část ---------------
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#include <esp_log.h>
#include "mcp9804.h"
#include "mcp9804_common.h"

static const char *TAG = "mcp9804";

#define MCP9804_DATA_BUFFER_SIZE 2

#define SDA_PIN GPIO_NUM_4
#define SCL_PIN GPIO_NUM_5

static uint16_t configuration;
static uint16_t configuration_shadow;

static void configure_i2c(void);
static void mcp9804_write(uint8_t reg_addr, uint16_t data);
static uint16_t mcp9804_read(uint8_t reg_addr);
static void mcp9804_read_configuration(void);


void test(void)
{

}

void mcp9804_init(void)
{
    ESP_LOGD(TAG, "Initializing MCP9804...");

    configure_i2c();

    ESP_LOGD(TAG, "MCP9804 initialized");
}

float mcp9804_get_temperature(void)
{
    int16_t temperature_raw = mcp9804_read(MCP9804_REG_TA);

    return convert_temperature(temperature_raw);
}

static void configure_i2c(void)
{

    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = SDA_PIN,
        .scl_io_num = SCL_PIN,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = 100000UL,
        .clk_flags = 0,
    };
    ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf));
    ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0));
}

/**
 * @brief Writes to the register at the given address
 * @param[in] reg_addr Register address
 * @param[in] data Data to write
 */
static void mcp9804_write(uint8_t reg_addr, uint16_t data)
{

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);

    i2c_master_write_byte(cmd, (MCP9804_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, reg_addr & 0xF, true);

    uint8_t data_to_write[] = {(data >> 8) & 0xFF, data & 0xFF};

    i2c_master_write(cmd, data_to_write, MCP9804_DATA_BUFFER_SIZE, true);

    i2c_master_stop(cmd);

    ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS));
    i2c_cmd_link_delete(cmd);
}

/**
 * @brief Reads the register at the given address
 * @param[in] reg_addr Register address
 * @return Data read from the register
 */
static uint16_t mcp9804_read(uint8_t reg_addr)
{

    uint8_t data[MCP9804_DATA_BUFFER_SIZE] = {0};

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);

    i2c_master_write_byte(cmd, (MCP9804_ADDR << 1) | I2C_MASTER_WRITE, true);

    i2c_master_write_byte(cmd, reg_addr & 0xF, true);

    i2c_master_start(cmd);

    i2c_master_write_byte(cmd, (MCP9804_ADDR << 1) | I2C_MASTER_READ, true);

    i2c_master_read(cmd, data, MCP9804_DATA_BUFFER_SIZE, I2C_MASTER_LAST_NACK);

    i2c_master_stop(cmd);

    ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS));
    i2c_cmd_link_delete(cmd);

    return (uint16_t)(data[0] << 8) | (data[1] & 0xFF);
}
------------- další část ---------------
idf_component_register(
    
    SRCS "mcp9804_spy.c" "mcp9804.c" "mcp9804_common.c"
                    
    REQUIRES driver
    
    INCLUDE_DIRS "include"
)
------------- další část ---------------
#include <mcp9804_common.h>

float convert_temperature(int16_t temperature_raw)
{
    temperature_raw &= 0x1FFF;

    if ((temperature_raw & 0x1000) != 0)
    {
        temperature_raw |= 0xe000;
    }

    float temperature = (float)temperature_raw / 16.0F;

    return temperature;
}


Další informace o konferenci Hw-list