Contiki-NG中使用2538的双UART

2020-03-29  本文已影响0人  irobust

网上并没有找到相关的资料或者例子,只看到TI的在Zigbee下如何使用2538的介绍(大致是按照2538的UART使用说明,逐个配置),2538里使用UART口需要一系列配置,虽然很多但是不一定要弄得很清楚,可以参照UART0的使用方法配置UART1,注意的一点是:UART1有CTS和RTS用于流控,UART0没有,由于我并不需要这个功能,所以直接忽略就行。

由于没有资料,所以就从源码跟踪,看看UART0到底是如何设置并且被初始化的。

platform.c

contiki-main.c是Contiki-NG的入口代码,C语言里那个不可或缺的main函数就在这里。第一行就是一个平台初始化函数platform_init_stage_one(),这个函数在arch/platform/cc2538dk/platform.c文件中实现,顺着这看下去,会看到这个文件中的另一个函数platform_inti_stage_two()中有UART的初始化代码。

#if UART_CONF_ENABLE
  uart_init(0);
  uart_init(1);
  uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte);
#endif
...
serial_line_init();

综上所述,修改如下:

#if UART_CONF_ENABLE
  uart_init(0);
  uart_init(1);
  uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte);
  // 如果只是为了发信息,下面这行代码可以不用
  uart_set_input(1, sensor_serial_line_input_byte);
#endif
...
serial_line_init();

board.h

位置:arch/platform/cc2538dk/dev/board.h
配置UART1的引脚(可参照UART0的配置,引脚不能和其他冲突),修改如下:

// UART1
#define UART1_RX_PORT           GPIO_A_NUM
#define UART1_RX_PIN            4

#define UART1_TX_PORT           GPIO_A_NUM
#define UART1_TX_PIN            5

#define UART1_CTS_PORT          (-1) //GPIO_B_NUM
#define UART1_CTS_PIN           (-1) //0

#define UART1_RTS_PORT          (-1) //GPIO_D_NUM
#define UART1_RTS_PIN           (-1) //3

serial-line.c

经过上述设置后,UART1能发信息了,为了让UART1能收信息,还需要设置这个文件。在platform.c中的sensor_serial_line_input_byteserial_line_init函数都来自这个文件。

默认情况下,这个文件代码处理了UART0的输入,包括:定义接收缓冲区
(用ringbuf实现)、接收处理事件信号、接收处理函数和处理进程。为了能够将独立处理UART1的输入,只需要把处理UART0的代码仿写一下就好。如下:

/*******
 * UART1
 * */
// 定义不同名称的接收缓冲区
static struct ringbuf srxbuf;
static uint8_t srxbuf_data[BUFSIZE];

// 定义处理进程
PROCESS(sensor_serial_line_process, "Sensor Serial driver");

// 定义接收处理事件信号
process_event_t sensor_serial_line_event_message;

/*---------------------------------------------------------------------------*/
// 接收处理函数
int
sensor_serial_line_input_byte(unsigned char c)
{
  static uint8_t overflow = 0; /* Buffer overflow: ignore until END */
  
  if(!overflow) {
    /* Add character */
    if(ringbuf_put(&srxbuf, c) == 0) {
      /* Buffer overflow: ignore the rest of the line */
      overflow = 1;
    }
  } else {
    /* Buffer overflowed:
     * Only (try to) add terminator characters, otherwise skip */
    if((c == END || c == END2) && ringbuf_put(&srxbuf, c) != 0) {
      overflow = 0;
    }
  }

  /* Wake up consumer process */
  process_poll(&sensor_serial_line_process);
  return 1;
}
/*---------------------------------------------------------------------------*/
// 接收处理进程
PROCESS_THREAD(sensor_serial_line_process, ev, data)
{
  static char buf[BUFSIZE];
  static int ptr;

  PROCESS_BEGIN();

  sensor_serial_line_event_message = process_alloc_event();
  ptr = 0;

  while(1) {
    /* Fill application buffer until newline or empty */
    int c = ringbuf_get(&srxbuf);
    
    if(c == -1) {
      /* Buffer empty, wait for poll */
      PROCESS_YIELD();
    } else {
      if((c != END && c != END2)) {
        if(ptr < BUFSIZE-1) {
          buf[ptr++] = (uint8_t)c;
        } else {
          /* Ignore character (wait for EOL) */
        }
      } else {
        /* Terminate */
        buf[ptr++] = (uint8_t)'\0';

        /* Broadcast event */
        process_post(PROCESS_BROADCAST, sensor_serial_line_event_message, buf);

        /* Wait until all processes have handled the serial line event */
        if(PROCESS_ERR_OK ==
          process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL)) {
          PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE);
        }
        ptr = 0;
      }
    }
  }

  PROCESS_END();
}

接下来还需要在serial_line_init增加UART1的相关代码:

void
serial_line_init(void)
{
  // UART0
  ringbuf_init(&rxbuf, rxbuf_data, sizeof(rxbuf_data));
  process_start(&serial_line_process, NULL);
  // UART1
  ringbuf_init(&srxbuf, srxbuf_data, sizeof(srxbuf_data));
  process_start(&sensor_serial_line_process, NULL);
}

如何使用

#include "dev/serial-line.h"
#include "dev/uart.h"
uart_write_byte(1, 0x41);
if(ev == sensor_serial_line_event_message) {
      uint8_t dLen = strlen((char*)data);
      for (size_t i = 0; i < dLen; i++)
      {
        uart_write_byte(1, *(char*)data++);
      }
    }
上一篇 下一篇

猜你喜欢

热点阅读