chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于AS32X601使用shell命令行終端詳解

安芯 ? 來源:jf_29981791 ? 作者:jf_29981791 ? 2025-12-26 15:31 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、引言

Letter shell是一個(gè)C語言編寫的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式設(shè)備。簡單來說是一個(gè)命令行交互軟件,可以讀取用戶輸入的命令,找到并執(zhí)行命令對應(yīng)的函數(shù)。本文基于國科安芯AS32A601開發(fā)板,實(shí)現(xiàn)輕量化的shell。

二、文件概述

本項(xiàng)目集成了一個(gè)輕量級串口命令行 Shell,支持通過 USART0 與主機(jī)交互,以 printf 為統(tǒng)一輸出通道。

-Shell 提供基礎(chǔ)命令( help 、 ver 、 echo 、 led ),可按需擴(kuò)展到 ADC、SPI 等外設(shè)。

目錄與文件

shell.h :Shell 對外 API 與類型。

shell.c :Shell 核心實(shí)現(xiàn)(輸入緩沖、命令解析、調(diào)度)。

shell_cmds.c :示例命令注冊與實(shí)現(xiàn)。

print.c :將 printf 輸出重定向到 USART0 。

main.c :Shell 初始化與主循環(huán)集成。

serial_cli.ps1 :Windows 交互腳本,便捷串口調(diào)試。

2.1****shell.c

#include "shell.h"

#include

#include

#include

/* RX ring buffer */

static****volatile uint8_t rx_buf[256];

static****volatile uint16_t rx_head = 0; /* write index */

static****volatile uint16_t rx_tail = 0; /* read index */

/* Line buffer */

static****char line_buf[SHELL_MAX_LINE];

static uint16_t line_len = 0;

/* Command registry */

static****const ShellCmd *cmd_table[8];

static****int cmd_table_count[8];

static****int table_used = 0;

void shell_init(void (writer)(**const***char** *buf, int len)) {

rx_head = rx_tail = 0;

line_len = 0;

table_used = 0;

( void )writer; /* output uses printf directly */

}

void shell_register(const ShellCmd *cmds, int count) {

__asm volatile ("fence.i");

if (!cmds || count <= 0) return ;

if (table_used < ( int )( sizeof (cmd_table)/ sizeof (cmd_table[0]))) {

cmd_table[table_used] = cmds;

cmd_table_count[table_used] = count;

table_used++;

}

}

void shell_input_byte(uint8_t b) {

uint16_t next = (uint16_t)((rx_head + 1) & 0xFF);

if (next == rx_tail) {

/* overflow, drop byte */

return ;

}

rx_buf[rx_head] = b;

rx_head = next;

}

static****int tokenize(char *line, char **argv, int max_args) {

int argc = 0;

char *p = line;

while (*p && argc < max_args) {

while (*p == ' ' || *p == 't') p++;

if (!*p) break ;

argv[argc++] = p;

while (*p && *p != ' ' && *p != 't') p++;

if (!*p) break ;

*p++ = '?';

}

return argc;

}

static****void print_prompt( void ) {

printf("rn> ");

}

static****int dispatch(int argc, char **argv) {

if (argc <= 0) return 0;

const****char *name = argv[0];

__asm volatile ("fence.i");

if (strcmp(name, "help") == 0) {

printf("Commands:rn");

for (int t = 0; t < table_used; ++t) {

for (int i = 0; i < cmd_table_count[t]; ++i) {

const ShellCmd *c = &cmd_table[t][i];

printf(" %s - %srn", c->name, c->desc ? c->desc : "");

__asm volatile ("fence.i");

}

}

return 0;

}

for (int t = 0; t < table_used; ++t) {

for (int i = 0; i < cmd_table_count[t]; ++i) {

const ShellCmd *c = &cmd_table[t][i];

if (strcmp(name, c->name) == 0) {

return c->handler(argc, argv);

}

}

}

printf("Unknown command: %srn", name);

return -1;

}

void shell_poll( void ) {

/* Read bytes from ring and build lines */

while (rx_tail != rx_head) {

uint8_t b = rx_buf[rx_tail];

rx_tail = (uint16_t)((rx_tail + 1) & 0xFF);

if (b == 'r') {

/* ignore CR */

continue ;

}

if (b == 'n') {

/* complete line */

line_buf[line_len] = '?';

char *argv[SHELL_MAX_ARGS];

int argc = tokenize(line_buf, argv, SHELL_MAX_ARGS);

if (argc > 0) {

( void )dispatch(argc, argv);

}

line_len = 0;

print_prompt();

continue ;

}

if (b == 'b' || b == 0x7F) {

/* backspace */

if (line_len > 0) line_len--;

continue ;

}

if (line_len < SHELL_MAX_LINE - 1) {

line_buf[line_len++] = ( char )b;

} else {

/* truncate on overflow */

}

}

}

主要函數(shù)分析

**1. **初始化函數(shù)

void shell_init(void (*writer)(const char *buf, int len));

  • 初始化緩沖區(qū)指針
  • writer 參數(shù)當(dāng)前未使用(直接使用 printf)

**2. **命令注冊函數(shù)

void shell_register(const ShellCmd *cmds, int count);

  • 注冊一組命令
  • fence.i 指令:RISC-V 內(nèi)存屏障,確保指令緩存一致性

**3. **字節(jié)輸入處理

void shell_input_byte(uint8_t b);

  • 從串口接收單個(gè)字節(jié)
  • 存入環(huán)形緩沖區(qū)
  • 處理緩沖區(qū)溢出(丟棄字節(jié))

**4. **主輪詢函數(shù)

void shell_poll(void);

核心處理邏輯

  • 從環(huán)形緩沖區(qū)讀取字節(jié)
  • 處理特殊字符:
  • 普通字符存入行緩沖區(qū)
  • 行完成后,分詞并調(diào)度執(zhí)行

**5. **分詞函數(shù)

static int tokenize(char *line, char **argv, int max_args);

  • 空格/制表符分割命令行
  • 支持最大 SHELL_MAX_ARGS 個(gè)參數(shù)
  • 原地修改字符串(添加 ? 終止符)

**6. **命令分發(fā)

static int dispatch(int argc, char **argv);

  • 內(nèi)置 help 命令:顯示所有注冊命令
  • 遍歷所有命令表查找匹配命令
  • 調(diào)用對應(yīng)的 handler 函數(shù)

2.2 ** shell_cmds.c**

用戶可在該文件中定義函數(shù),并注冊到命令列表中

#include "shell.h"

#include "led.h"

#include

#include

static****int cmd_ver(int argc, char **argv) {

( void )argc; ( void )argv;

printf("AS32X601 usart_eflash shell v0.1rn");

return 0;

}

static****int cmd_echo(int argc, char **argv) {

for (int i = 1; i < argc; ++i) {

printf("%s%s", argv[i], (i == argc - 1) ? "" : " ");

}

printf("rn");

return 0;

}

static****int cmd_led(int argc, char **argv) {

if (argc < 3) {

printf("Usage: led <1|2|3>rn");

return -1;

}

int idx = argv[2][0] - '0';

if (idx < 1 || idx > 3) {

printf("Invalid LED index: %srn", argv[2]);

return -1;

}

int toggle = (strcmp(argv[1], "toggle") == 0);

int on = (strcmp(argv[1], "on") == 0);

int off = (strcmp(argv[1], "off") == 0);

if (!(toggle || on || off)) {

printf("Invalid action: %srn", argv[1]);

return -1;

}

switch (idx) {

case 1:

if (toggle) LED1_TOGGLE(); else****if (on) LED1_ON(); else****if (off) LED1_OFF();

break ;

case 2:

if (toggle) LED2_TOGGLE(); else****if (on) LED2_ON(); else****if (off) LED2_OFF();

break ;

case 3:

if (toggle) LED3_TOGGLE(); else****if (on) LED3_ON(); else****if (off) LED3_OFF();

break ;

default :

break ;

}

printf("led %s %drn", argv[1], idx);

return 0;

}

static****const ShellCmd default_cmds[] = {

{"ver", "Show shell version", cmd_ver},

{"echo", "Echo back arguments", cmd_echo},

{"led", "Control LEDs: led <1|2|3>", cmd_led},

};

void shell_cmds_init( void ) {

shell_register(default_cmds, ( int )( sizeof (default_cmds)/ sizeof (default_cmds[0])));

}

void shell_info()

{

printf("rn");

printf("rn");

printf (" _ _ _ _ _ _ rn");

printf( "| | _* | | | |* ___ _ __ _| | ___| | |rn");

printf("| | / _ __| / _ ' | / _| ' / _ | |rn");

printf("| |__| __/ |_| || **/ | ** | | | __/ | |rn");

printf("| | | | | | * * / | |* |* * | |* |rn");

printf ("rn");

printf("rn");

printf("Version: 0.1n");

printf("Board: AS32X601n");

printf("Build: " DATE " " TIME "n");

printf("n");

}

  1. 版本信息命令

static int cmd_ver(int argc, char **argv)

  • 顯示固件版本信息

2.回顯命令

static int cmd_echo(int argc, char **argv)

  • 打印所有參數(shù)(argv[0] 是命令名本身)
  • 正確處理參數(shù)間的空格

3. ** LED **控制命令

static int cmd_led(int argc, char **argv)

  • 完整的參數(shù)驗(yàn)證 :參數(shù)數(shù)量、范圍、合法性
  • 清晰的錯誤提示
  • 執(zhí)行反饋 :操作成功后打印確認(rèn)信息

**4. **命令表定義

static const ShellCmd default_cmds

  • 結(jié)構(gòu)清晰:命令名、描述、處理函數(shù)
  • 包含使用示例(led命令)

**5. **初始化函數(shù)

void shell_cmds_init(void)

  • 自動計(jì)算命令數(shù)量,避免硬編碼
  • 提供清晰的模塊初始化接口

2.3 main.c****部分流程

shell_init(NULL);

shell_cmds_init();

shell_info();

printf("AS32X601 shell readyrnType 'help' to list commands.rn> ");

while (1)

{

if (SET == USART_GetFlagStatus(USART0, USART_FLAG_RXFNE))

{

usart_data = USART_ReceiveData(USART0);

ClearCache();

/* feed incoming byte to shell */

shell_input_byte(usart_data);

}

/* process any pending input and run commands */

shell_poll();

}

輸入路徑:串口接收中斷或輪詢將字節(jié)喂給 shell_input_byte ,Shell維護(hù)環(huán)形緩沖與狀態(tài)機(jī)。

解析執(zhí)行:按行解析命令,匹配已注冊的命令表或函數(shù)指針,執(zhí)行對應(yīng)處理例程。

主循環(huán):周期性調(diào)用 shell_poll 以處理緩沖區(qū)中的數(shù)據(jù)與命令

三、開發(fā)板驗(yàn)證:

該項(xiàng)目實(shí)現(xiàn)通過串口分別控制led 1,2,3翻轉(zhuǎn)和回顯功能

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 命令行
    +關(guān)注

    關(guān)注

    0

    文章

    82

    瀏覽量

    10740
  • Shell
    +關(guān)注

    關(guān)注

    1

    文章

    374

    瀏覽量

    25279
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    命令行阿里千問搭建過程

    克隆千問倉庫,安裝依賴; 下載模型權(quán)重; 命令行執(zhí)行啟動腳本,配置參數(shù)后運(yùn)行推理。
    發(fā)表于 12-24 10:35

    AS32X601的I2C模塊操作EEPROM詳解

    國科安芯推出的AS32X601系列MCU芯片內(nèi)置的I2C模塊提供了符合工業(yè)標(biāo)準(zhǔn)的兩線串行制接口,可用于MCU和外部I2C設(shè)備的通訊。I2C總線使用兩條串行線:串行數(shù)據(jù)線SDA和串行時(shí)鐘線SCL
    的頭像 發(fā)表于 12-21 21:39 ?499次閱讀
    <b class='flag-5'>AS32X601</b>的I2C模塊操作EEPROM<b class='flag-5'>詳解</b>

    基于 AS32X601 微控制器的定時(shí)器模塊(TIM)技術(shù)研究與應(yīng)用實(shí)踐

    摘要: 本文全面介紹了國科安芯推出的AS32X601系列微控制器的定時(shí)器模塊(TIM),包括其系統(tǒng)架構(gòu)、功能特性、應(yīng)用場景以及工程實(shí)踐要點(diǎn)。通過對芯片的詳細(xì)分析,揭示了其高性能運(yùn)行的基礎(chǔ)。本文詳細(xì)
    的頭像 發(fā)表于 08-19 16:44 ?738次閱讀

    AS32X601芯片F(xiàn)lash擦寫調(diào)試技術(shù)解析

    本文聚焦于 國科安芯推出的AS32X601 芯片的 Flash 擦寫調(diào)試工作,深入剖析其片內(nèi) Flash 存儲器架構(gòu),詳述 Flash 控制器功能與運(yùn)作機(jī)制。通過對 Flash 指令集的解讀,梳理
    的頭像 發(fā)表于 07-22 13:47 ?636次閱讀
    <b class='flag-5'>AS32X601</b>芯片F(xiàn)lash擦寫調(diào)試技術(shù)解析

    USB串行配置實(shí)用程序是否有可用的命令行版本?

    USB串行配置實(shí)用程序是否有可用的命令行版本?
    發(fā)表于 07-22 08:09

    【RA-Eco-RA6M4開發(fā)板評測】移植shell實(shí)現(xiàn)命令交互

    /XLmbJn0SKoDT1aLdxHDrbg 一個(gè)超級精簡高可移植的shell命令行C實(shí)現(xiàn)二. 移植移植參考上述文章,很簡單只需要實(shí)現(xiàn)輸入輸出接口 即可。代碼見shell.c/h shell
    發(fā)表于 07-19 22:47

    淺談wsl --update` 命令行選項(xiàng)無效的解決方案

    PS C:\Users\Administrator> wsl --update >> 命令行選項(xiàng)無效: --update
    的頭像 發(fā)表于 06-27 10:28 ?1.1w次閱讀

    AS32X601驅(qū)動系列教程 GPIO_點(diǎn)亮LED詳解

    的大門。自本章開始,正式開始用代碼控制AS32x601各外設(shè)完成功能配置。 需要注意的是,AS32X601提供了8組GPIO,其中GPIOA~GPIOG寄存器操作完全一致,但在使用GPIOH的時(shí)候,寄存器列表中間少了一個(gè)32位寄存器,因此在使用過程中容易造成誤操作,我們在
    的頭像 發(fā)表于 05-23 16:14 ?660次閱讀
    <b class='flag-5'>AS32X601</b>驅(qū)動系列教程 GPIO_點(diǎn)亮LED<b class='flag-5'>詳解</b>

    AS32X601驅(qū)動系列教程 SMU_系統(tǒng)時(shí)鐘詳解

    時(shí)鐘和復(fù)位的管理。在默認(rèn)狀態(tài)下SMU工作在IDLE狀態(tài)。只有接收到PMU的使能信號后才開始工作。SMU模塊會根據(jù)PMU的指令自動配置COR、AXIBUS0/1/2等總線的時(shí)鐘和復(fù)位。 需要注意的是,MCU芯片AS32X601可通過BOOT選擇從外部QSPI Flash啟動和內(nèi)部PFlash啟動,
    的頭像 發(fā)表于 05-23 16:01 ?650次閱讀
    <b class='flag-5'>AS32X601</b>驅(qū)動系列教程 SMU_系統(tǒng)時(shí)鐘<b class='flag-5'>詳解</b>

    aurix development studio無法用命令行編譯工程的原因?

    aurix development studio無法用命令行編譯工程
    發(fā)表于 04-18 06:50

    樹莓派新手必看!在樹莓派上編寫和運(yùn)行 Shell 腳本!

    在本教程中,我將討論Shell腳本的基礎(chǔ)知識、它們的用途以及如何在RaspberryPi上編寫和運(yùn)行Shell腳本。什么是Shell腳本?Shell腳本可以讓你自動化幾乎所有在Linu
    的頭像 發(fā)表于 03-25 09:28 ?1041次閱讀
    樹莓派新手必看!在樹莓派上編寫和運(yùn)行 <b class='flag-5'>Shell</b> 腳本!

    AS32X601芯片技術(shù)剖析

    芯片簡介 AS32X601系列MCU是國產(chǎn)高可靠嵌入式處理器的重要突破,其企業(yè)宇航級型號AS32S601針對空間輻射環(huán)境與極端溫度條件優(yōu)化,滿足衛(wèi)星載荷控制、航天器運(yùn)動控制等場景需求。該芯片采用
    的頭像 發(fā)表于 03-14 16:17 ?972次閱讀

    AS32X601雙核鎖步MCU技術(shù)優(yōu)勢分析

    AS32X601是國科安芯公司研制的一系列基于32位RISC-V指令集車規(guī)級MCU處理器芯片。主頻高達(dá)180MHz,支持雙核鎖步架構(gòu),基于軟錯誤防護(hù)技術(shù)加持,顯著提高芯片安全性能。產(chǎn)品具有高安全、低
    的頭像 發(fā)表于 03-07 16:12 ?869次閱讀

    【ELF 2學(xué)習(xí)板試用】命令行功能測試-shell腳本進(jìn)行IO控制-燈閃

    文件 有2方式調(diào)試硬件 命令行功能測試和桌面功能測試 我準(zhǔn)備在Linux5.10主板命令行啟動后網(wǎng)絡(luò)SSH 下用shell腳本進(jìn)行控制部分硬件測試。從IO控制-燈閃開始。 ELF 2開發(fā)板快速啟動手冊中
    發(fā)表于 01-25 15:30

    curl wget bond:深入解析命令行工具的差異與應(yīng)用場景

    curl curl 是一個(gè)用于與服務(wù)器進(jìn)行數(shù)據(jù)傳輸?shù)?b class='flag-5'>命令行工具。它支持多種協(xié)議,包括 HTTP、HTTPS、 FTP 等。 基本用法 獲取網(wǎng)頁內(nèi)容: curl http://example.com
    的頭像 發(fā)表于 01-24 09:20 ?855次閱讀