Thread blocking

Hi Everyone,

I'm using nrfConnect Sdk v1.7.0 with vs code for nrf52833 chip.

I'm new to developing rtos applications, here I tried to to poll out some uart tx data using threads.

from some examples I've picked two methods of thread creation and I got some doubts related to them.

They maybe too newbie questions, pardon me.

Find method 1: in there I was able to create a thread, and my code blocks from there and nothing else executes from there on.

method 2: I was able to create a thread and transmit data successfully, but it requires my main thread to put into sleep (as you can find peripheral_uart example)

I suppose threads should be running parallelly, if i put main thread, there's added delay for other events, of  k_sleep(K_MSEC(1));

/* main thread */

void main(void)
{
  int err;
  
  /* Init Uart */
  uartDev = device_get_binding("UART_0");  
  InitUart(uartDev);
 
  
  /* Start Timer */
  /* Duartion : One MSec,Period : One MSec */
  k_timer_start(&msec_timer,K_MSEC(1),K_MSEC(1));
  for (;;)
  { /* Some app related events executed here */
    for(uint8_t i =0; i<NUMBEROFEVENTS; i++)
    {
      if(AppInstance.Events[i]==TM_TRUE)
      {
        AppInstance.Events[i] = TM_FALSE;
        HandleEvents(i);
      }
    }
    k_sleep(K_MSEC(1)); /* Sleep call, so that uart thread executes */
  }
}

 

/* uart thread */

#include "tmuart.h"
#define UARTTHREADSIZE 1024
#define PRIORITY 7

extern const struct device *uartDev;
extern struct uart_data uartData;
extern void uarttxComplete(void);
static K_SEM_DEFINE(uart_write_ok, 0, 1);
static struct k_thread uartThreadData;
static K_KERNEL_STACK_DEFINE(uarttx_thread_stack, UARTTHREADSIZE);
uint8_t uartbuf[512];
uint16_t uartbuflen =0;

void UARTDeQueueData(uint8_t *pData,uint16_t Len,const struct device *pUartDev)
{
    
    memcpy(uartbuf,pData,Len);
    uartbuflen = Len;
  // uart_irq_tx_enable(pUartDev);
   k_sem_give(&uart_write_ok);
  }

/****************************************************************
 * Init Uart
****************************************************************/
void InitUart(const struct device *pUartDev)
{
  
  

 /* TX thread */ /* METHOD 1 */
	//  k_thread_create(&uartThreadData, uarttx_thread_stack,
	// 		K_KERNEL_STACK_SIZEOF(uarttx_thread_stack),
	//  		uart_tx_thread, hTxUart, NULL, NULL,
	//  		K_PRIO_COOP(7), 
	//  		0, K_NO_WAIT);
	//  k_thread_name_set(&uartThreadData, "UART TX");

}


#if 1

static void uart_tx_thread(void *p1, void *p2, void *p3)
{
  
    k_sem_take(&uart_write_ok,K_FOREVER);
  while(1)
  {


for(int i=0;i<uartbuflen;i++)
  uart_poll_out(uartDev,uartbuf[i]);

  uartbuflen =0;
  uarttxComplete();

     k_yield();
  }
}
#endif

#if 1 /* METHOD 2 */
K_THREAD_DEFINE(uart_thread_id, UARTTHREADSIZE, uart_tx_thread  , NULL, NULL,
		NULL, PRIORITY, 0, 0);
#endif 

Parents
  • Hi Viswa, 

    I still don't know how you configure the Threads and what inside them in both Method 1 and Method 2. Please elaborate a little bit more. 

    When you are running a Thread at non-negative priority it will be executed as "pre-emptive" thread and "a preemptible thread may be supplanted at any time if a cooperative thread, or a preemptible thread of higher or equal priority, becomes ready."

    See the documentation on Thread priority here.

    I assume your question is about why the threads with same priority doesn't yield to each other and require you to do either k_sleep or k_yield. 

    The important part here is that it only automatically yield to same priority thread when time slice scheduling is used. See here.

    As far as I know by default CONFIG_TIMESLICING=y, however, CONFIG_TIMESLICE_SIZE=0 by default. 
     CONFIG_TIMESLICE_SIZE=0 means there will be no time slice (A time slice size of zero means "no limit" (i.e. an infinitely large time slice).)


    I tried to set CONFIG_TIMESLICE_SIZE=100 (100ms/slice) and it seems to work for me. The Thread with no yield or sleep will be preempted by other thread when it's ready. 

    Anyway doing a Thread without proper yielding is not a good practice. 

Reply
  • Hi Viswa, 

    I still don't know how you configure the Threads and what inside them in both Method 1 and Method 2. Please elaborate a little bit more. 

    When you are running a Thread at non-negative priority it will be executed as "pre-emptive" thread and "a preemptible thread may be supplanted at any time if a cooperative thread, or a preemptible thread of higher or equal priority, becomes ready."

    See the documentation on Thread priority here.

    I assume your question is about why the threads with same priority doesn't yield to each other and require you to do either k_sleep or k_yield. 

    The important part here is that it only automatically yield to same priority thread when time slice scheduling is used. See here.

    As far as I know by default CONFIG_TIMESLICING=y, however, CONFIG_TIMESLICE_SIZE=0 by default. 
     CONFIG_TIMESLICE_SIZE=0 means there will be no time slice (A time slice size of zero means "no limit" (i.e. an infinitely large time slice).)


    I tried to set CONFIG_TIMESLICE_SIZE=100 (100ms/slice) and it seems to work for me. The Thread with no yield or sleep will be preempted by other thread when it's ready. 

    Anyway doing a Thread without proper yielding is not a good practice. 

Children
No Data
Related