Wrong assignment to struct

Viewed 108

I have structs like this:

typedef struct ws2811_channel_t
{
    int gpionum;                                 //< GPIO Pin with PWM alternate function, 0 if unused
    int invert;                                  //< Invert output signal
    int count;                                   //< Number of LEDs, 0 if channel is unused
    int strip_type;                              //< Strip color layout -- one of WS2811_STRIP_xxx constants
    ws2811_led_t *leds;                          //< LED buffers, allocated by driver based on count
    uint8_t brightness;                          //< Brightness value between 0 and 255
    uint8_t wshift;                              //< White shift value
    uint8_t rshift;                              //< Red shift value
    uint8_t gshift;                              //< Green shift value
    uint8_t bshift;                              //< Blue shift value
    uint8_t *gamma;                              //< Gamma correction table
} ws2811_channel_t;

typedef struct ws2811_t
{
    uint64_t render_wait_time;                   //< time in µs before the next render can run
    struct ws2811_device *device;                //< Private data for driver use
    const rpi_hw_t *rpi_hw;                      //< RPI Hardware Information
    uint32_t freq;                               //< Required output frequency
    int dmanum;                                  //< DMA number _not_ already in use
    ws2811_channel_t channel[RPI_PWM_CHANNELS];
} ws2811_t;

and my working example:

ws2811_channel_t channel = {
        .gpionum = LED_PIN,
        .invert = LED_INVERT,
        .count = LED_COUNT,
        .strip_type = WS2811_STRIP_RGB,
        .brightness = LED_BRIGHTNESS,

    };
    ws2811_t test = {
        .freq = LED_FREQ_HZ,
        .dmanum = LED_DMA,
        channel,
    };
    LOG_INFO("LEDController: Init - " << ws2811_get_return_t_str(ws2811_init(&test)));
    for (int i = 0; i < LED_COUNT; i++)
    {
        test.channel[0].leds[i] = (0 << 16) | (0 << 8) | 0;
    
    }
    ws2811_render(&test);

I want to make proper assignment for private property in class, so when I am declaring it like this:

ws2811_channel_t channel;
channel.gpionum = LED_PIN;
channel.invert = LED_INVERT;
channel.count = LED_COUNT;
channel.strip_type = WS2811_STRIP_RGB;
channel.brightness = LED_BRIGHTNESS;
ws2811_t test;
test.freq = LED_FREQ_HZ;
test.dmanum = LED_DMA;
test.channel[0] = channel;

    LOG_INFO("LEDController: Init - " << ws2811_get_return_t_str(ws2811_init(&test)));
    for (int i = 0; i < LED_COUNT; i++)
    {
        test.channel[0].leds[i] = (0 << 16) | (0 << 8) | 0;
    
    }
ws2811_render(&test);

ws2811_render(&test); hangs and freezes, on some point I got error which was pointing to that method. I am assuming it's because it has wrong assignments somehow. But why?

definition of render is

ws2811_return_t  ws2811_render(ws2811_t *ws2811)

From here: https://github.com/jgarff/rpi_ws281x/blob/master/ws2811.c#L1138

What am I doing wrong?

1 Answers

In your second example, try ws2811_channel_t channel{}; and ws2811_t test{}; - e.g. add the {}.

If you do this, then you'll zero initialise all the members. The key difference between your first (working) version, and the second (broken) version is that first version will zero things like gamma whilst the second version won't. Adding {} will zero everything before you overwrite the items you want.

If you do type a = {...}, then whatever is in the ... and not mentioned or indexed will be zeroed. If you do type b; b.field=value; there is nothing here that will zero any specifically not initialised fields.

Related