Предупреждение: 'blkb.si47x_rds_blockb :: refined.si47x_rds_blockb :: :: groupType 'используется неинициализированным в этой функции - PullRequest
0 голосов
/ 30 марта 2020

/ Arduino / библиотеки / SI4735 / SI4735. cpp: в функции-члене 'char * SI4735 :: getRdsTime ()': /Users/rcaratti/Documents/Arduino/libraries/SI4735/SI4735.cpp: 1534: 5: предупреждение: 'blkb.si47x_rds_blockb :: refined.si47x_rds_blockb :::: groupType' используется неинициализированным в этой функции [-Wuninitialized] if (getRdsGroupType () == 4

/*
 * Block B data type
 * See also Si47XX PROGRAMMING GUIDE; AN332; pages 78 and 79
 * See also https://en.wikipedia.org/wiki/Radio_Data_System
 */
typedef union {
    struct
    {
        uint8_t address : 2;            // Depends on Group Type and Version codes. If 0A or 0B it is the Text Segment Address.
        uint8_t DI : 1;                 // Decoder Controll bit
        uint8_t MS : 1;                 // Music/Speech
        uint8_t TA : 1;                 // Traffic Announcement
        uint8_t programType : 5;        // PTY (Program Type) code
        uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
        uint8_t versionCode : 1;        // (B0) => 0=A; 1=B
        uint8_t groupType : 4;          // Group Type code.
    } group0;
    struct
    {
        uint8_t address : 4;            // Depends on Group Type and Version codes. If 2A or 2B it is the Text Segment Address.
        uint8_t textABFlag : 1;         // Do something if it chanhes from binary "0" to binary "1" or vice-versa
        uint8_t programType : 5;        // PTY (Program Type) code
        uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
        uint8_t versionCode : 1;        // (B0) => 0=A; 1=B
        uint8_t groupType : 4;          // Group Type code.
    } group2;
    struct
    {
        uint8_t content : 4;            // Depends on Group Type and Version codes.
        uint8_t textABFlag : 1;         // Do something if it chanhes from binary "0" to binary "1" or vice-versa
        uint8_t programType : 5;        // PTY (Program Type) code
        uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
        uint8_t versionCode : 1;        // (B0) => 0=A; 1=B
        uint8_t groupType : 4;          // Group Type code.
    } refined;
    struct
    {
        uint8_t lowValue;
        uint8_t highValue; // Most Significant byte first
    } raw;
} si47x_rds_blockb;
/*
 * Returns the Group Type (extracted from the Block B) 
 */
uint8_t SI4735::getRdsGroupType(void)
{
    si47x_rds_blockb blkb;

    blkb.raw.lowValue = currentRdsStatus.resp.BLOCKBL;
    blkb.raw.highValue = currentRdsStatus.resp.BLOCKBH;

    return blkb.refined.groupType;
}
/* 
 * Gets the RDS time and date when the Group type is 4 
 */
char *SI4735::getRdsTime()
{
    // Under Test and construction
    // Need to check the Group Type before.
    si47x_rds_date_time dt;

    if (getRdsGroupType() == 4)
    {
        char offset_sign;
        int offset_h;
        int offset_m;

        // uint16_t y, m, d;

        dt.raw[4] = currentRdsStatus.resp.BLOCKBL;
        dt.raw[5] = currentRdsStatus.resp.BLOCKBH;
        dt.raw[2] = currentRdsStatus.resp.BLOCKCL;
        dt.raw[3] = currentRdsStatus.resp.BLOCKCH;
        dt.raw[0] = currentRdsStatus.resp.BLOCKDL;
        dt.raw[1] = currentRdsStatus.resp.BLOCKDH;

        /*
        y = (unsigned)(dt.refined.mjd - 15078.2) / 365.25;
        m = ((unsigned)(dt.refined.mjd - 14956.1) - (unsigned)(y * 365.25)) / 30.6001;
        d = (unsigned)(dt.refined.mjd - 14956) - (unsigned)(y * 365.25) - (m * 30.6001);

        if (m > 13) {
            m = 1;
            y++;
        }
        y = y % 100;
        */
        // sprintf(rds_time, "%02/%02/%04 %02d:%02d", d,m,y,dt.refined.hour, dt.refined.minute);

        offset_sign = (dt.refined.offset_sense == 1) ? '+' : '-';
        offset_h = (dt.refined.offset * 30) / 60;
        offset_m = (dt.refined.offset * 30) - (offset_h * 60);
        sprintf(rds_time, "%02d:%02d %c%02d:%02d", dt.refined.hour, dt.refined.minute, offset_sign, offset_h, offset_m);
        return rds_time;
    }

    return NULL;
}

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Спасибо. Я исправил проблему на платформах Arduino DUE, STM32 и ESP32 и, возможно, на других, использующих компилятор G CC. Компилятор G CC не допускает «Границу пересечений». Например, поле, образованное набором битов, не может быть сформировано частью байта и его последующим.

Мое решение было: typedef union {struct {uint16_t content: 4; // Зависит от типа группы и кода версии. uint16_t textABFlag: 1; // Делаем что-то, если оно изменяется из двоичного «0» в двоичное «1» или наоборот uint16_t programType: 5; // PTY (тип программы) код uint16_t trafficProgramCode: 1; // (TP) => 0 = Нет Traffi c Alerts; 1 = станция выдает траффи c оповещений uint16_t versionCode: 1; // (B0) => 0 = A; 1 = B uint16_t groupType: 4; // Код типа группы. } refinedValues; struct {uint16_t lowValue; uint16_t highValue; // Самый значимый байт первым} raw; значение uint16_t; } si47x_rds_blockb;

0 голосов
/ 30 марта 2020

Стандарт C ++ гласит:

Единицы распределения битовых полей на некоторых машинах, а не на других.

Так что, если мы посмотрим на

, то это очевидно
    struct
    {
        uint8_t content : 4;            // Depends on Group Type and Version codes.
        uint8_t textABFlag : 1;         // Do something if it chanhes from binary "0" to binary "1" or vice-versa
        uint8_t programType : 5;        // PTY (Program Type) code
        uint8_t trafficProgramCode : 1; // (TP) => 0 = No Traffic Alerts; 1 = Station gives Traffic Alerts
        uint8_t versionCode : 1;        // (B0) => 0=A; 1=B
        uint8_t groupType : 4;          // Group Type code.
    } refined;

что на машинах, где битовые поля не единицы размещения с перестановкой , content и textABFlag упакованы в первый октет, programType (не умещается полностью в первом ) вместе с trafficProgramCode и versionCode, упакованными во второй, и groupType в третий октет. Учитывая это,

uint8_t SI4735::getRdsGroupType(void)
{
    si47x_rds_blockb blkb;

    blkb.raw.lowValue = currentRdsStatus.resp.BLOCKBL;
    blkb.raw.highValue = currentRdsStatus.resp.BLOCKBH;

    return blkb.refined.groupType;
}

локальной переменной blkb эта функция устанавливает только первые два октета (lowValue и highValue), но возвращает groupType из неинициализированного третьего октета.

Чтобы надежно поместить все эти битовые поля в два октета, мы должны использовать uint16_t вместо uint8_t - но имейте в виду, что:

Битовые поля назначается справа налево на некоторых машинах, слева направо на других.

...