openwch / ch32v307

Including the SDK、HDK、Datasheet of RISC-V MCU CH32V307 and other relevant development materials
387 stars 95 forks source link

ch32v307 - How to determine at what priority the current code is running. #58

Closed KurtE closed 1 year ago

KurtE commented 1 year ago

Is there a prescribed way for some core code to determine in what context (more specifically priority) the code is being called in?

In a particular case, I am working on an Arduino version of HardwareSerial for the USarts as well as Uarts. And in the current code, the calls like: Serial1.print("ABCD"); Will try to put the string onto the software queue and output the stuff from the queue to the hardware using the interrupt handler. Where it gets interesting, is if you fill up the queue, the code wants to wait until there is enough room on the queue to hold the complete data before returning.

However suppose that the Serial1.print() (or in your case printf) is called from inside an interrupt handler, which has a higher priority (lower number) than the Hardware Serial Interrupt is currently running. The current code hangs.

On a different platform, we have code in place, that detects this and manually feeds the hardware from the software queue. Something like:

    while (tx_buffer_tail_ == head) {
        int priority = nvic_execution_priority();
        if (priority <= hardware->irq_priority) {
            if ((port->STAT & LPUART_STAT_TDRE)) {
                uint32_t tail = tx_buffer_tail_;
                if (++tail >= tx_buffer_total_size_) tail = 0;
                if (tail < tx_buffer_size_) {
                    n = tx_buffer_[tail];
                } else {
                    n = tx_buffer_storage_[tail-tx_buffer_size_];
                }
                port->DATA  = n;
                tx_buffer_tail_ = tail;
            }
        } else if (priority >= 256) 
        {
            yield(); // wait
        } 
    }

In this case the interesting line is: int priority = nvic_execution_priority();

My question is, is there an equivalent way on the risc-v or more specifically CH32v307 and if so will it also work on the CH32v203

Thanks Kurt

KurtE commented 1 year ago

Wondering: will experiment if I can simply detect if I am running on an ISR or not... Looking at the QingKeV4_Processor pdf, I see there is a register: PFIC_GISR, which has the field NESTSTA. And maybe if that value is 0, not running ISR code?