飛凌 OK536x-C 平臺 FreeRTOS 應(yīng)用部署指南
Forlinx
2025-10-29 19:11:00
t536
536開發(fā)板
全志t536
本文基于飛凌嵌入式 OK536x-C 平臺官方技術(shù)資料、全志科技 T536 芯片規(guī)格書整理編寫,聚焦 RISCV 核的系統(tǒng)架構(gòu)、內(nèi)核初始化流程及自定義應(yīng)用部署,所有核心邏輯均匹配平臺官方定義,數(shù)據(jù)及技術(shù)細節(jié)經(jīng)原廠驗證,可作為工程師開發(fā)適配的實操參考文檔。飛凌 OK536x-C 開發(fā)板亮點 采用全志 T536 工業(yè)級SoC,四核 Cortex-A55 + 單核 RISC-V 異構(gòu)架構(gòu),A55 主頻 1.6 GHz,RISC-V 實時核獨立運行 FreeRTOS,整板工業(yè)級寬溫設(shè)計。若您正在尋找“Linux + 實時核”同時落地的量產(chǎn)級方案,OK536x-C 幾乎是不二之選。
本指南核心適配飛凌 OK536x-C 硬件平臺,且基于 Linux5.10 操作系統(tǒng)環(huán)境;其他基于 T536 芯片的硬件平臺可參考本指南的流程框架,但需注意不同廠家在 GPIO 引腳定義、串口配置、外設(shè)驅(qū)動適配等硬件設(shè)計上的差異,需結(jié)合自身平臺手冊進行修改調(diào)整。
系統(tǒng)架構(gòu):RISCV 核與 FreeRTOS
OK536x-C 平臺的 T536 RISCV 核默認集成 FreeRTOS 實時操作系統(tǒng),核心技術(shù)特性符合 FreeRTOS 官方標(biāo)準(zhǔn),具體如下:
- 搶占式調(diào)度機制:基于任務(wù)優(yōu)先級調(diào)度,高優(yōu)先級任務(wù)可主動中斷低優(yōu)先級任務(wù),保障實時事件響應(yīng)效率。
- 模塊化可裁剪:支持根據(jù)項目需求選擇性啟用 / 關(guān)閉內(nèi)核模塊(如內(nèi)存管理、內(nèi)核對象),優(yōu)化系統(tǒng)資源占用。
- 輕量化設(shè)計:內(nèi)核代碼精簡,僅需少量 RAM/ROM 即可運行,適配嵌入式設(shè)備資源受限場景。
- 多任務(wù)并發(fā)支持:提供標(biāo)準(zhǔn)化任務(wù)創(chuàng)建、刪除、掛起 / 恢復(fù)接口,滿足復(fù)雜業(yè)務(wù)邏輯需求。
- 豐富內(nèi)核同步通信組件:內(nèi)置信號量、隊列、互斥量、事件組等,實現(xiàn)任務(wù)間同步與數(shù)據(jù)交互。
- 靈活內(nèi)存管理策略:支持靜態(tài)內(nèi)存分配(編譯時確定大?。?、動態(tài)堆分配(運行時申請),適配不同內(nèi)存管理需求。
內(nèi)核初始化流程(含核心代碼框架)
T536 RISCV 核的啟動初始化圍繞三個核心函數(shù) / 任務(wù)展開,以下為關(guān)鍵初始化邏輯及代碼框架,僅保留 "決定流程成敗、需手動關(guān)注" 的核心部分,剔除平臺固化的底層驅(qū)動實現(xiàn):
4.1 start_kernel 函數(shù):RISCV 核啟動入口
函數(shù) void start_kernel(void) 是目前能夠找到的最先開始執(zhí)行的函數(shù),里面對RISCV核以及FreeRTOS系統(tǒng)做了初始化,并開啟了一個 void cpu0_app_entry(void \*) 任務(wù),最后打開FreeRTOS調(diào)度器,開始運行FreeRTOS。
void start_kernel(void)
{
portBASE_TYPE ret;
#ifdef CONFIG_COMPONENTS_STACK_PROTECTOR
//void stack_protector_init(void);
//stack_protector_init();
#endif
// 初始化Dcache、Icache等
extern void hardware_config(void);
hardware_config();
// 空函數(shù),沒有實際作用
systeminit();
// 不執(zhí)行
#ifdef CONFIG_COMPONENTS_CERTIFICATION_60730
extern int aw_startup_check_entry(void);
#if 0
extern void aw_check_set_test_break_point(unsigned char value);
aw_check_set_test_break_point(1);
#endif
aw_startup_check_entry();
#endif
/* Init heap */
heap_init();
#ifdef CONFIG_COMPONENTS_PM
pm_devops_init();
pm_syscore_init();
#endif
// 和多核處理有關(guān)(Open Asymmetric Multi-Processing)
#ifdef CONFIG_AMP_SHARE_IRQ
openamp_share_irq_early_init();
#endif
/* Init hardware devices */
prvSetupHardware();
// 注冊multi_console
// 暫時不知道m(xù)ulti_console具體的作用是什么
#ifdef CONFIG_MULTI_CONSOLE
extern int multiple_console_early_init(void);
multiple_console_early_init();
#endif
// 打印啟動信息
/* Setup kernel components */
print_banner();
// 設(shè)置標(biāo)準(zhǔn)輸入輸出
setbuf(stdout, 0);
setbuf(stdin, 0);
setvbuf(stdin, NULL, _IONBF, 0);
#ifdef CONFIG_COMPONENT_CPLUSPLUS
/* It should be called after the stdout is ready, otherwise the std:cout can't work */
int cplusplus_system_init(void);
cplusplus_system_init();
#endif
#ifdef CONFIG_ARCH_HAVE_ICACHE
hal_icache_init();
printf("init Icache\n");
#endif
#ifdef CONFIG_ARCH_HAVE_DCACHE
hal_dcache_init();
printf("init Dcache\n");
#endif
#ifdef CONFIG_DRIVERS_HWSPINLOCK
hal_hwspinlock_init();
#endif
#ifdef CONFIG_DRIVERS_WATCHDOG
hal_watchdog_init();
#endif
#ifdef CONFIG_DRIVERS_MSGBOX
hal_msgbox_init();
#endif
start_kernel_flag = 0;
#ifdef CONFIG_COMPONENTS_AMP_HW_WATCHDOG
extern int amp_hw_wdog_init(void);
amp_hw_wdog_init();
#endif
#ifdef CONFIG_COMPONENTS_AMP_TIMESTAMP
extern int amp_timestamp_init(void);
amp_timestamp_init();
#endif
// 添加cpu0_app_entry任務(wù)到FreeRTOS內(nèi)部的任務(wù)池中
extern void cpu0_app_entry(void *);
ret = xTaskCreate(cpu0_app_entry, "init-thread-0", 1024, NULL, 31, NULL);
if (ret != pdPASS)
{
printf("Error creating task, status was %d\n", ret);
while (1);
}
// 打開FreeRTOS調(diào)度器
vTaskStartScheduler();
}
4.2 cpu0_app_entry 任務(wù):核心業(yè)務(wù)初始化
cpu0_app_entry 主要做了以下工作:
- 開啟OpenAMP的初始化進程 openamp_init_thread;
- 打開FreeRTOS命令行 vCommandConsoleStart(0x1000, HAL_THREAD_PRIORITY_CLI, NULL)。
svoid cpu0_app_entry(void *param)
{
(void)param;
#ifdef CONFIG_COMPONENTS_PM
pm_init(1, NULL);
#endif
#ifdef CONFIG_COMPONENTS_OPENAMP
void *thread;
thread = hal_thread_create(openamp_init_thread, NULL, "amp_init", 8 * 1024, HAL_THREAD_PRIORITY_SYS);
if (thread != NULL)
hal_thread_start(thread);
#endif
#ifdef CONFIG_COMPONENT_CLI
vCommandConsoleStart(0x1000, HAL_THREAD_PRIORITY_CLI, NULL);
#endif
#ifdef COMMAND_AUTO_START_MEMTESTER
void *autotest_thread;
autotest_thread = hal_thread_create(auto_memtester_thread, NULL, "auto_memtester", 8 * 1024, HAL_THREAD_PRIORITY_SYS);
if (autotest_thread != NULL)
hal_thread_start(autotest_thread);
#endif
vTaskDelete(NULL);
}
4.3 vCommandConsoleStart 函數(shù):CLI 初始化與任務(wù)創(chuàng)建
函數(shù) vCommandConsoleStart 的作用是初始化命令行界面(CLI,Command Line Interface),并且啟動對應(yīng)的任務(wù) prvUARTCommandConsoleTask。CLI使用的串口通過 CONFIG_CLI_UART_PORT 定義來決定。
void vCommandConsoleStart( uint16_t usStackSize, portBASE_TYPE uxPriority, void * console)
{
#if !defined(CONFIG_DISABLE_ALL_UART_LOG)
/* A UART is used for printf() output and CLI input and output. Note there
is no mutual exclusion on the UART, but the demo as it stands does not
require mutual exclusion. */
TaskHandle_t cli_task = NULL;
prvConfigureUART(console);
vRegisterSampleCLICommands();
portBASE_TYPE ret;
/* Create that task that handles the console itself. */
ret = xTaskCreate(prvUARTCommandConsoleTask, /* The task that implements the command console. */
"CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */
usStackSize, /* The size of the stack allocated to the task. */
NULL, /* The parameter is not used, so NULL is passed. */
uxPriority, /* The priority allocated to the task. */
&cli_task); /* A handle is not required, so just pass NULL. */
if (ret != pdPASS) {
printf("Error creating console task, status was %d\n", (int)ret);
}
#ifdef CONFIG_COMPONENTS_MULTI_CONSOLE
cli_task_set_console(cli_task, console);
#endif
#endif
}
RISCV 核啟動信息打印規(guī)則
[5.800] [5.800] ************************************************************ [5.802] ** Welcome to T536_E907 FreeRTOS V1.6.0 ** [5.803] ** Copyright (C) 2019-2021 AllwinnerTech ** [5.805] ** ** [5.809] ** starting riscv FreeRTOS ** [5.814] ************************************************************ [5.819] [5.819]Date:Feb 13 2025, Time:17:50:53 [5.823]init Icache [5.825]init Dcache [5.826]AMP timestamp device 0 probe success, count_freq: 24000000Hz [5.832]amp_hw_wdog_feed_thread enter, feed_interval: 100ms, feed_interval_tick: 100 [5.840]AMP hardware watchdog's new timeout: 2s [5.844]Begin to feed AMP hardware watchdog! [5.848]pm_client_init end!!! FreeRTOS command server. Type Help to view a list of registered commands. >[5.858][RV] [AMP_INFO][openamp_platform_init:168]rproc0 init [5.864][RV] [AMP_INFO][rproc_common_mmap:128]remoteproc mmap pa: 0x60050db0, da: 0xffffffff, size = 0xc8 [5.874][RV] [AMP_INFO][rproc_common_mmap:199]map pa(0x60050db0) to va(0x60050db0) [5.882][RV] [AMP_INFO][rproc_common_mmap:128]remoteproc mmap pa: 0x42400000, da: 0x42400000, size = 0x40000 [5.892][RV] [AMP_INFO][rproc_common_mmap:199]map pa(0x42400000) to va(0x42400000) [5.900][RV] [AMP_INFO][rproc_common_mmap:128]remoteproc mmap pa: 0xffffffff, da: 0x42440000, size = 0x1406 [5.911][RV] [AMP_INFO][rproc_common_mmap:199]map pa(0x42440000) to va(0x42440000) [5.919][RV] [AMP_INFO][rproc_common_mmap:128]remoteproc mmap pa: 0xffffffff, da: 0x42442000, size = 0x1406 [5.929][RV] [AMP_INFO][rproc_common_mmap:199]map pa(0x42442000) to va(0x42442000) [5.937][RV] [AMP_INFO][openamp_sunxi_create_rpmsg_vdev:365]Wait connected to remote master [5.946][RV] [AMP_INFO][openamp_sunxi_create_rpmsg_vdev:371]Connecte to remote master Successed [5.955][RV] [AMP_INFO][openamp_platform_init:219]rproc0 init done [5.961][RV] [AMP_INFO][openamp_platform_init:168]rproc0 init [5.968][RV] [AMP_INFO][openamp_platform_init:178]rproc0 already init. [5.975][RV] [AMP_INFO][openamp_ept_open:388]Waiting for ept('sunxi,rpmsg_ctrl') ready uart>[5.984][RV] [AMP_INFO][openamp_ept_open:393]ept('sunxi,rpmsg_ctrl') ready! src: 0x400, dst: 0x400 [5.993]rpmsg ctrldev: Start Running... [5.997][RPBUF_INFO][rpbuf_init_service:154]Waiting for rpbuf ept('rpbuf-service') ready. [6.005][RV] [AMP_INFO][openamp_platform_init:168]rproc0 init [6.011][RV] [AMP_INFO][openamp_platform_init:178]rproc0 already init. [6.018][RV] [AMP_INFO][openamp_ept_open:388]Waiting for ept('sunxi,rpmsg_heartbeat') ready [6.047][RPBUF_INFO][rpbuf_init_service:160]rpbuf ept('rpbuf-service') ready! src: 0x401, dst: 0x401 cpu> cpu>
自定義應(yīng)用部署:GPIO 控制示例
如果需要在RISCV核啟動之后,直接運行自己的應(yīng)用,而不通過CLI去調(diào)用,可以在 start_kernel 或者 cpu0_app_entry 中加入自己的應(yīng)用。這里以啟動一個GPIO控制應(yīng)用為例,介紹如何編寫一個簡單的GPIO應(yīng)用,并且將它放到FreeRTOS的任務(wù)池中。
6.1 步驟 1:編寫 GPIO 控制任務(wù)函數(shù)
我們在gpio應(yīng)用中編寫一個簡單的測試函數(shù)。注意返回值和參數(shù)要和示例中保持一致,否則FreeRTOS無法正常創(chuàng)建對應(yīng)的任務(wù)。
void hjl_test_gpio_output(void *param)
{
gpio_pin_t pin;
gpio_data_t data;
hal_gpio_pinmux_set_function(239, GPIO_MUXSEL_OUT);
hal_gpio_set_pull(239, GPIO_PULL_UP);
hal_gpio_set_direction(239, GPIO_DIRECTION_OUTPUT);
hal_gpio_set_data(239, 0);
while (1) {
hal_gpio_set_data(239, 0);
hal_sleep(2);
hal_gpio_set_data(239, 1);
hal_sleep(2);
}
6.2 步驟 2:將 GPIO 任務(wù)添加到任務(wù)池
void start_kernel(void)
{
......
extern void cpu0_app_entry(void *);
ret = xTaskCreate(cpu0_app_entry, "init-thread-0", 1024, NULL, 31, NULL);
if (ret != pdPASS)
{
printf("Error creating task, status was %d\n", ret);
while (1);
}
// 添加的自己的測試應(yīng)用
extern void hjl_test_gpio_output(void *);
ret = xTaskCreate(hjl_test_gpio_output, "gpio_app", 1024, NULL, 31, NULL);
if (ret != pdPASS)
{
printf("Error creating task hjl_test_gpio_output, status was %d\n", ret);
while (1);
}
vTaskStartScheduler();
}
6.3 步驟 3:編譯與驗證
修改完成后對源碼進行全編譯并燒錄到系統(tǒng)里,按照手冊啟動RISCV核,可以看到LEDC會開始閃爍,代表應(yīng)用啟動成功。
飛凌OK536x-C開發(fā)板實物參考圖
相關(guān)產(chǎn)品 >
-
FET536-C核心板
了解詳情基于全志T536工業(yè)級處理器的FET536-C全國產(chǎn)核心板。該核心板的開發(fā)設(shè)計充分利用了T536處理器的性能優(yōu)勢。T536處理器的主頻為1.6GHz,集成了四核Cortex-A55以及64位玄鐵E907 RISC-V MCU,能夠提供高效的計算能力。此外,T536還支持2TOPS NPU、安全啟動、國密算法IP、全通路ECC、AMP、Linux-RT等功能。T536還配備了廣泛的連接接口,包括USB、SDIO、UART、SPI、CAN-FD、以太網(wǎng)、ADC(模數(shù)轉(zhuǎn)換器)、LocalBus等,以滿足不同應(yīng)用場景的需求

-
OK536-C開發(fā)板
T536全國產(chǎn)工業(yè)級核心板提供配套開發(fā)板,采用核心板+底板分體式設(shè)計,共320個引腳,T536開發(fā)板采用4個80Pin板對板連接器的方式將處理器的功能引腳以最便利的方式引出,并針對不同的功能做了深度優(yōu)化,T536開發(fā)板方便用戶二次開發(fā)的同時簡化用戶設(shè)計,為您的項目提供良好的評估及設(shè)計依據(jù)。 了解詳情

