历史上的今天
返回首页

历史上的今天

今天是:2025年04月07日(星期一)

正在发生

2020年04月07日 | 【Contiki学习】01.Contiki-stm32系统下实现serial-shell功能

2020-04-07 来源:eefocus

一,背景介绍


之前通过网上收集资料(资料后期整理之后会在博客分享),在stm32上面跑通了,就是实现了简单的点灯程序,以及串口输出。


但是后期开发使用肯定需要用到shell,经过一番折腾后小有收获。


在这说一下开发环境:IAR+stm32vet6(ST官方库3.5+contiki3.0)


二,准备工作


1,在contiki源码中按照目录提取以下文件:

ps. stm32_shell.c是自行添加的代码


三,源码分析


1,先看一下main函数:


int main()

{

  dbg_setup_uart();

  led_init();

  printf("Initialisingrn");

  

  clock_init();

  process_init();

  //shell serial_line 初始化

  uart1_set_input(serial_line_input_byte);

  serial_line_init();

  //

  process_start(&etimer_process, NULL);

  autostart_start(autostart_processes);

  printf("Processes runningrn");

  while(1) {

    do 

    {

    } 

    while(process_run() > 0);

    idle_count++;

    /* Idle! */

    /* Stop processor clock */

    /* asm("wfi"::); */ 

  }

  return 0;

}


需要注意的是:


  //shell serial_line 初始化

  uart1_set_input(serial_line_input_byte);

  serial_line_init();

  //


2,usrt1_set_input定义在串口底层驱动里面

static int (* uart1_input_handler)(unsigned char c);


void uart1_set_input(int (* input)(unsigned char c))

{

    uart1_input_handler = input;

}

先建立一个函数指针:


static int (* uart1_input_handler)(unsigned char c);

再通过

uart1_set_input(serial_line_input_byte);

将(*uart1_input_handler)指向 serial_line_input_byte()函数,

这样就可以通过调用uart1_input_handler();将串口接到的数据导入serial_line中,从而可以通过serial_line_process进程进行命令分析做出相应处理。


uart1_input_handler();的调用写在串口中断中即可:


void USART1_IRQHandler(void)

{

      ENERGEST_ON(ENERGEST_TYPE_IRQ);

      if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

    {

if(uart1_input_handler != NULL)

{

  /* Read one byte from the receive data register */

uint8_t buf = USART_ReceiveData(USART1);

uart1_input_handler(buf);

}

    }

ENERGEST_OFF(ENERGEST_TYPE_IRQ);

}


3,通过上面的处理已经把串口接收到的数据导入serial_line中了,当然串口配置初始化在这就不用多说了,接下来就是要把shell进程加入系统了:


调用serial_shell_init()函数即可


定义:


void

serial_shell_init(void)

{

  process_start(&serial_shell_process, NULL);

}

就是开启serial_shell_process进程,但是我这边新建立一个进程,用于后续其他自定义的shell命令的初始化:


#include "contiki.h"

#include "shell.h"

#include "serial-shell.h"


PROCESS(stm32_shell_process, "STM32 Contiki Shell");


PROCESS_THREAD(stm32_shell_process, ev, data)

{

    PROCESS_BEGIN();


    serial_shell_init();//初始化shell


    PROCESS_END();

}


然后再将改进程加入main函数即可,

到这边就已经完成了shell的功能,可以通过串口看见

发送 help(加回车)

这是一些默认的命令,你也可以自己定义一些命令,通过阅读shell部分的源码进一步了解原理。


4,在shell.c中可以看见关于上面打印出来的命令的定义,其实每个shell命令对应一个process,


PROCESS(help_command_process, "help");

SHELL_COMMAND(help_command, "help", "help: shows this help",

      &help_command_process);

SHELL_COMMAND(question_command, "?", "?: shows this help",

      &help_command_process);

PROCESS(shell_killall_process, "killall");

SHELL_COMMAND(killall_command, "killall", "killall: stop all running commands",

      &shell_killall_process);

PROCESS(shell_kill_process, "kill");

SHELL_COMMAND(kill_command, "kill", "kill : stop a specific command",

      &shell_kill_process);

PROCESS(shell_null_process, "null");

SHELL_COMMAND(null_command, "null", "null: discard input",

      &shell_null_process);

PROCESS(shell_exit_process, "exit");

SHELL_COMMAND(exit_command, "exit", "exit: exit shell",

      &shell_exit_process);

SHELL_COMMAND(quit_command, "quit", "quit: exit shell",

      &shell_exit_process);

PROCESS_THREAD(shell_kill_process, ev, data)

{

  struct shell_command *c;

  char *name;

  PROCESS_BEGIN();


  name = data;

  if(name == NULL || strlen(name) == 0) {

    shell_output_str(&kill_command,

     "kill : command name must be given", "");

  }



  for(c = list_head(commands);

      c != NULL;

      c = c->next) {

    if(strcmp(name, c->command) == 0 &&

       c != &kill_command &&

       process_is_running(c->process)) {

      command_kill(c);

      PROCESS_EXIT();

    }

  }


  shell_output_str(&kill_command, "Command not found: ", name);

  

  PROCESS_END();

}


5,添加自定义命令通过一下方式即可:


#include "contiki.h"

#include "shell.h"


#include "stdio.h"

#include "string.h"

#include "stm32f10x.h"


PROCESS(shell_blink_process, "shell blink");

SHELL_COMMAND(blink_command, "blink",

              "blink on/off : led on/off", &shell_blink_process);

static void

led_init()

{

    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);


    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;



    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;

    GPIO_Init(GPIOF, &GPIO_InitStructure);

}



/**

 * brief

 * param

 *

 */

static void

led_on()

{

    GPIO_SetBits(GPIOF, GPIO_Pin_7);

}


static void

led_off()

{

    GPIO_ResetBits(GPIOF, GPIO_Pin_7);

}


PROCESS_THREAD(shell_blink_process, ev, data)

{

    PROCESS_BEGIN();

    if(data != NULL)

    {

        if(strcmp(data, "on"))

        {

            led_on();

        }

        else if(strcmp(data, "off"))

        {

            led_off();

        }

        else

        {

            printf("Invalid param!n");

        }

    }



    PROCESS_END();

}


void

shell_blink_init(void)

{

    led_init();

    shell_register_command(&blink_command);

}


a,通过SHELL_COMMAND(blink_command, "blink",

              "blink on/off : led on/off", &shell_blink_process);定义shell命令;

b,通过shell_register_command(&blink_command);在shell初始化的时候一并初始化即可


推荐阅读

史海拾趣

Everbuild公司的发展小趣事

随着全球对环保和可持续发展的重视,Everbuild也将绿色环保理念融入到产品设计和生产过程中。公司采用环保材料和节能技术,减少生产过程中的污染和能源消耗。同时,Everbuild还积极参与环保公益活动,倡导绿色生活方式。这些举措不仅提高了公司的社会责任感,也为公司的可持续发展奠定了基础。

ABI Electronics公司的发展小趣事

ABI Electronics公司的起点可以追溯到其对电路板测试技术的深入研究。在创立初期,ABI便以开发出高精度、高效率的电路板故障检测仪为目标。通过对电路板测试技术的不断钻研和创新,ABI成功推出了一系列性能卓越的测试设备,这些设备不仅提高了电路板测试的准确性和效率,也极大地降低了测试成本,赢得了市场的广泛认可。

Base Two (2) Systems公司的发展小趣事

随着公司业务的不断发展壮大,Base Two (2) Systems开始实施国际化战略。公司积极拓展海外市场,与多个国家和地区的合作伙伴建立了合作关系。同时,公司还在海外设立了研发中心和生产基地,以便更好地服务全球客户。这一国际化战略的实施,使得公司的业务范围更加广泛,也为公司的未来发展打开了新的篇章。

这五个故事展示了Base Two (2) Systems在电子行业中的发展历程和取得的成就。通过技术创新、市场扩张、研发投入、品质管理和国际化战略的实施,公司逐渐发展成为电子行业中的佼佼者,为行业的发展做出了积极的贡献。

Asia Electronics Ind Co Ltd公司的发展小趣事

随着公司产品的不断成熟和市场的不断扩大,Asia Electronics Ind Co Ltd积极寻求市场拓展的机会。公司加强与国际知名企业的合作,通过参加国际电子展、建立海外销售渠道等方式,不断提升品牌知名度和影响力。同时,公司还注重品牌形象的塑造,通过统一的品牌标识、宣传资料等,增强消费者对品牌的认知度和信任度。

创都(CAX)公司的发展小趣事

在电子行业的浪潮中,创都(CAX)公司凭借其卓越的技术创新能力,逐渐崭露头角。公司创始人李先生是一位热衷于新技术的电子工程师,他带领着一支由业内顶尖人才组成的研发团队,不断挑战技术极限。在一次偶然的机会中,他们成功研发出了一款具有革命性意义的高效能芯片,这款芯片不仅性能卓越,而且成本大幅降低,迅速在市场中获得了广泛认可。随着这款芯片的成功推出,创都公司的知名度迅速提升,订单量激增,公司也借此机会逐步扩大了生产规模和市场占有率。

科达嘉CODACA公司的发展小趣事

科达嘉电子高度重视质量管理,先后通过了ISO9001质量管理体系、ISO14001环境管理体系认证。公司不仅建立了完善的质量检测流程,还成立了专门的检测中心,对产品进行严格的质量把控。这些措施确保了科达嘉电子产品的稳定性和可靠性,进一步提升了公司在市场上的竞争力。

问答坊 | AI 解惑

单片机MCS-51系列指令快速记忆法

随着微电子技术和超大规模集成电路技术的发展,单片微型计算机以其体积小、性价比 高、功能强、可靠性高等独有的特点, 在各个领域(如工业控制、家电产品、汽车电子、通信、智能仪器仪表)得到了广泛的应 用。学习、使用单片机的人越来越多, 而生 ...…

查看全部问答>

由ASIC原型校验用FPGA看高端FPGA

业界主要高端ASIC原型校验产品列表 这个表格验证了前面的初步判断,在高端领域,不论是FPGA芯片的数量,还是目标验证芯片的规模,赛灵思占有着绝对的市场地位。其中: l 在1片FPGA数量的板卡规模产品上,大部分公司既可以开发基于Altera FPGA的 ...…

查看全部问答>

拿到开发板的来这里集合

留个QQ号,大家在使用过程中遇到问题,可以交流!我们的群号是85824260 [ 本帖最后由 jxb01033016 于 2009-9-16 10:01 编辑 ]…

查看全部问答>

Vxworks下虚拟ftp客户端问题

在Vxworks下虚拟ftp客户端问题登陆到windowsFTP服务器上,通过ftpCommand(ctrlSock, \"HELP\",0, 0, 0, 0, 0, 0),或LIST、PWD等命令,请问命令执行的结果回显到哪里了? 通过这种方式发送的命令都会执行,比如MKD就可以看到创建的目录,但就是不 ...…

查看全部问答>

关于DSP下C语言的封装技术

我开发了一套控制程序。该控制程序是用C写的,并在仿真和实验室环境都验证过了。在实际的工业应用中,该程序需要运行在基于DSP的数字控制硬件系统上。根据被控对象的不同特点,用户需要能够修改参数。所以我希望能详细了解程序的封装技术,即如何能 ...…

查看全部问答>

请问下面的单片机中断延时错在哪里?

晶振是11.0592 我想得到一秒的时间         TMOD=0x01;         //定时时间50ms         TH0= -46080/256;         TL0= -46080%256;       ...…

查看全部问答>

stm8编译后生成的.map看不懂了。

stm8编译后生成的.map看不懂了。 “.const”因该是rom吧,那“.text"又是什么? “.ubsct”、“.data, initialized”、“.data, from”、“.bss”因该是ram吧,但他们有什么区别? 更奇怪的是“.debug”,它怎么从地址0开始了?它因该不会 ...…

查看全部问答>

谁帮忙编个32/64位IEEE浮点转换程序?

调试F28035的CLA时要用。网上找了一个很好用,后来再去,可用不成了---:http://jinzhi.supfree.net/…

查看全部问答>

电子信息制造业现回暖迹象

工信部 7月4日发布的数据显示,5月我国电子信息制造业内销、出口交货值增速比4月分别提高3和0.7个百分点 ,电子信息制造业有望逐步企稳回升。  1-5月,规模以上电子制造业增加值同比增长13.1%;实现销售产值31724亿元,同比增长11.2%。其中,5月 ...…

查看全部问答>