ch32v003fun icon indicating copy to clipboard operation
ch32v003fun copied to clipboard

Why does my code stop when I connect minichlink terminal?

Open vegetablesalad opened this issue 1 year ago • 8 comments

I have some console output I show when receiving I2C data. Whenever I start ./minichlink -i -T my IC freezes and I get no output. If I delete the blinking LED code from while then everything works.

Doesn't work:

int main() {
    SystemInit();
    GPIO_port_enable(GPIO_port_D);
    GPIO_port_enable(GPIO_port_C);

    uint8_t blinkPin = GPIOv_from_PORT_PIN(GPIO_port_D, 5);
    GPIO_pinMode(blinkPin, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);

    // Initialize I2C slave
    GpioOf(PC1)->CFGLR = (GpioOf(PC1)->CFGLR & (~(0xf<<(4*((PC1)&0xf))))) | ((GPIO_CFGLR_OUT_10Mhz_AF_OD)<<(4*((PC1)&0xf))); 
    GpioOf(PC2)->CFGLR = (GpioOf(PC2)->CFGLR & (~(0xf<<(4*((PC2)&0xf))))) | ((GPIO_CFGLR_OUT_10Mhz_AF_OD)<<(4*((PC2)&0xf))); 

    SetupI2CSlave(address, i2c_registers, sizeof(i2c_registers), onWrite, onRead, false);
    while (1) {
        GPIO_digitalWrite(blinkPin, high);
		Delay_Ms( 200 );
        GPIO_digitalWrite(blinkPin, low);
		Delay_Ms( 200 );
    } // Do not let main exit, you can do other things here
}

Works:

    while (1) {
        //GPIO_digitalWrite(blinkPin, high);
		Delay_Ms( 200 );
        //GPIO_digitalWrite(blinkPin, low);
		Delay_Ms( 200 );
    } // Do not let main exit, you can do other things here

vegetablesalad avatar Apr 11 '24 10:04 vegetablesalad

What happen if u comment out the console output? I had issues with printf in the past.

unicab369 avatar Apr 12 '24 05:04 unicab369

@unicab369 tried to test out your theory today and it got even weirder.

First I tried to just run my code again to make sure the problem still persists, and what ended up happening - it started to work as it should. But only about ~30% of the time. And when minichlink connects and it doesn't freeze my LED starts pulsing at exactly 9.17Hz. No matter what my initial delay was.

Removed all printf from my code and it didn't make any difference.

This latest issue happens with this code:

void initLED(){
    GPIO_port_enable(GPIO_port_D);
    GPIOB = GPIOv_from_PORT_PIN(GPIO_port_D, 5);
    GPIOG = GPIOv_from_PORT_PIN(GPIO_port_D, 6);
    GPIOR = GPIOv_from_PORT_PIN(GPIO_port_D, 4);
    GPIO_pinMode(GPIOB, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
    GPIO_pinMode(GPIOG, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
    GPIO_pinMode(GPIOR, GPIO_pinMode_O_pushPull, GPIO_Speed_10MHz);
}
int main() {
    SystemInit();
    // initI2C();
    initLED();
    while (1) {
        GPIO_digitalWrite(GPIOR, high);
        GPIO_digitalWrite(GPIOG, high);
        GPIO_digitalWrite(GPIOB, high);
		Delay_Ms( 200 );
        GPIO_digitalWrite(GPIOR, low);
        GPIO_digitalWrite(GPIOG, low);
        GPIO_digitalWrite(GPIOB, low);
		Delay_Ms( 200 );
    } // Do not let main exit, you can do other things here
}

And only with this code. If I comment out two LED's and leave only one blinking then I'm back to freezing. If I leave two LED's then I might get some other weird combination of faster blinking or always on.

This is so weird and inconsistent.

vegetablesalad avatar Apr 12 '24 07:04 vegetablesalad

I just wanted to add for mine: I also have an I2C slave running receiving data, entire code doesn't run at all when there's no at least 5 printf statements. It's works perfectly fine when debug console is up and connected with ./minichlink -i -T (same as OP), but code execution will slowdown significantly when debug console is removed. I'm not sure what's going on, I'm fairly new to "low level" stuff. I'm assuming the slow down is because it's waiting to send the printf message but then times out??

I'll continue to look into it, but thought I'd comment about it here, seems like I'm not the only one with printf shenanigans

QuartzAl avatar Apr 29 '24 13:04 QuartzAl

This is worth having a deeper discussion on - what would you hope the behavior to be? We don't want to drop print() messages because we missed a window on the host PC, so the attitude is we can wait for a while and if it doesn't come out, then we keep going.

If we don't pause until the first printf read, and you did a bunch of printf's at start, then they would get missed.

I'm up for any behavior, and they're all pretty easy, but just don't know what the correct behavior should be.

cnlohr avatar Apr 30 '24 00:04 cnlohr

@QuartzAl how do you feel about an explicit attach function? I.e. "Please wait up to n milliseconds" for the debugger/semihost to attach so you can printf things, and if it doesn't attach, then, prints won't wait at all, until a terminal does attach?

cnlohr avatar Apr 30 '24 18:04 cnlohr

@cnlohr that's a pretty cool idea, and would definitely help. Reminds me of how arduino handles debug messages, if I'm not wrong, upon boot the device checks for anything connected if there is a debugger it connects, otherwise it doesn't care and continues.

Though an explicit function like that would probably be better, allows for debugger connection in the middle of code execution? Plus removes the delay issue. Not sure how any of that works, but it sounds cool

QuartzAl avatar Apr 30 '24 19:04 QuartzAl

Well, I think printf would always check. Since I would not want to mess with timing constraints. But, you could selectively printf based on this new function... Or you could manually run this function any time you wish. I think it may be:

int funDebugHostConnected( int nTimeoutMs ); // Set to negative to wait for forever.
// Return value:
// 0: Debug host is connected
// -1: Debug host is not connected.

I guess one thing I would want to consider is, what if there is NO additional state within ch32v003fun, and the current printf behavior remains the same - but now this function would let you manually use it or not.

cnlohr avatar Apr 30 '24 22:04 cnlohr

if no additional state is wanted giving this kind of function sounds like a good idea, the checks could be a user choice to make. I'm all in for this function being implemented

QuartzAl avatar May 02 '24 04:05 QuartzAl