Application of queue Serialization of print debug - renesas/rx72n-envision-kit GitHub Wiki

Things to prepare

  • Indispensable

Prerequisite

Serialize means

  • Line up requirement in serial (continuously)
  • An appropriate data structure as implementation is queue
  • This method is effective when there are multiple tasks to use the hardware for one hardware.
  • As typical examples, explain the serialize of print debug.
    • Receive string transmission requirement from multiple tasks and run into the transmission function of SCI
    • Since the transmission function of SCI is non-blocking call, the process itself has not completed when the function ends.
    • Process complete is the format notified by callback function
    • After the transmission function of SCI ends, take semaphore and is in wait state.
    • Give semaphore when callback transmission complete notice of SCI, and release wait state.

Check circuit

Set SCI driver software with Smart Configurator

Add component

Set component

  • r_sci_rx
    • Reference
    • Enable "setting to generate interrupt when transmission completes" as setting not included in the above reference.
  • FreeRTOS_Object
    • Register task
      • Select FreeRTOS_Object -> Task
      • Enter task_2, task_3, print_task in Task Code and Task Name
    • Register semaphore
      • Select FreeRTOS_Object -> Semaphores
      • Select binary in Semaphore Type
    • Register queue
      • Select FreeRTOS_Object -> Queues
      • Enter 16 in Queue Length
      • Enter 256 in Item Size.
        • Setting to make up to sixteen queues with 256 character data.

Pin setting

print_task.c coding

#include "task_function.h"
/* Start user code for import. Do not edit comment generated here */
#include "r_sci_rx_if.h"
#include "r_sci_rx_pinset.h"
#include "platform.h"
#include <string.h>

void sci_callback(void *arg);

static sci_hdl_t sci_handle;
static signed portBASE_TYPE xHigherPriorityTaskWoken;

extern QueueHandle_t queue_handle_1;
extern SemaphoreHandle_t semaphore_handle_1;

/* End user code. Do not edit comment generated here */

void print_task(void * pvParameters)
{
/* Start user code for function. Do not edit comment generated here */
	sci_cfg_t   my_sci_config;
	static char string[256];

    /* Set up the configuration data structure for asynchronous (UART) operation. */
    my_sci_config.async.baud_rate    = 115200;
    my_sci_config.async.clk_src      = SCI_CLK_INT;
    my_sci_config.async.data_size    = SCI_DATA_8BIT;
    my_sci_config.async.parity_en    = SCI_PARITY_OFF;
    my_sci_config.async.parity_type  = SCI_EVEN_PARITY;
    my_sci_config.async.stop_bits    = SCI_STOPBITS_1;
    my_sci_config.async.int_priority = 15; /* disable 0 - low 1 - 15 high */

    R_SCI_Open(SCI_CH2, SCI_MODE_ASYNC, &my_sci_config, sci_callback, &sci_handle);
    R_SCI_PinSet_SCI2();

    while(1)
    {
    	xQueueReceive(queue_handle_1, string, portMAX_DELAY);
    	R_SCI_Send(sci_handle, (uint8_t *)string, strlen(string));
    	xSemaphoreTake( semaphore_handle_1, portMAX_DELAY );
    }
/* End user code. Do not edit comment generated here */
}
/* Start user code for other. Do not edit comment generated here */
void sci_callback(void *arg)
{
	xHigherPriorityTaskWoken = pdFALSE;
	xSemaphoreGiveFromISR(semaphore_handle_1, &xHigherPriorityTaskWoken);
	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

/* End user code. Do not edit comment generated here */

task_2.c coding

#include "task_function.h"
/* Start user code for import. Do not edit comment generated here */
#include "platform.h"

extern QueueHandle_t queue_handle_1;
/* End user code. Do not edit comment generated here */

void task_2(void * pvParameters)
{
/* Start user code for function. Do not edit comment generated here */
	char string[256];
	while(1)
	{
		vTaskDelay(1000);
		sprintf(string, "task_2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
		xQueueSend(queue_handle_1, string, portMAX_DELAY);
	}
/* End user code. Do not edit comment generated here */
}
/* Start user code for other. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

task_3.c coding

#include "task_function.h"
/* Start user code for import. Do not edit comment generated here */
#include "platform.h"

extern QueueHandle_t queue_handle_1;
/* End user code. Do not edit comment generated here */

void task_3(void * pvParameters)
{
/* Start user code for function. Do not edit comment generated here */
	char string[256];
	while(1)
	{
		vTaskDelay(1000);
		sprintf(string, "task_3: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n");
		xQueueSend(queue_handle_1, string, portMAX_DELAY);
	}
/* End user code. Do not edit comment generated here */
}
/* Start user code for other. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

Adjust heap capacity

Check operation

  • Boot Teraterm on Windows PC and select COM port (COMx: RSK USB Serial Port(COMx)) to connect
    • Setting -> Perform the setting below with serial port
      • Baud rate: 115200 bps
      • Data: 8 bit
      • Parity: none
      • Stop: 1 bit
      • Flow control: none
    • Setting -> Perform the setting below with terminal
      • Newline code
        • Reciept: AUTO
        • Transmission: CR+LF
      • Local echo
        • Uncheck the box
  • Execution:Reference
  • Check that the following log is outputted every second
task_2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
task_3: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
task_2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
task_3: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
task_2: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
task_3: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
  • Check that the print outputs from task_2 and task_3 are outputted without running into each other.
  • If R_SCI_Send() is called directly without xQueueSend() from task_2 and task_3, the transmission of task_3 is mixed into that of task_2, accordingly, it is not possible to output without running into each other as described above.
⚠️ **GitHub.com Fallback** ⚠️