Jump to content

    
Sign in to follow this  
mantech

Новая ревизия IMX6S стала сильнее греться...

Recommended Posts

4 часа назад, aaarrr сказал:

Дался вам этот датчик!

Да вот дело то в том, что началась эта история так, запускал я программу для теста, на плате без радиатора в течении 1 часа. "старые" платы это всегда прекрасно переносили, не зависали и не перегружались, а новые через 20 мин стали виснуть и перегружаться по ватчдогу. До этого я на этот датчик и не смотрел. Сначала подумал, что просто плата неудачная попалась, но остальные вели себя так же...

Потом взял термометр с термопарой и замерил, что по факту на 5 град горячее, хотя по датчику на 8-10 показывает, но т.к. разброс 4 град - это укладывается. По току померяю, как будет возможность...

4 часа назад, makc сказал:

К тому же так бывает, что на плате что-то другое может подогревать процессор, даже когда он заглушен (в ресете).

Это исключено - платы абсолютно одинаковы и по сути и по комплектации.

Share this post


Link to post
Share on other sites
11 минут назад, mantech сказал:

Это исключено - платы абсолютно одинаковы и по сути и по комплектации.

Пока причина не установлена что бы то ни было исключать на 100% нельзя. Мое предложение сравнить потребление при остановленном процессоре как раз и направлено на проверку тезиса "абсолютно одинаковы" хотя бы по одному показателю - потреблению в статическом режиме. Проверьте, убедитесь, и двигайтесь дальше по пути усложнения теста. А пока раз никто с таким не сталкивался и простые и очевидные предложения закончились, то без новой информации дальше продвинуться не удастся.

PS: когда я когда-то впервые столкнулся с обычным чип-конденсатором, ушедшим почти в КЗ и гревшимся как чёрт, я тоже с трудом мог поверить своим глазам, пока не выпаял его и не прозвонил отдельно.

Share this post


Link to post
Share on other sites
21 minutes ago, mantech said:

по факту на 5 град горячее, хотя по датчику на 8-10 показывает

В общем-то не повод виснуть и перезагружаться...

Share this post


Link to post
Share on other sites
5 минут назад, aaarrr сказал:

В общем-то не повод виснуть и перезагружаться...

В общем-то верно, но не даёт понимания с чем именно может быть проблема. 

@mantech стресс-тест для внешней памяти гоняли?

Share this post


Link to post
Share on other sites
45 минут назад, aaarrr сказал:

В общем-то не повод виснуть и перезагружаться...

Это тест такой, на грани дин. диапазона.

ЗЫ. Проверил токи в разных режимах питание платы - 5В  (Г-"горячая",  Х-"холодная"):

1) пустая плата(без программы, только внутренний бут)

Х - 152мА   Г-165мА

2) собственнописанный загрузчик

Х - 260   Г - 270

3) ПО с графикой и пр плюшками

Х - 450   Г - 470

Вроде разница в 20мА , но это при 5В, при питании ядра в 1.1В ток отличается почти в 70мА, это уже ощутимо...

42 минуты назад, makc сказал:

стресс-тест для внешней памяти гоняли?

Да, все норм.

Share this post


Link to post
Share on other sites
54 минуты назад, mantech сказал:

1) пустая плата(без программы, только внутренний бут)

Х - 152мА   Г-165мА

А при поданном на процессор ресете какая получается разница?

Share this post


Link to post
Share on other sites
17 hours ago, mantech said:

при питании ядра в 1.1В ток отличается почти в 70мА

Кстати, напряжение проверяли? Да и осциллографом посмотреть не грех.

Share this post


Link to post
Share on other sites
55 минут назад, mantech сказал:

Х - 35мА   Г-40мА

Довольно большая разница. Это однозначно говорит о том, что платы не одинаковы не только процессором. Дальше стоит внимательно проверить питание с помощью осциллографа на пульсации и стабильность.

2 минуты назад, aaarrr сказал:

Кстати, напряжение проверяли? Да и осциллографом посмотреть не грех.

Про напряжение я уже спрашивал и вроде бы оно в норме. А вот с осциллографом туда ещё не лазили, видимо пора.

Share this post


Link to post
Share on other sites
29.04.2021 в 18:07, mantech сказал:

Приветствую. Сегодня привезли платы с чипом IMX6S от известной Ижевской фирмы

а автору плат вопросы задали, он в курсе? по imx6s последние упоминания там были за 2019 - смена ревизии ddr3 и обновление конфига

в еррате от 2019 есть упоминания о проблемах lpddr2/lpddr3, но там проблема с двумя чипами, а на Холе и СоМах вроде как один и просто ddr3

Share this post


Link to post
Share on other sites
4 часа назад, aaarrr сказал:

Кстати, напряжение проверяли?

Все норм, подозрение в быдлокоде от IMX Platform SDK...

Вопрос, где в линуксовых исходниках идет работа с термодатчиком, че-то не могу найти ничего, кроме 

\kernel\rel_imx_3.0.35_4.1.0-sk\drivers\thermal\thermal_sys.c  - но это общий файл, сами функции (get_temp(tz, &temperature) где-то закопаны...

 

Похоже нашел - kernel\rel_imx_3.0.35_4.1.0-sk\drivers\mxc\thermal\thermal.c

Edited by mantech

Share this post


Link to post
Share on other sites
23 часа назад, mantech сказал:

подозрение в быдлокоде

Вообщем смотрел код, ничего криминального не нашел, может глаза замылились, посмотрите, если не лень кому, может что есть...

Код работы с термодатчиком:

#include "tempmon/tempmon.h"
#include "registers/regstempmon.h"
#include "registers/regsocotp.h"
#include "registers/regspmu.h"
#include "interrupt.h"
#include "irq_numbers.h"
#include "soc_memory_map.h"

//////////////////////////////////////////////////////////////////////////////////////////
// Definitions
//////////////////////////////////////////////////////////////////////////////////////////

//! @name Temperature calibration OTP field masks
//!{
#define BM_ROOM_COUNT (0xfff00000)  //!< Room temperature sensor count bit mask.
#define BP_ROOM_COUNT (20)          //!< Room temperature sensor count bit position.
#define BM_HOT_COUNT (0x000fff00)   //!< Hot temperature sensor count bit mask.
#define BP_HOT_COUNT (8)            //!< Hot temperature sensor count bit position.
#define BM_HOT_TEMP (0x000000ff)    //!< Hot test temperature in degrees C bit mask.
#define BP_HOT_TEMP (0)             //!< Hot test temperature in degrees C bit position.
//@}

//! @brief Room temperature in degrees C.
#define ROOM_TEMP (25.0f)

//! @brief Default temperature calibration points.
#define DEFAULT_TEMP_CAL_DATA (0x57d4df7d)

//! @brief Temperature calibration OTP register info
enum _temp_cal_otp_reg {
    kTempCalibrationOtpBank = 1,    //!< Bank 1
    kTempCalibrationOtpRow = 6      //!< Row/word 6
};

//! @brief Temperature measurement period constants.
enum _temp_period {
    kMaxMeasurementPeriod_ms = 2000, //!< 2 seconds is the maximum time between measurements.
    kMaxMeasurementTicks = 0xffff,   //!< The max measurement period in 32.768 kHz clock ticks.
    kMeasurementTicksPerSecond = 32768, //!< The temperature measurement clock rate.
    kMillisecondsPerSecond = 1000   //!< Number of milliseconds per second.
};

/*!
 * @brief Global data for the tempmon driver.
 */
typedef struct _tempmon_info {
    float roomCount; //!< Room temperature sensor count value.
    float hotCount;  //!< Hot temperature sensor count value.
    float hotTemp;  //!< The hot test temperature in degrees C.
    tempmon_alarm_callback_t alarmCallback; //!< Callback to invoke when a new measurement is ready.
    bool isAlarmEnabled; //!< True if automatic measurements are in progress.
} tempmon_info_t;

//////////////////////////////////////////////////////////////////////////////////////////
// Prototypes
//////////////////////////////////////////////////////////////////////////////////////////

inline float compute_temp(float measuredCount);
inline int compute_alarm(float alarmTemp);

static void tempmon_alarm_isr(void);

//////////////////////////////////////////////////////////////////////////////////////////
// Variables
//////////////////////////////////////////////////////////////////////////////////////////

//! @brief Global data for the tempmon driver.
static tempmon_info_t s_tempmon;

//////////////////////////////////////////////////////////////////////////////////////////
// Code
//////////////////////////////////////////////////////////////////////////////////////////

//! @brief Calculate the temperature from a measurement result.
//! @param measuredCount The resulting count value of a temp sensor measurement cycle.
//! @return The temperature in degrees C.
float compute_temp(float measuredCount)
{
    float a = (s_tempmon.hotTemp - ROOM_TEMP);
    float b = (s_tempmon.roomCount - s_tempmon.hotCount);
    float c = a / b;
    float d = (measuredCount - s_tempmon.hotCount);
    float e = d * c;
    float f = s_tempmon.hotTemp - e;
    return f;
//     return hotTemp - (measuredCount - hotCount) * ((hotTemp - ROOM_TEMP) / (roomCount - hotCount));
}

//! @brief Calculate an alarm value given the alarm temperature.
//! @param alarmTemp The desired alarm temperature in degrees C.
//! @return Value to use for the alarm count value for @a alarmTemp.
int compute_alarm(float alarmTemp)
{
    float a = (alarmTemp - s_tempmon.hotTemp);
    float b = (s_tempmon.hotTemp - ROOM_TEMP);
    float c = (s_tempmon.roomCount - s_tempmon.hotCount);
    float d = (b / c);
    return s_tempmon.hotCount + a / d;
//     return s_tempmon.hotCount + (alarmTemp - s_tempmon.hotTemp) / ((s_tempmon.hotTemp - ROOM_TEMP) / (s_tempmon.roomCount - s_tempmon.hotCount));
}

//! @brief Interrupt handler for the over-temperature alarm.
//!
//! This interrupt handler gets the current die temperature and calls the alarm callback function
//! that was previously installed with tempmon_set_alarm(). If for some reason there is no alarm
//! callback set, this routine does nothing except clear the IRQ.
static void tempmon_alarm_isr(void)
{
    if (s_tempmon.alarmCallback)
    {
        // Pass the current die temp to the alarm callback.
        float currentTemp = tempmon_get_temp();
        s_tempmon.alarmCallback(currentTemp);
    }
    
    // Clear the alarm IRQ by writing a 1.
    BF_SET(PMU_MISC1, IRQ_TEMPSENSE);
}

int tempmon_init(void)
{
    // Read the calibration point data from OTP.
    uint32_t calibrationData = HW_OCOTP_ANA1_RD();
    
    // If the OTP fields are blank, use a default set of calibration points.
    if (calibrationData == 0)
    {
        calibrationData = DEFAULT_TEMP_CAL_DATA;
    }
    
    // Extract calibration points from the OTP data.
    s_tempmon.roomCount = (calibrationData & BM_ROOM_COUNT) >> BP_ROOM_COUNT;
    s_tempmon.hotCount = (calibrationData & BM_HOT_COUNT) >> BP_HOT_COUNT;
    s_tempmon.hotTemp = (calibrationData & BM_HOT_TEMP) >> BP_HOT_TEMP;
    
    // Fill in other global info fields.
    s_tempmon.alarmCallback = NULL;
    s_tempmon.isAlarmEnabled = false;
    
    return 0;
}

float tempmon_get_temp(void)
{
    // If automatic measurements are not enabled, wake up the temp sensor and take a measurement.
    if (!s_tempmon.isAlarmEnabled)
    {
        // Wake up the temp monitor.
        BF_CLR(TEMPMON_TEMPSENSE0, POWER_DOWN);
    
        // Clear the measure frequency so we only get single measurements.
        BF_CLR(TEMPMON_TEMPSENSE1, MEASURE_FREQ);
    
        // Start a measurement cycle.
        BF_SET(TEMPMON_TEMPSENSE0, MEASURE_TEMP);
    }
    
    // Wait until the measurement is ready.
    while (!HW_TEMPMON_TEMPSENSE0.B.FINISHED);
    
    // Read the measured temperature.
    int measuredCount = HW_TEMPMON_TEMPSENSE0.B.TEMP_CNT;
    
    // Power down the temp monitor, unless alarms are enabled.
    if (!s_tempmon.isAlarmEnabled)
    {
        BF_SET(TEMPMON_TEMPSENSE0, POWER_DOWN);
    }
    
    // Return the computed temperature.
    return compute_temp(measuredCount);
}

void tempmon_set_alarm(uint32_t period, float alarmTemp, tempmon_alarm_callback_t alarmCallback)
{
    // Save alarm info.
    s_tempmon.alarmCallback = alarmCallback;
    s_tempmon.isAlarmEnabled = true;
    
    // Wake up the temp monitor.
    BF_CLR(TEMPMON_TEMPSENSE0, POWER_DOWN);
    
    // Set the measurement frequency.
    int ticks;
    if (period >= kMaxMeasurementPeriod_ms)
    {
        ticks = kMaxMeasurementTicks;
    }
    else
    {
        // Convert milliseconds to 32.768 kHz clock ticks.
        ticks = period * kMeasurementTicksPerSecond / kMillisecondsPerSecond;
    }
    
    BF_WR(TEMPMON_TEMPSENSE1, MEASURE_FREQ, ticks);
    
    // Calculate and fill in the alarm value.
    int alarmValue = compute_alarm(alarmTemp);
    BF_WR(TEMPMON_TEMPSENSE0, ALARM_VALUE, alarmValue);
    
    // Clear the alarm IRQ by writing a 1.
    BF_SET(PMU_MISC1, IRQ_TEMPSENSE);
    
    // Enable the alarm interrupt.
    register_interrupt_routine(IMX_INT_TEMPERATURE, tempmon_alarm_isr);
    enable_interrupt(IMX_INT_TEMPERATURE, CPU_0, 1);
    
    // Start automatic measurements.
    BF_SET(TEMPMON_TEMPSENSE0, MEASURE_TEMP);
}

void tempmon_disable_alarm(void)
{
    // Turn off the alarm interrupt.
    disable_interrupt(IMX_INT_TEMPERATURE, CPU_0);
    
    // Stop automatic measurements.
    BF_CLR(TEMPMON_TEMPSENSE0, MEASURE_TEMP);
    BF_CLR(TEMPMON_TEMPSENSE1, MEASURE_FREQ);
    
    // Power down the temp monitor.
    BF_SET(TEMPMON_TEMPSENSE0, POWER_DOWN);

    // Clear auto measurement info.
    s_tempmon.alarmCallback = NULL;
    s_tempmon.isAlarmEnabled = false;
}

Инициализация из программы: 

  tempmon_init(); 
  int period = 1000;
  int alarmTemp = 90;//restart after 100grad    100-restart after 90grad
  tempmon_set_alarm(period, alarmTemp, over_temp_callback); 
 

Получение температуры - tempmon_get_temp();

Посмотрел по даташиту - формула для расчета верная, вообщем х.з,  но вот это смущает

int alarmTemp = 90;//restart after 100grad    100-restart after 90grad - почему обратная зависимость?

Edited by mantech

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this