cc2652移植letter-shell

cc26xx系列的MCU中,官方SDK不支持类似于Linux bash shell的命令行接口,因此我选择移植letter-shell。

  移植主要是修改shell_port.c、shell_port.h、shell_cfg_user.h三个文件,如果想使用SHELL_EXPORT_CMD()等导出命令,还需要修改链接器文件,即cc2652工程的*.cmd文件。

shell_port.h的内容比较简单,如下

/**
 * @file shell_port.h
 * @author Letter (NevermindZZT@gmail.com)
 * @brief 
 * @version 0.1
 * @date 2019-02-22
 * 
 * @copyright (c) 2019 Letter
 * 
 */

#ifndef __SHELL_PORT_H__
#define __SHELL_PORT_H__

#include "shell.h"

extern Shell *shell;

void userShellInit(void);
#endif

shell_port.c的内容,如下

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include "ti/sysbios/knl/Semaphore.h"
#include "ti/sysbios/gates/GateMutexPri.h"
#include <ti/drivers/UART2.h>
#include "ti_drivers_config.h"
#include "shell.h"
#include "log.h"
#include "string.h"

// Task configuration
#define SHELL_TASK_PRIORITY           2

#ifndef SHELL_TASK_STACK_SIZE
#define SHELL_TASK_STACK_SIZE         1024
#endif

// Task configuration
uint8_t shellTaskStack[SHELL_TASK_STACK_SIZE];
Task_Struct shellTask_Struct;
Task_Handle shellTask_Handle;

UART2_Handle uart;

static Shell uartShell;
Shell *shell = NULL;

char shellBuffer[1024];

static intptr_t mutex_key;
static GateMutexPri_Handle shellMutex;
//static Semaphore_Handle shellSem;


/**
 * @brief 用户shell写
 * 
 * @param data 数据
 * @param len 数据长度
 * 
 * @return short 实际写入的数据长度
 */
short userShellWrite(char *data, unsigned short len)
{
	int32_t status;
	// Write to the UART
	size_t  bytesWritten;
	status = UART2_write(uart, data, len, &bytesWritten);
	
    return bytesWritten;
}


/**
 * @brief 用户shell读
 * 
 * @param data 数据
 * @param len 数据长度
 * 
 * @return short 实际读取到
 */
short userShellRead(char *data, unsigned short len)
{
	// Read from the UART.
	size_t  bytesRead;
	uint8_t buffer;
	int32_t status;
	// 因为配置UART的接收为阻塞,因此UART2_read会阻塞在一个信号量上
	status = UART2_read(uart, &buffer, 1, &bytesRead);

	data[0] = buffer;
	
	return 1;
}


/**
 * @brief 用户shell上锁
 * 
 * @param shell shell
 * 
 * @return int 0
 */
int userShellLock(Shell *shell)
{
	mutex_key = GateMutexPri_enter(shellMutex);
//	Semaphore_pend(shellSem, BIOS_WAIT_FOREVER);

    return 0;
}


/**
 * @brief 用户shell解锁
 * 
 * @param shell shell
 * 
 * @return int 0
 */
int userShellUnlock(Shell *shell)
{
	GateMutexPri_leave(shellMutex, mutex_key);
//	Semaphore_post(shellSem);

    return 0;
}


/*********************************************************************
 * @fn      shellTask_Entry
 *
 * @brief   shell task entry point.
 *
 * @param   a0, a1 - not used.
 */
static void shellTask_Entry(UArg a0, UArg a1)
{
  Shell *shell = (Shell *)a0;
  char data;
  // Application main loop
  for (;;)
  {
      if (shell->read && shell->read(&data, 1) == 1)
      {
          shellHandler(shell, data);
      }
  }
}


/**
 * @brief 用户shell初始化
 * 
 */
void userShellInit(void)
{
    Task_Params taskParams;
	UART2_Params params;

	GateMutexPri_Params mutexParams;
	GateMutexPri_Params_init(&mutexParams);
	shellMutex = GateMutexPri_create(&mutexParams, NULL);
	
//	Semaphore_Params sem_params;
//	Semaphore_Params_init(&sem_params);
//	sem_params.mode = Semaphore_Mode_BINARY;
//	shellSem = Semaphore_create(1, &sem_params, NULL);

	shell = &uartShell;
    shell->write = userShellWrite;
    shell->read = userShellRead;
    shell->lock = userShellLock;
    shell->unlock = userShellUnlock;
    shellInit(shell, shellBuffer, sizeof(shellBuffer));

	// Initialize UART2 parameters
	UART2_Params_init(&params);
	params.baudRate = 115200;
	params.readMode = UART2_Mode_BLOCKING;
	params.writeMode = UART2_Mode_BLOCKING;
	
	// Open the UART
	uart = UART2_open(CONFIG_DISPLAY_UART, &params);
	// Enable receiver, inhibit low power mode
	UART2_rxEnable(uart);

    // Configure task
    Task_Params_init(&taskParams);
    // create shell task
    taskParams.stack = shellTaskStack;
    taskParams.stackSize = SHELL_TASK_STACK_SIZE;
    taskParams.priority = SHELL_TASK_PRIORITY;
    taskParams.arg0 = (UArg)shell;

    Task_construct(&shellTask_Struct, shellTask_Entry, &taskParams, NULL);
    shellTask_Handle = Task_handle(&shellTask_Struct);
}

其中,userShellLock/Unlock可以使用二值信号量或者GataMutex(Pri)互斥锁实现,我选择的是GataMutexPri,可以通过修改注释的代码用Semaphore实现,或者用GataMutex实现。

如果想使用SHELL_EXPORT_CMD()等导出命令,*.cmd文件修改如下:

SECTIONS
{
  .intvecs        :   >  FLASH_START
  .text           :   >> FLASH | FLASH_LAST_PAGE
  .const          :   >> FLASH | FLASH_LAST_PAGE
  .constdata      :   >> FLASH | FLASH_LAST_PAGE
  .rodata         :   >> FLASH | FLASH_LAST_PAGE
  .cinit          :   >  FLASH | FLASH_LAST_PAGE
  .pinit          :   >> FLASH | FLASH_LAST_PAGE
  .init_array     :   >  FLASH | FLASH_LAST_PAGE
  .emb_text       :   >> FLASH | FLASH_LAST_PAGE
  .ccfg           :   >  FLASH_LAST_PAGE (HIGH)

  shellCommand :
  {
    . = ALIGN(4);
    _shell_command_start = .;
	*(shellCommand)
    _shell_command_end = .;
    . = ALIGN(4);
  } >FLASH

  ......
}

其中,“shellCommand :{......} >FLASH”之间的代码段为添加的代码段。如果想使用命令列表的方式,可以不需要修改*.cmd文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值