您现在的位置是:首页 > 正文

tiny4412 基础(七)移植command

2024-02-29 12:44:21阅读 1

先看效果图

这个图是在裸机下跑的,移植了u-boot的command, 新的u-boot改成cli(命令行接口)

使用起来非常方便:

static int do_version (struct cmd_tbl_s *cmd_tbl_t, int argc, int type, char * const argv[]) { puts("version : V1.0 \r\n"); return 0; } REGISTER_CMD( ver, 1, ARG_TYPE_NONE, do_version, "print monitor version" );

在任意文件里面都可以添加命令。

REGISTER_CMD宏即

#define REGISTER_CMD(name,maxargs,type,handler,usage) \
	const cmd_tbl_t cmd_##name __attribute__ ((section (".cli_cmd"))) =  {#name, maxargs, type, handler, usage}

也即REGISTER_CMD宏定义的命令最终都会链接到“.cli_cmd”段里面,在链接脚本里面:


SECTIONS
{
        . = 0x02023400;

        .text : {
                src/head.o
                * (.text)
        }

        .data : {
                * (.data)
        }

        __cli_cmd_start = .;
        .cli_cmd : {
                *(.cli_cmd)
        }
        __cli_cmd_end = .;

        bss_start = .;
        .bss : {
                * (.bss)
        }

        bss_end  = .;
}

可以看到.cli_cmd字段。

上面简单描述了效果即简单解析。

目录结构

 

.
├── basic.lds
├── common
├── HAL
│   ├── uart.c
│   └── uart.h
├── include
│   ├── system_clock.h
│   └── tiny4412.h
├── Makefile
├── src
│   ├── command.c
│   ├── command.h
│   ├── head.S
│   ├── main.c
│   └── system_clock.c
└── tools
    ├── bl2.bin
    ├── E4412_N.bl1.bin
    ├── E4412_tzsw.bin
    ├── Makefile
    ├── mkbl2
    ├── sd_fuse.sh
    └── V310-EVT1-mkbl2.c

其中basic.lds就是链接脚本,内容在上面以及贴出来了。

Makefile

CC      = /home/flinn/tools/4.5.1/bin/arm-none-linux-gnueabi-gcc
LD      = /home/flinn/tools/4.5.1/bin/arm-none-linux-gnueabi-ld
AR      = /home/flinn/tools/4.5.1/bin/arm-none-linux-gnueabi-ar
OBJCOPY = /home/flinn/tools/4.5.1/bin/arm-none-linux-gnueabi-objcopy
OBJDUMP = /home/flinn/tools/4.5.1/bin/arm-none-linux-gnueabi-objdump


CFLAGS          := -Wall -O2 -nostdlib -fno-builtin \
                -I./include \
                -I./HAL \
                -I./common \
                -I./src \
                -lgcc -L/home/flinn/tools/4.5.1/arm-none-linux-gnueabi/lib

OBJS := src/head.o src/main.o src/system_clock.o HAL/uart.o src/command.o

VER = 1.0
TARGET = tiny4412_$(VER).bin

$(TARGET): $(OBJS)
        ${LD} -Tbasic.lds -o $(TARGET)_elf $^
        ${OBJCOPY} -O binary -S $(TARGET)_elf $@
        ${OBJDUMP} -D -m arm $(TARGET)_elf > $(TARGET).dis


%.o:%.c
        ${CC} $(CFLAGS) -c -o $@ $< %.o:%.S ${CC} $(CFLAGS) -c -o $@ $< clean: rm -f $(TARGET) $(TARGET)_elf $(TARGET).dis *.o *.bin $(OBJS)

main

main很简单:

include "tiny4412.h"
#include "system_clock.h"
#include "uart.h"
#include "command.h"


int main(void)
{
        int i = 0;

        system_clock_init();

        uart_init();
        command_init();


        puts("\r\nstart...\r\n"); while (1) { command_loop(); } return 0; } 

其中需要初始化串口。

command_init()和command_loop()两个实现都在src/command.c里面

以上代码没有实现itoa,strlen, printf ,  vsprintf等标准库函数,并运行在tiny4412裸机上,对于其他平台,比如fpga,stm32, msp430, 51等平台,一般IDE支持标准库函数,移植起来更方便。熟悉u-boot移植的人来说,cli接口是必不可少的调试神器。

所有代码由以下方式获取:

git clone git@github.com:fanglinn/tiny4412.git

最后还是补充一下:
如果你想使用以上框架,需要做如下几点:

1.在Makefile里面修改你的编译器gcc路径

2.实现uart底层读写函数,必须实现putc, puts, getc, tstc四个函数,分别表示发送字符,发送字符串, 获 
  取一个字符, 监测是否有数据来

3.插入SD卡,使用sudo fdisk -l来识别,比如/dev/sdc

4.进入tools目录,执行sudo ./sd_fuse /dev/sdc 即可

最后还是贴上代码,以便自己后面使用:

src/command.c

#include "command.h"
#include "uart.h" char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */ static const char erase_seq[] = "\b \b"; /* erase sequence */ static const char tab_seq[] = " "; /* used to expand TABs */ static cmd_tbl_t * CLI_cmd_start; static cmd_tbl_t * CLI_cmd_end ; static int do_version (struct cmd_tbl_s *cmd_tbl_t, int argc, int type, char * const argv[]) { puts("version : V1.0 \r\n"); return 0; } REGISTER_CMD( ver, 1, ARG_TYPE_NONE, do_version, "print monitor version" ); int do_help(struct cmd_tbl_s *cmd, int argc, int type, char * const argv[]) { cmd_tbl_t *cmdtp; int len = CLI_cmd_end - CLI_cmd_start; for (cmdtp = CLI_cmd_start; cmdtp != CLI_cmd_start + len; cmdtp++) { puts(cmdtp->name); puts("\t"); puts(cmdtp->usage); puts("\r\n"); } return 0; } REGISTER_CMD( help, 1, ARG_TYPE_NONE, do_help, "print help information" ); char * strcpy(char * dest,const char *src) { char *tmp = dest; while ((*dest++ = *src++) != '\0') /* nothing */; return tmp; } unsigned int strlen(const char * s) { const char *sc; for (sc = s; *sc != '\0'; ++sc) /* nothing */; return sc - s; } int strcmp(const char * cs,const char * ct) { register signed char __res; while (1) { if ((__res = *cs - *ct++) != 0 || !*cs++) break; } return __res; } static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen) { char *s; if (*np == 0) { return (p); } if (*(--p) == '\t') { /* will retype the whole line */ while (*colp > plen) { puts (erase_seq); (*colp)--; } for (s=buffer; s<p; ++s) { if (*s == '\t') { puts (tab_seq+((*colp) & 07)); *colp += 8 - ((*colp) & 07); } else { ++(*colp); putc (*s); } } } else { puts (erase_seq); (*colp)--; } (*np)--; return (p); } int readline_into_buffer(const char *const prompt, char *buffer, int timeout) { char *p = buffer; char * p_buf = p; int n = 0; /* buffer index */ int plen = 0; /* prompt length */ int col; /* output column cnt */ char c; /* print prompt */ if (prompt) { plen = strlen (prompt); puts (prompt); } col = plen; for (;;) { c = getc(); /* * Special character handling */ switch (c){ case '\r': /* Enter */ case '\n': *p = '\0'; puts ("\r\n"); return p - p_buf; case '\0': /* nul */ continue; case 0x03: /* ^C - break */ p_buf[0] = '\0'; /* discard input */ return -1; case 0x15: /* ^U - erase line */ while (col > plen) { puts (erase_seq); --col; } p = p_buf; n = 0; continue; case 0x17: /* ^W - erase word */ p=delete_char(p_buf, p, &col, &n, plen); while ((n > 0) && (*p != ' ')) { p=delete_char(p_buf, p, &col, &n, plen); } continue; case 0x08: /* ^H - backspace */ case 0x7F: /* DEL - backspace */ p=delete_char(p_buf, p, &col, &n, plen); continue; default: /* * Must be a normal character then */ if (n < CONFIG_SYS_CBSIZE-2) { if (c == '\t') { /* expand TABs */ puts (tab_seq+(col&07)); col += 8 - (col&07); } else { char buf[2]; /* * Echo input using puts() to force an * LCD flush if we are using an LCD */ ++col; buf[0] = c; buf[1] = '\0'; puts(buf); } *p++ = c; ++n; } else { /* Buffer full */ putc ('\a'); } } } } int readline (const char *const prompt) { /* * If console_buffer isn't 0-length the user will be prompted to modify * it instead of entering it from scratch as desired. */ console_buffer[0] = '\0'; return readline_into_buffer(prompt, console_buffer, 0); } int parse_line (char *line, char *argv[]) { int nargs = 0; while (nargs < CONFIG_SYS_MAXARGS) { /* skip any white space */ while (isblank(*line)) ++line; if (*line == '\0') { 

转载于:https://www.cnblogs.com/Flinn6425/p/10962775.html

网站文章

  • SpringMvc整合Druid.

    SpringMvc整合Druid.SpringMvc整合Druid数据库连接池1.pom.xml添加依赖2.配置web.xml3.配置Spring4.访问监控页面5.碰到的问题 SpringMvc整合Druid数据库连接池 1.pom.xml添加依赖 com.alibaba druid ${dr

    2024-02-29 12:44:14
  • 《实用python程序设计》练习题:成绩排序

    描述 给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。 输入 第一行为n (0 &lt; n &lt; 20),表示班里的学生数目; 接下来的n行,每...

    2024-02-29 12:44:07
  • FCFS先来先服务算法C++

    FCFS简单的讲就是先到达的先服务,比如A进程3秒到达,B进程2秒到达的话,那么就让B一直执行到满足它所需的服务时间。它是非抢占式的。**

    2024-02-29 12:43:37
  • 从DDD角度来看MVC

    从DDD角度来看MVC

    DDD不是银弹,只是微服务架构下的最佳代码结构实践

    2024-02-29 12:43:26
  • ansible报错"RequestsDependencyWarning"

    报错提示ans -m ping devS/usr/lib/python2.7/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.23) or chardet (2.2.1) doesn't match a supported version! RequestsDependencyWarn...

    2024-02-29 12:43:19
  • LeetCode最长有效括号

    LeetCode: Longest Valid Parentheses问题描述Given a string containing just the characters ‘(’ and ‘)’, fi...

    2024-02-29 12:42:50
  • vue axios 兼容性处理

    项目中发现,在安卓4.3及以下的手机不支持axios的使用,主要就是无法使用promise。加上以下polyfill就可以了。 项目中安装es6-promise cnpm install es6-promise --save-dev main.js里面添加 require(&#39;es6-promise&#39;).polyfill()    转载于:https://www.c...

    2024-02-29 12:42:31
  • 交大计算机专硕 学费,从4万涨到12万?上海交通大学这个专业“太贵”,家长:供不起...

    交大计算机专硕 学费,从4万涨到12万?上海交通大学这个专业“太贵”,家长:供不起...

    从4万涨到12万?上海交通大学这个专业“太贵”,家长:供不起。目前,基本很多考生都收到了自己的大学录取通知书,那么大家在收到录取通知书后做的第一件事都是什么呢?谨慎的考生都会检查通知书上的内容,其实这...

    2024-02-29 12:42:03
  • C/C++ 面试题 指针函数和函数指针

    指针函数 指针函数:顾名思义,它的本质是一个函数,不过它的返回值是一个指针。其声明的形式如下所示: ret *func(args, ...); 其中,func是一个函数,args是形参列表,ret *...

    2024-02-29 12:41:55
  • 包过滤防火墙配置和应用

    包过滤防火墙配置和应用

    实验目的:在linux系统下,包过滤防火墙配置及其应用。 实验环境:装linux系统环境(一台:配置包过滤防火墙)和安装Windows2003系统环境(一台:作客户端)。其中一台机器(linux系统)...

    2024-02-29 12:41:47