相關文章
FreeRTOS qemu mps2-an385 bsp 移植制作 :環境搭建篇
FreeRTOS qemu mps2-an385 bsp 移植制作 :系統啟動篇
FreeRTOS qemu mps2-an385 bsp 移植制作 :系統運行篇
開發環境
-
Win10 64位 + VS Code,ssh 遠程連接 ubuntu
-
VMware Workstation Pro 16 + Ubuntu 20.04
-
FreeRTOSv202212.01(備注:可以在 github 獲取最新版本)
-
qemu qemu-system-arm mps2-an385 開發板,qemu 版本 QEMU emulator version 4.2.1 或更高
-
arm gcc 交叉編譯工具鏈:當前使用 gcc 編譯環境, gcc-arm-11.2-2022.02-x86_64-arm-none-eabi, gcc version 11.2.1 20220111
前言
-
前面的 FreeRTOS qemu mps2-an385 bsp 移植制作 :環境搭建篇 大體講了一下環境搭建,初步配置了工程目錄
-
FreeRTOS qemu mps2-an385 bsp 移植制作 :系統啟動篇 配置了 VS Code gdb 調試環境,初步讓MCU 啟動,進入了啟動入口函數
FreeRTOS qemu mps2-an385 bsp 移植制作 :系統運行篇 實現了 FreeRTOS 的運行,創建一個task 并成功運行
- 本篇繼續優化,增加串口驅動,讓系統運行時打印串口信息
串口驅動
-
qemu mps2-an385 的串口驅動相對簡單,當前串口打印只需要關心串口的輸出,串口的中斷輸入,待后續增加 shell 終端功能時再處理
-
創建
qemu_mps2/driver/drv_uart.c
,內容如下:
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>#include "drv_uart.h"
#include "CMSDK_CM3.h"#define DBG_BUFF_MAX_LEN 256
static char rt_log_buf[DBG_BUFF_MAX_LEN] = { 0 };/* qemu uart dirver class */
struct uart_instance
{const char *name;CMSDK_UART_TypeDef *handle;IRQn_Type irq_num;int uart_index;
};static struct uart_instance uart0_handle = { 0 };static void uart_putc(uint8_t c)
{uart0_handle.handle->DATA = c;
}static int serial_put(const char *data, int length)
{int size;size = length;while (length){uart_putc(*data);++ data;-- length;}return size - length;
}/* debug print */
int os_printf(const char *fmt, ...)
{int length;va_list args;va_start(args, fmt);length = vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);serial_put(rt_log_buf, length);return length;
}void UART0RX_Handler(void)
{uint32_t irq_status = 0x00;irq_status = uart0_handle.handle->INTCLEAR;uart0_handle.handle->INTCLEAR = irq_status;
}int uart_init(void)
{uart0_handle.handle = CMSDK_UART0;uart0_handle.uart_index = UART0RX_IRQn;uart0_handle.name = "uart0";uart0_handle.handle->BAUDDIV = 16; /* 115200bps */uart0_handle.handle->CTRL = CMSDK_UART_CTRL_RXIRQEN_Msk | CMSDK_UART_CTRL_RXEN_Msk | CMSDK_UART_CTRL_TXEN_Msk;NVIC_EnableIRQ(uart0_handle.irq_num);uart0_handle.handle->STATE = 0;return 0;
}
-
這里借助 C 庫 函數
vsnprintf
,實現格式化輸出,實現比較的簡單,類似于printf
功能 -
創建
qemu_mps2/driver/drv_uart.h
串口頭文件
#ifndef __DRV_UART_H__
#define __DRV_UART_H__#include <stdint.h>int uart_init(void);
int os_printf(const char *fmt, ...);#endif //__DRV_UART_H__
修改 main.c 增加串口打印
- 在
qemu_mps2/application/main.c
中,再創建一個 task,注意 棧空間可以適當的加大,防止棧溢出引發異常
#include "FreeRTOS.h"
#include "task.h"#include <stdio.h>
#include <string.h>#include "drv_uart.h"#define TASK_TEST_PRIORITY (tskIDLE_PRIORITY + 6)
#define TASK_TEST2_PRIORITY (tskIDLE_PRIORITY + 8)static void task_test_entry(void *pvParameters)
{uint32_t cnt = 0;os_printf("%s : enter\r\n", __func__);while (1){vTaskDelay(1000);os_printf("%s : cnt %d\r\n", __func__, cnt++);}
}static void task_test2_entry(void *pvParameters)
{uint32_t cnt = 0;os_printf("%s : enter\r\n", __func__);while (1){vTaskDelay(2000);os_printf("%s : cnt %d\r\n", __func__, cnt++);}
}void main( void )
{uart_init();os_printf("%s : enter\r\n", __func__);xTaskCreate(task_test_entry, "task_test", 512, NULL, TASK_TEST_PRIORITY, NULL);xTaskCreate(task_test2_entry, "task_test2", 512, NULL, TASK_TEST2_PRIORITY, NULL);vTaskStartScheduler();for( ;; );
}
- 串口輸出信息
- 串口輸出正常,兩個任務輪流輸出
小結
-
本篇主要實現
qemu mps2-an385
的串口輸出打印功能,借助 C 庫函數簡單實現 -
后續可以增加串口的 shell 終端功能,到時候會利用起來串口的接收處理