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

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

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

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

【項(xiàng)目移植】國(guó)民技術(shù)N32G4FR開發(fā)板:RT-Thread Nano移植FinSH

電子發(fā)燒友論壇 ? 來源:未知 ? 2023-02-14 13:00 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

開發(fā)環(huán)境:

  • MDK:Keil 5.30

  • 開發(fā)板:N32G4FRML-STB 開發(fā)板

  • MCU:N32G4FRMEL7

  • RT-Thread版本:3.1.5


FinSH簡(jiǎn)介

FinSH是RT-Thread的命令行外殼(shell),提供一套供用戶在命令行的操作接口,主要用于調(diào)試、查看系統(tǒng)信息。在大部分嵌入式系統(tǒng)中,一般開發(fā)調(diào)試都使用硬件調(diào)試器和printf日志打印,在有些情況下,這兩種方式并不是那么好用。比如對(duì)于RT-Thread這個(gè)多線程系統(tǒng),我們想知道某個(gè)時(shí)刻系統(tǒng)中的線程運(yùn)行狀態(tài)、手動(dòng)控制系統(tǒng)狀態(tài)。如果有一個(gè)shell,就可以輸入命令,直接相應(yīng)的函數(shù)執(zhí)行獲得需要的信息,或者控制程序的行為。這無疑會(huì)十分方便。硬件拓?fù)浣Y(jié)構(gòu)如下圖所示:



用戶在控制終端輸入命令,控制終端通過串口、USB、網(wǎng)絡(luò)等方式將命令傳給設(shè)備里的 FinSH,F(xiàn)inSH 會(huì)讀取設(shè)備輸入命令,解析并自動(dòng)掃描內(nèi)部函數(shù)表,尋找對(duì)應(yīng)函數(shù)名,執(zhí)行函數(shù)后輸出回應(yīng),回應(yīng)通過原路返回,將結(jié)果顯示在控制終端上。


當(dāng)使用串口連接設(shè)備與控制終端時(shí),F(xiàn)inSH 命令的執(zhí)行流程,如下圖所示:



FinSH 支持權(quán)限驗(yàn)證功能,系統(tǒng)在啟動(dòng)后會(huì)進(jìn)行權(quán)限驗(yàn)證,只有權(quán)限驗(yàn)證通過,才會(huì)開啟 FinSH 功能,提升系統(tǒng)輸入的安全性。


FinSH 支持自動(dòng)補(bǔ)全、查看歷史命令等功能,通過鍵盤上的按鍵可以很方便的使用這些功能,F(xiàn)inSH 支持的按鍵如下表所示:



FinSH支持兩種模式,分別是傳統(tǒng)命令行模式和 C 語言解釋器模式:


  1. C語言解釋器模式, 為行文方便稱之為c-style;C 語言解釋器模式下,F(xiàn)inSH 能夠解析執(zhí)行大部分 C 語言的表達(dá)式,并使用類似 C 語言的函數(shù)調(diào)用方式訪問系統(tǒng)中的函數(shù)及全局變量,此外它也能夠通過命令行方式創(chuàng)建變量。在該模式下,輸入的命令必須類似 C 語言中的函數(shù)調(diào)用方式,即必須攜帶 () 符號(hào),例如,要輸出系統(tǒng)當(dāng)前所有線程及其狀態(tài),在 FinSH 中輸入 list_thread() 即可打印出需要的信息。FinSH 命令的輸出為此函數(shù)的返回值。對(duì)于一些不存在返回值的函數(shù)(void 返回值),這個(gè)打印輸出沒有意義。

  2. 傳統(tǒng)命令行模式,此模式又稱為msh(module shell)。C語言表達(dá)式解釋模式下, finsh能夠解析執(zhí)行大部分C語言的表達(dá)式,并使用類似C語言的函數(shù)調(diào)用方式訪問系統(tǒng)中的函數(shù)及全局變量,此外它也能夠通過命令行方式創(chuàng)建變量。在msh模式下,finsh運(yùn)行方式類似于dos/bash等傳統(tǒng)shell。例如,可以通過 cd / 命令將目錄切換至根目錄。msh 通過解析,將輸入字符分解成以空格區(qū)分開的命令和參數(shù)。其命令執(zhí)行格式如下所示:

command [arg1] [arg2] [...]


其中 command 既可以是 RT-Thread 內(nèi)置的命令,也可以是可執(zhí)行的文件。


最初 FinSH 僅支持 C-Style 模式,后來隨著 RT-Thread 的不斷發(fā)展,C-Style 模式在運(yùn)行腳本或者程序時(shí)不太方便,而使用傳統(tǒng)的 shell 方式則比較方便。另外,C-Style 模式下,F(xiàn)inSH 占用體積比較大。出于這些考慮,在 RT-Thread 中增加了 msh 模式,msh 模式體積小,使用方便,推薦大家使用 msh 模式。


如果在 RT-Thread 中同時(shí)使能了這兩種模式,那它們可以動(dòng)態(tài)切換,在 msh 模式下輸入 exit 后回車,即可切換到 C-Style 模式。在 C-Style 模式輸入 msh() 后回車,即可進(jìn)入 msh 模式。兩種模式的命令不通用,msh 命令無法在 C-Style 模式下使用,反之同理。


FinSH的移植分為兩個(gè)部分:第一部分是實(shí)現(xiàn) UART 控制臺(tái),該部分只需要實(shí)現(xiàn)兩個(gè)函數(shù)即可完成 UART 控制臺(tái)打印功能。第二部分是實(shí)現(xiàn)移植 FinSH 組件,實(shí)現(xiàn)在控制臺(tái)輸入命令調(diào)試系統(tǒng),該部分實(shí)現(xiàn)基于第一部分,只需要添加 FinSH 組件源碼并再對(duì)接一個(gè)系統(tǒng)函數(shù)即可實(shí)現(xiàn)。下面將對(duì)這兩部分進(jìn)行說明。


在Nano上添加UART控制臺(tái)

在 RT-Thread Nano 上添加 UART 控制臺(tái)打印功能后,就可以在代碼中使用 RT-Thread 提供的打印函數(shù) rt_kprintf() 進(jìn)行信息打印,從而獲取自定義的打印信息,方便定位代碼 bug 或者獲取系統(tǒng)當(dāng)前運(yùn)行狀態(tài)等。實(shí)現(xiàn)控制臺(tái)打印,需要完成基本的硬件初始化,以及對(duì)接一個(gè)系統(tǒng)輸出字符的函數(shù)。


2.1 串口初始化

使用串口對(duì)接控制臺(tái)的打印,首先需要初始化串口,如引腳、波特率等。需要在 board.c 中的 rt_hw_board_init() 函數(shù)中調(diào)用串口初始化。



2.2 實(shí)現(xiàn) rt_hw_console_output

實(shí)現(xiàn) finsh 組件輸出一個(gè)字符,即在該函數(shù)中實(shí)現(xiàn) uart 輸出字符:

/*輸出一個(gè)字符,系統(tǒng)函數(shù),函數(shù)名不可更改 */
void rt_hw_console_output(const char *str);

(左右移動(dòng)查看全部?jī)?nèi)容)


示例代碼:如下是基于N32G4FRMEL7的串口驅(qū)動(dòng)對(duì)接的 rt_hw_console_output() 函數(shù),實(shí)現(xiàn)控制臺(tái)字符輸出,示例僅做參考。



以上代碼很簡(jiǎn)單,就是將裸機(jī)的字符輸出的內(nèi)容使用rt_hw_console_output()函數(shù)實(shí)現(xiàn),筆者使用的是串口1作為調(diào)試串口。


注意:RT-Thread 系統(tǒng)中已有的打印均以 結(jié)尾,而并非 ,所以在字符輸出時(shí),需要在輸出 之前輸出 ,完成回車與換行,否則系統(tǒng)打印出來的信息將只有換行。


上面實(shí)現(xiàn)了rt_hw_console_output()函數(shù),也就實(shí)現(xiàn)了rt_kprintf()函數(shù),在kservice.c中調(diào)用了rt_hw_console_output()函數(shù)。



以下代碼就是在調(diào)用rt_hw_console_output()。



RT_CONSOLEBUF_SIZE定義緩沖區(qū)的最大長(zhǎng)度為,默認(rèn)配置的大小為128。



2.3 結(jié)果驗(yàn)證

在應(yīng)用代碼中編寫含有 rt_kprintf() 打印的代碼,編譯下載,打開串口助手進(jìn)行驗(yàn)證。如下圖是一個(gè)在 main() 函數(shù)中每隔 1 秒進(jìn)行循環(huán)打印 Hello RT-Thread 的示例效果:



在Nano上添加FinSH組件

RT-Thread FinSH 是 RT-Thread 的命令行組件(shell),提供一套供用戶在命令行調(diào)用的操作接口,主要用于調(diào)試或查看系統(tǒng)信息。它可以使用串口 / 以太網(wǎng) / USB 等與 PC 機(jī)進(jìn)行通信,使用 FinSH 組件基本命令的效果圖如下所示。



本文以串口 UART 作為 FinSH 的輸入輸出端口與 PC 進(jìn)行通信,描述如何在 Nano 上實(shí)現(xiàn) FinSH shell 功能。


在 RT-Thread Nano 上添加 FinSH 組件,實(shí)現(xiàn) FinSH 功能的步驟主要如下:

  1. 添加 FinSH 源碼到工程。

  2. 實(shí)現(xiàn)函數(shù)對(duì)接。

  3. 1 Keil添加 FinSH 源碼工程


把 FinSH 組件的源碼到工程。



另外還需要配置Finsh的頭文件路徑。



3.2 實(shí)現(xiàn) rt_hw_console_getchar

要實(shí)現(xiàn) FinSH 組件功能:既可以打印也能輸入命令進(jìn)行調(diào)試,控制臺(tái)已經(jīng)實(shí)現(xiàn)了打印功能,現(xiàn)在還需要在 board.c 中對(duì)接控制臺(tái)輸入函數(shù),實(shí)現(xiàn)字符輸入:

/* finsh 獲取一個(gè)字符,系統(tǒng)函數(shù),函數(shù)名不可更改 */
char rt_hw_console_getchar(void)

(左右移動(dòng)查看全部?jī)?nèi)容)


rt_hw_console_getchar():控制臺(tái)獲取一個(gè)字符,即在該函數(shù)中實(shí)現(xiàn) uart 獲取字符,可以使用查詢方式獲取(注意不要死等,在未獲取到字符時(shí),需要讓出 CPU),也可以使用中斷方式獲取。


3.2.1查詢方式

如下是基于N32G4FRMEL7的串口驅(qū)動(dòng)對(duì)接的 rt_hw_console_getchar(),完成對(duì)接 FinSH 組件,其中獲取字符采用查詢方式,示例僅做參考。

/* 移植 FinSH,實(shí)現(xiàn)命令行交互, 需要添加 FinSH 源碼,然后再對(duì)接 rt_hw_console_getchar */
char rt_hw_console_getchar(void)
{
int ch = -1;
if (USART_GetFlagStatus(USART1, USART_FLAG_RXDNE) != RESET)
{
ch = (int)USART_ReceiveData(USART1);
}
else
{
if(USART_GetFlagStatus(USART1, USART_FLAG_OREF) != RESET)
{
USART_ClrFlag(USART1,USART_FLAG_TXC);
}
rt_thread_mdelay(10);
}
return ch;
}

(左右移動(dòng)查看全部?jī)?nèi)容)


3.2.2 中斷方式

如下是基于 N32G4FRMEL7串口驅(qū)動(dòng),實(shí)現(xiàn)控制臺(tái)輸出與 FinSH Shell,其中獲取字符采用中斷方式。原理是,在 uart 接收到數(shù)據(jù)時(shí)產(chǎn)生中斷,在中斷中把數(shù)據(jù)存入 ringbuffer 緩沖區(qū),然后釋放信號(hào)量,tshell 線程接收信號(hào)量,然后讀取存在 ringbuffer 中的數(shù)據(jù)。

/* 第一部分:ringbuffer 實(shí)現(xiàn)部分 */
#include
#include


#define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb))


struct rt_ringbuffer
{
rt_uint8_t *buffer_ptr;


rt_uint16_t read_mirror : 1;
rt_uint16_t read_index : 15;
rt_uint16_t write_mirror : 1;
rt_uint16_t write_index : 15;


rt_int16_t buffer_size;
};


enum rt_ringbuffer_state
{
RT_RINGBUFFER_EMPTY,
RT_RINGBUFFER_FULL,
/* half full is neither full nor empty */
RT_RINGBUFFER_HALFFULL,
};


rt_inline enum rt_ringbuffer_state rt_ringbuffer_status(struct rt_ringbuffer *rb)
{
if (rb->read_index == rb->write_index)
{
if (rb->read_mirror == rb->write_mirror)
return RT_RINGBUFFER_EMPTY;
else
return RT_RINGBUFFER_FULL;
}
return RT_RINGBUFFER_HALFFULL;
}


/**
* get the size of data in rb
*/
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb)
{
switch (rt_ringbuffer_status(rb))
{
case RT_RINGBUFFER_EMPTY:
return 0;
case RT_RINGBUFFER_FULL:
return rb->buffer_size;
case RT_RINGBUFFER_HALFFULL:
default:
if (rb->write_index > rb->read_index)
return rb->write_index - rb->read_index;
else
return rb->buffer_size - (rb->read_index - rb->write_index);
};
}


void rt_ringbuffer_init(struct rt_ringbuffer *rb,
rt_uint8_t *pool,
rt_int16_t size)
{
RT_ASSERT(rb != RT_NULL);
RT_ASSERT(size > 0);


/* initialize read and write index */
rb->read_mirror = rb->read_index = 0;
rb->write_mirror = rb->write_index = 0;


/* set buffer pool and size */
rb->buffer_ptr = pool;
rb->buffer_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
}


/**
* put a character into ring buffer
*/
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch)
{
RT_ASSERT(rb != RT_NULL);


/* whether has enough space */
if (!rt_ringbuffer_space_len(rb))
return 0;


rb->buffer_ptr[rb->write_index] = ch;


/* flip mirror */
if (rb->write_index == rb->buffer_size-1)
{
rb->write_mirror = ~rb->write_mirror;
rb->write_index = 0;
}
else
{
rb->write_index++;
}


return 1;
}
/**
* get a character from a ringbuffer
*/
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch)
{
RT_ASSERT(rb != RT_NULL);


/* ringbuffer is empty */
if (!rt_ringbuffer_data_len(rb))
return 0;


/* put character */
*ch = rb->buffer_ptr[rb->read_index];


if (rb->read_index == rb->buffer_size-1)
{
rb->read_mirror = ~rb->read_mirror;
rb->read_index = 0;
}
else
{
rb->read_index++;
}


return 1;
}


/* 第二部分:finsh 移植對(duì)接部分 */
#define UART_RX_BUF_LEN 16
rt_uint8_t uart_rx_buf[UART_RX_BUF_LEN] = {0};
struct rt_ringbuffer uart_rxcb; /* 定義一個(gè) ringbuffer cb */
static struct rt_semaphore shell_rx_sem; /* 定義一個(gè)靜態(tài)信號(hào)量 */


/**
* [url=home.php?mod=space&uid=2666770]@Brief[/url] 配置USART接收中斷
* [url=home.php?mod=space&uid=3142012]@param[/url] uint8_t IRQChannel, uint8_t PreemptionPriority, uint8_t SubPriority
* @retval None
*/
static void BSP_USART_NVIC_Configuration(uint8_t IRQChannel, uint8_t PreemptionPriority, uint8_t SubPriority)
{
NVIC_InitType NVIC_InitStructure;


/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


/**
* @brief USART GPIO 配置
* @param ST_BSP_USART_Dev *BSP_USART_Dev, uint32_t BaudRate, uint8_t PreemptionPriority, uint8_t SubPriority
* @retval None
*/
void BSP_USART_Init(ST_BSP_USART_Dev *BSP_USART_Dev, uint32_t BaudRate, uint8_t PreemptionPriority, uint8_t SubPriority)
{
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;


/* config USART GPIO clock */
RCC_EnableAPB2PeriphClk(BSP_USART_Dev->usart_rx_gpio_clk | BSP_USART_Dev->usart_tx_gpio_clk, ENABLE);


/* config USART clock */
RCC_EnableAPB2PeriphClk(BSP_USART_Dev->usart_clk, ENABLE);


/* 初始化串口接收 ringbuffer */
rt_ringbuffer_init(&uart_rxcb, uart_rx_buf, UART_RX_BUF_LEN);


/* 初始化串口接收數(shù)據(jù)的信號(hào)量 */
rt_sem_init(&(shell_rx_sem), "shell_rx", 0, 0);


/* USART GPIO config */
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.Pin = BSP_USART_Dev->usart_tx_pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(BSP_USART_Dev->usart_tx_port, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.Pin = BSP_USART_Dev->usart_rx_pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitPeripheral(BSP_USART_Dev->usart_rx_port, &GPIO_InitStructure);


USART_DeInit(BSP_USART_Dev->usart);
/* USART mode config */
USART_InitStructure.BaudRate = BaudRate;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO ;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
USART_Init(BSP_USART_Dev->usart, &USART_InitStructure);


// 配置中斷
BSP_USART_NVIC_Configuration(BSP_USART_Dev->usart_irqn, PreemptionPriority, SubPriority);
/* 使能串口接收中斷 */
USART_ConfigInt(BSP_USART_Dev->usart, USART_INT_RXDNE, ENABLE);
//USART_ConfigInt(BSP_USART_Dev->usart, USART_INT_IDLEF, ENABLE); // 空閑中斷


USART_Enable(BSP_USART_Dev->usart, ENABLE);
}




/*輸出一個(gè)字符,系統(tǒng)函數(shù),函數(shù)名不可更改 */
void rt_hw_console_output(const char *str)
{
rt_size_t i = 0, size = 0;
char a = ' ';

/*清楚標(biāo)志位*/
USART_ClrFlag(USART1,USART_FLAG_TXC);

size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if (*(str + i) == ' ')
{
/* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到USART1 */
USART_SendData(USART1, (uint8_t) a);
/* 等待發(fā)送完畢 */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXC) == RESET);
}
/* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到USART1 */
USART_SendData(USART1, (uint8_t) *(str+i));
/* 等待發(fā)送完畢 */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXC) == RESET);
}
}


/* 移植 FinSH,實(shí)現(xiàn)命令行交互, 需要添加 FinSH 源碼,然后再對(duì)接 rt_hw_console_getchar */
/* 中斷方式 */
char rt_hw_console_getchar(void)
{
char ch = 0;


/* 從 ringbuffer 中拿出數(shù)據(jù) */
while (rt_ringbuffer_getchar(&uart_rxcb, (rt_uint8_t *)&ch) != 1)
{
rt_sem_take(&shell_rx_sem, RT_WAITING_FOREVER);
}
return ch;
}


/* 第三部分:中斷部分*/
void USART1_IRQHandler(void)
{
int ch = -1;

/* enter interrupt */
rt_interrupt_enter(); //在中斷中一定要調(diào)用這對(duì)函數(shù),進(jìn)入中斷

if( (USART_GetIntStatus(USART1, USART_INT_RXDNE) != RESET) && (USART_GetFlagStatus(USART1, USART_FLAG_RXDNE) != RESET) )
{
while (1)
{
ch = -1;
if(USART_GetIntStatus(USART1, USART_INT_RXDNE) != RESET)
{
ch = USART_ReceiveData(USART1);
}
if(ch ==-1)
{
break;
}
/* 讀取到數(shù)據(jù),將數(shù)據(jù)存入 ringbuffer */
rt_ringbuffer_putchar(&uart_rxcb, ch);
}
rt_sem_release(&shell_rx_sem);
}
/* leave interrupt */
rt_interrupt_leave(); //在中斷中一定要調(diào)用這對(duì)函數(shù),離開中斷
}

(左右移動(dòng)查看全部?jī)?nèi)容)


【注】需要確認(rèn) rtconfig.h 中已使能 RT_USING_CONSOLE 宏定義


移植完成后,將程序下載到板子中,打開串口助手,在發(fā)送去輸入字符,點(diǎn)擊發(fā)送即可進(jìn)行交互。注意一定要有換行符。



這里推薦使用xshell等工具,用起來就有種Linux終端的感覺。



FinSH實(shí)例

前文移植了FinSH,接下來我門通過一個(gè)實(shí)例來講解如果使用自定義 msh 命令。本節(jié)我們來讀取芯片閃存容量寄存器和芯片ID,寄存器地址描述如下:


  • 存儲(chǔ)器容量寄存器



  • 產(chǎn)品唯一身份標(biāo)識(shí)寄存器(96位)


產(chǎn)品唯一的身份標(biāo)識(shí)應(yīng)用如下:

  • 用來作為序列號(hào)(例如USB字符序列號(hào)或者其他的終端應(yīng)用)

  • 用來作為密碼,在編寫閃存時(shí),將此唯一標(biāo)識(shí)與軟件加解密算法結(jié)合使用,提高代碼在閃存存儲(chǔ)器內(nèi)的安全性。

  • 用來激活帶安全機(jī)制的自舉過程


96位的產(chǎn)品唯一身份標(biāo)識(shí)所提供的參考號(hào)碼對(duì)任意一個(gè)STM32微控制器,在任何情況下都是唯一的。用戶在何種情況下,都不能修改這個(gè)身份標(biāo)識(shí)。


這個(gè)96位的產(chǎn)品唯一身份標(biāo)識(shí),按照用戶不同的用法,可以以字節(jié)(8位)為單位讀取,也可以以半字(16位)或者全字(32位)。


實(shí)現(xiàn)讀取芯片閃存容量寄存器和芯片ID很簡(jiǎn)單,代碼如下:

uint32_t ChipUniqueID[3];


void GetChipID(void)
{
ChipUniqueID[0] = *(volatile uint32_t *)(0x1FFFF7F0);//ID最高位
ChipUniqueID[1] = *(volatile uint32_t *)(0x1FFFF7EC);//ID最高位
ChipUniqueID[2] = *(volatile uint32_t *)(0x1FFFF7E8);//ID最高位


rt_kprintf(" Chip ID id:0x%08X-0x%08X-0x%08X ",ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2]);
}


MSH_CMD_EXPORT(GetChipID, Get 96 bit unique chip ID);


void GetFlashCapactity(void)
{
rt_kprintf(" Chip flash capacity is:%dK ",*(volatile uint16_t *)(0x1FFFF7E0));
}


MSH_CMD_EXPORT(GetFlashCapactity, Get Chip flash capacity);

(左右移動(dòng)查看全部?jī)?nèi)容)


這里需要關(guān)注宏定義MSH_CMD_EXPORT,我們?cè)贔insh命令行中就可調(diào)用我們自定義的命令,如下所示:



從結(jié)果可以看出閃存存儲(chǔ)器容量是512K,芯片唯一序列號(hào)是:39FFDF054E42323210611451,以上結(jié)果是完全符合預(yù)期的。



本文由電子發(fā)燒友社區(qū)發(fā)布,轉(zhuǎn)載請(qǐng)注明以上來源。如需社區(qū)合作及入群交流,請(qǐng)?zhí)砑?/span>微信EEFans0806,或者發(fā)郵箱liuyong@huaqiu.com。



熱門推薦干貨好文


1、社區(qū)精選!PCB多層板設(shè)計(jì)挑戰(zhàn)賽作品集合

2、超強(qiáng)性能AI芯片,OpenHarmony多系統(tǒng)支持,可定制高性能AP(附10+開發(fā)Demo)

3、從零入門物聯(lián)網(wǎng)OH開源平臺(tái),從簡(jiǎn)單到高階項(xiàng)目,創(chuàng)客電子愛好者都愛用!

4、低成本ESP32方案,支持OpenHarmony系統(tǒng)開發(fā)(附10+項(xiàng)目樣例Demo)

5、從0到1玩轉(zhuǎn)瑞薩RA4系列開發(fā)板,教你變著花樣玩板子

6、四核64位,超強(qiáng)CPU ,看RK3568“競(jìng)”開發(fā)板DEMO!

7、人工智能也能這么玩, 簡(jiǎn)單快速入手,還能自定義AI運(yùn)算

8、業(yè)界首款!支持富設(shè)備開發(fā),OpenHarmony開發(fā)者都選它!

9、高性能雙核RISC-V,滿足大多數(shù)開發(fā),這款國(guó)產(chǎn)MCU工程師都愛


原文標(biāo)題:【項(xiàng)目移植】國(guó)民技術(shù)N32G4FR開發(fā)板:RT-Thread Nano移植FinSH

文章出處:【微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

原文標(biāo)題:【項(xiàng)目移植】國(guó)民技術(shù)N32G4FR開發(fā)板:RT-Thread Nano移植FinSH

文章出處:【微信號(hào):gh_9b9470648b3c,微信公眾號(hào):電子發(fā)燒友論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

    RISC-V單片機(jī)快速入門02,移植RT_Thread Nano系統(tǒng)

    :Sipeed Longan開發(fā)板 (5)移植參考資料:https://www.rt-thread.org/document/site/tutorial/nano/
    發(fā)表于 11-10 07:23

    FlashDB移植rt-thread nano,運(yùn)行時(shí)控制臺(tái)無輸出怎么解決?

    rt-thread標(biāo)準(zhǔn)版和HAL裸機(jī)版,移植非常成功,換成nano 3.15版,就出現(xiàn)控制臺(tái)無輸出,也無法輸入,調(diào)試時(shí)進(jìn)入死循環(huán),如圖所示 ,關(guān)閉hook也不行,請(qǐng)求指點(diǎn)。謝謝! 上傳測(cè)試代碼,用的是
    發(fā)表于 10-11 09:34

    移植最新版的rt-thread nano時(shí)程序進(jìn)入到entry就報(bào)錯(cuò),為什么?

    我在移植最新版的rt-thread nano時(shí)發(fā)現(xiàn)程序只要一進(jìn)去entry函數(shù)就直接跳到一個(gè)死循環(huán)里,我使用的編譯器是armgcc10.2版本。然而我移植舊版的
    發(fā)表于 10-09 07:17

    如何移植rt-thread到野火imx6ull開發(fā)板上?

    求助如何將rt-thread移植到野火imx6ull(coretex-A7)開發(fā)板上,官方的bsp中沒有imx6ull
    發(fā)表于 09-29 06:25

    使用RT-Thread studio 開發(fā)RT-Thread Nano項(xiàng)目的時(shí)候 串口的驅(qū)動(dòng)是要自己寫嗎?

    剛?cè)肟?。使?b class='flag-5'>RT-Thread studio 開發(fā)RT-Thread 標(biāo)準(zhǔn)項(xiàng)目的時(shí)候直接使用里邊的串口uart_dev=
    發(fā)表于 09-26 08:14

    CubeMX移植RT-Thread 3.1.5文件重復(fù)怎么解決?

    CubeMX6.7.0內(nèi)移植RT-Thread Nano3.1.5文件重復(fù),主要是兩個(gè)部分 1、 和 兩個(gè)地方重復(fù)rtconfig.h 2、shell相關(guān)的文件也會(huì)重復(fù) 和 請(qǐng)問下各位有沒有辦法可以解決這個(gè)問題的?
    發(fā)表于 09-24 07:11

    RT-Thread Nano移植后動(dòng)態(tài)創(chuàng)建線程創(chuàng)建不了怎么解決?

    RT-Thread Nano 移植后動(dòng)態(tài)創(chuàng)建線程創(chuàng)建不了,靜態(tài)可以.直接燒錄DEMO也一樣,將RT_USING_HEAP開起來,使用動(dòng)態(tài)創(chuàng)建就創(chuàng)建不起來,
    發(fā)表于 09-19 06:28

    rt-thread nano 4.1.1 finsh無法正常打開怎么解決?

    本人萌新,在官網(wǎng)下載了RT-Thread nano的下載包,根據(jù)網(wǎng)絡(luò)教程在STM32F103C8T6上進(jìn)行移植,編譯時(shí)發(fā)現(xiàn)缺少finsh_config.h,于是從
    發(fā)表于 09-11 07:17

    恩智浦MCU教程 基于MCUXpresso和FRDM-MCXA346的RT-Thread Nano移植

    本篇還是以移植RT-Thread Nano到MCUXpresso IDE為主,移植的代碼可以在nxpic.org.cn論壇搜索到。
    的頭像 發(fā)表于 08-21 09:49 ?6513次閱讀
    恩智浦MCU教程 基于MCUXpresso和FRDM-MCXA346的<b class='flag-5'>RT-Thread</b> <b class='flag-5'>Nano</b><b class='flag-5'>移植</b>

    如何移植 RT-Thread Nano 并創(chuàng)建 2 個(gè)線程?

    基于 BSP 中的 GPIO_OutputInput 演示,展示了如何移植 RT-Thread Nano 并創(chuàng)建 2 個(gè)線程。
    發(fā)表于 08-19 07:45

    RT-Thread Nano硬核移植指南:手把手實(shí)現(xiàn)VGLite圖形驅(qū)動(dòng)適配 | 技術(shù)集結(jié)

    VGLite是NXP提供的輕量級(jí)2D圖形API,本文將手把手帶你實(shí)現(xiàn)VGLite圖形驅(qū)動(dòng)適配RT-Thread。文章分為上、下兩篇,將手把手教您移植。上篇對(duì)RT-ThreadNano內(nèi)核與Fi
    的頭像 發(fā)表于 07-17 14:40 ?3234次閱讀
    <b class='flag-5'>RT-Thread</b> <b class='flag-5'>Nano</b>硬核<b class='flag-5'>移植</b>指南:手把手實(shí)現(xiàn)VGLite圖形驅(qū)動(dòng)適配 | <b class='flag-5'>技術(shù)</b>集結(jié)

    開發(fā)板暢游網(wǎng)絡(luò):RT-Thread CherryUSB 驅(qū)動(dòng) RNDIS 模塊詳解 | 技術(shù)集結(jié)

    本文通過在RT-Thread操作系統(tǒng)上,使用CherryUSB軟件包作為USBHost協(xié)議棧,驅(qū)動(dòng)AIR780E4GCat.1模塊的RNDIS功能,并成功接入lwIP網(wǎng)絡(luò)協(xié)議棧,最終在開發(fā)板上實(shí)現(xiàn)了
    的頭像 發(fā)表于 07-02 17:04 ?3264次閱讀
    讓<b class='flag-5'>開發(fā)板</b>暢游網(wǎng)絡(luò):<b class='flag-5'>RT-Thread</b> CherryUSB 驅(qū)動(dòng) RNDIS 模塊詳解 | <b class='flag-5'>技術(shù)</b>集結(jié)

    RT-Thread Nano移植后動(dòng)態(tài)創(chuàng)建線程創(chuàng)建不了怎么處理?

    RT-Thread Nano移植后動(dòng)態(tài)創(chuàng)建線程創(chuàng)建不了,靜態(tài)可以.直接燒錄DEMO也一樣,將RT_USING_HEAP開起來,使用動(dòng)態(tài)創(chuàng)建就創(chuàng)建不起來,
    發(fā)表于 06-11 06:36

    移植最新版的rt-thread nano時(shí)發(fā)現(xiàn)程序只要一進(jìn)去entry函數(shù)就直接跳到一個(gè)死循環(huán)里,為什么?

    我在移植最新版的rt-thread nano時(shí)發(fā)現(xiàn)程序只要一進(jìn)去entry函數(shù)就直接跳到一個(gè)死循環(huán)里,我使用的編譯器是armgcc10.2版本。然而我移植舊版的
    發(fā)表于 04-01 07:04

    如何將RT-Thread移植到NXP MCUXPressoIDE上

    RT-Thread默認(rèn)支持的IDE只有IAR 和 Keil, 那如何將RT-Thread移植到NXP MCUXPressoIDE上呢?本文內(nèi)容比較簡(jiǎn)單但稍有瑣碎,希望對(duì)有需要的小伙伴有所幫助。
    的頭像 發(fā)表于 02-13 10:37 ?2624次閱讀
    如何將<b class='flag-5'>RT-Thread</b><b class='flag-5'>移植</b>到NXP MCUXPressoIDE上