STM32F407移植OpenHarmony笔记6

继上一篇笔记,编译好STM32的裸机程序,能点亮LED灯了。
下一步就是启动liteos_m内核了。


 不过为了更好的调试代码,需要先把printf重定向到串口,基于gcc的printf重定向和Keil不一样。
直接新建printf.c,在里面重写printf函数即可。

int printf(char const *fmt, ...)
{
    char buf[256];
    va_list ap;
    va_start(ap, fmt);
    int len = vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, fmt, ap);
    UartWrite(buf, len);
    va_end(ap);
    return len;
}

UartWrite是写串口的函数,基于HAL库写串口驱动我就不介绍了。
记得在printf之前要初始化UART和相关的GPIO。
这里有2个细节需要注意:
1.写串口没有临界区保护,多线程printf会有竞争风险,等kernel跑起来了,到时候加上mutex。
2.格式化字符串的buf长度256,是在stack上开辟的,注意调用线程的stack空间要给够。


liteos_m内核已经完成了ARM cortex-m4的适配,理论上所有基于cortex-m4的MCU都能快速使用。
我们只需要在main函数调用LOS_KernelInit()和LOS_Start()可以了。
启动之前自己创建一个线程,用来闪灯。

static void LED_Blink(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOA_CLK_ENABLE();
	GPIO_InitStruct.Pin = GPIO_PIN_4;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = 0;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    printf("enter led blink.\n");
	while(1)
	{
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
		LOS_TaskDelay(250);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
		LOS_TaskDelay(250);
	}
}

static void InitTask(void)
{
    UINT32 taskID = 0;
    TSK_INIT_PARAM_S stTask = {0};
    stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)LED_Blink;
    stTask.uwStackSize = 1024;
    stTask.pcName = "led";
    stTask.usTaskPrio = 1;
    LOS_TaskCreate(&taskID, &stTask);
    printf("task id=%d\n", taskID);
}

int main(void)
{
	HAL_Init();
	SystemClock_Config();
	UartInit();
	printf("init...\n");
	LOS_KernelInit();
	InitTask();
	LOS_Start();
    printf("BUG!!!\n");
	while(1);
}

运气好的话,编译下去,可以看到串口打印,同时LED也会闪烁。

init...
entering kernel init...
task id=2
Entering scheduler
enter led blink.

如果没有跑起来的话,可以检查一下:

1. 进入kernel/liteos_m目录,执行make menuconfig
试试修改相关配置项。

2. 检查LOSCFG_PLATFORM_HWI有没有定义为1
liteos_m有接管中断向量表的功能,需要开启这个宏。
这样一来我们就不用修改startup.s里面的中断向量函数。

3.检查printf函数能不能正常工作
printf不正常好像也会影响程序运行。


内核跑起来之后,我们可以开启shell控制台。
这个控制台是liteos_m提供的,需要手动开启,里面有几个基本命令。

开启配置后,在main函数里面调用shell初始化:

LosShellInit();
OsShellInit();
//注册自定义的命令reboot使实现重启功能
osCmdReg(CMD_TYPE_EX, "reboot", 0,(CMD_CBK_FUNC)cmd_reboot); 

static void cmd_reboot(UINT32 argc, const CHAR **argv)
{
    printf("reboot...\n");
    HAL_NVIC_SystemReset();
}

初始化完了还不能用,还要提供一个串口读取字符串的函数:uint8_t UartGetc(void)
这个函数从串口返回1个字符,没有收到数据时返回0。

光是这样还不行,它还需要我们在串口中断里面发送一个信号:
LOS_EventWrite(&g_shellInputEvent, 0x1);
g_shellInputEvent是在shell代码里面定义的全局变量,用来阻塞shell线程。
当收到g_shellInputEvent事件后,shell线程调用UartGetc来接收输入。

由于liteos_m接管了中断向量表,所以我们UART的中断函数要用:
LOS_HwiCreate(USART1_IRQn, 0, 1, (HWI_PROC_FUNC)uart_irq, 0);
这个函数来注册。

好了,终于写好代码,我们编译下载,不出意外可以看到串口打印.
输入help可以看到命令列表。

init...
entering kernel init...
task id=3
Entering scheduler
enter led blink.
OHOS # 
OHOS # 
OHOS # help
*******************shell commands:*************************

cat      cd       cp       date     free     help     ls       memusage 
mkdir    pwd      reboot   rm       rmdir    task     touch    
OHOS # 
OHOS # reboot
reboot...
init...
entering kernel init...
task id=3
Entering scheduler
enter led blink.
OHOS # 

试了下mkdir、ping等命令都不能用,下一步要实现文件系统和网络,让这几个命令正常工作。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/362404.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于 NOVATEK NT98530 Multiview Stitching 应用解决方案

感测技术近来于影像监控系统应用有了进一步的发展,多镜头的应用也与日俱增,如 AI 视觉感测会议相机,能满足远端多人聚会、远距教育训练的多元需求等,相关应用层面广泛涵盖了在生活中所面对的各种场景,带动更加可观的潜…

【安装指南】nodejs下载、安装与配置详细教程

目录 🌼一、概述 🍀二、下载node.js 🌷三、安装node.js 🍁四、配置node.js 🌼一、概述 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,用于构建可扩展的网络应用程序。Node.js 使用事件驱动、…

各品牌主板快速启动热键对照表及CMOS进入方法

各品牌主板快速启动热键对照表 主板品牌 启动按键 笔记本品牌 启动按键 主机品牌 启动按键 华硕主板 F8 联想笔记本 F12 联想台式机 F12 技嘉主板 F12 宏碁笔记本 F12 惠普台式机 F12 微星主板 F11 华硕笔记本 ESC 宏碁台式机 F12 梅捷主板 F9 惠普笔…

机器学习数学基础

机器学习基础 1、标量、向量、矩阵、张量2、概率函数、概率分布、概率密度、分布函数3、向量的线性相关性4、最大似然估计5、正态分布(高斯分布)6、向量的外积(叉积)7、向量的内积(点积)8、超平面(H)1、标量、向量、矩阵、张量 标量、向量、矩阵和张量是线性代数中不同…

Java基础学习:System类和Static方法的实际使用

一、System类 1.在程序开发中,我们需要对这个运行的结果进行检验跟我们预判的结果是否一致,就会用到打印结果在控制台中显示出来使用到了System类。System类定义了一些和系统相关的属性和方法,它的属性和方法都是属于静态的,想使用…

win11安装wsl作为linux子系统并当作服务器

wsl安装 打开控制面板,找到启用或关闭windows功能 开启windows虚拟机监控平台和适用于Linux的Windows子系统,重启电脑。 打开microsoft store搜索ubuntu,找到合适的版本下载安装 输入wsl -l如下所示,即为安装成功。 安装过程比较…

怎么进行视频压缩大小?常见的4种压缩方法

在当今数字化的时代,我们经常处理大量的视频文件,无论是用于社交媒体分享、视频制作还是存储在我们的设备中。然而,随着视频质量的提升和分辨率的增加,视频文件的大小也相应地变得更加庞大,给存储、分享和传输带来了一…

HTTPS之使用acme.sh申请免费ssl证书

1、步骤一:安装 acme.sh acme.sh 是一个集成了 ACME 客户端协议的 Bash 脚本 a、安装命令 curl https://get.acme.sh | sh -s emailusernameexample.com 或者 git clone --depth 1 https://github.com/acmesh-official/acme.sh.git cd acme.sh ./acme.sh --ins…

循环系统的血流方向 Circulatory System‘s Pathway of Blood Through the Heart

循环系统的血流方向 目录 循环系统的血流方向前置知识:心脏腔室和阀门:血液路线:心脏瓣膜病 循环系统是由心脏、血管和血液组成的复杂系统,负责输送氧气、营养和其他物质到身体的各个部位,并将代谢产物带回肺和肾脏等器…

【力扣经典面试题】189. 轮转数组

题目描述: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 …

SIT1145AQ带选择性唤醒及故障保护的低功耗 CAN FD 总线收发器

特点 符合 ISO 11898-2:2016 和 SAE J2284-1 至 SAE J2284-5 标准 ➢ AEC-Q100 认证 ➢ 拥有低功耗休眠模式以及待机模式 ➢ 支持标准 CAN 唤醒帧的远程唤醒,兼容 ISO 11898- 2:2016 标准的选择性唤醒帧远程唤醒 ➢ 唤醒源诊断识别功能 ➢ 总…

二月外贸新规,外贸人请查收

政策导读: 1.新版《稳外贸稳外资税收政策指引》发布; 2.商务部公布2024年进出口许可证发证机构名录; 3.2月9日起中国和新加坡互免签证; 4.进出口低含量三乙醇胺混合物产品无需办理两用物项许可证; 5.USB-C成为欧盟…

通过与chatGPT交流实现零样本事件抽取

1、写作动机: 近来的大规模语言模型(例如Chat GPT)在零样本设置下取得了很好的表现,这启发作者探索基于提示的方法来解决零样本IE任务。 2、主要贡献: 提出了基于chatgpt的多阶段的信息抽取方法:在第一阶…

企业网络基础架构监控工具

IT 基础架构已成为提供基本业务服务的基石,无论是内部管理操作还是为客户托管的应用程序服务,监控 IT 基础设施至关重要,并且已经建立起来,SMB IT 基础架构需要简单的网络监控工具来监控性能和报告问题。通常,几个 IT …

写个Android事件分发实际用例(持续更新)

一,概述 感兴趣的读者,如果对Android事件分发还有不了解的地方,可以阅读笔者写的文章再谈android事件分发机制。 本文的主要目的,是结合前文所分享事件分发相关原理,在实际案例中使用。 二,Recycler嵌套…

SourceTree 不显示新添加文件

最近遇到了在项目中新添加了文件,但是在提交的时候SourceTree 中“未暂存区域”却不显示文件。如果你也有类似的问题,不防来看看吧。 我可能不知道什么时候动了下面的配置: 配置选择为“待定”,新增的未提交文件就显示出来了&…

Pycharm连接云算力远程服务器(AutoDL)训练深度学习模型全过程

前言:在上一篇windows搭建深度学习环境中,我试图使用笔记本联想小新air14的mx350显卡训练一个图像检测的深度学习模型,但是训练时长大概需要几天时间远超我的预期,所以我便选择租用GPU进行训练,在对多家平台对比后找到…

在Arduino给自己的SSD1306 OLED显示定制Logo或者图片

我在使用Arduino上的SSD1306显示屏时,基本都用使用Adafruit的SSD1306库,但是Adafruit的开机logo实在没特色(如下图),如果在开机时,让自己的项目上显示自己的定制logo,甚至是照片(如果…

【蓝桥杯日记】复盘篇三——循环结构

前言 本篇内容是对循环结构进行复盘的,循环可谓是在基础阶段特别重要的东西,是三大结构(顺序结构、选择结构、循环结构)中最重要的结构之一。 目录 🍑1.找最小值 分析: 知识点: 代码如下 &…

Multi ElasticSearch Head插件基本操作

Multi ElasticSearch Head插件安装好之后我们可以进行一些基本的操作。 1、复合查询 因为ES提供了一些Restful风格的接口,可以让任何语言去调用,因此我们可以将之前的请求地址粘贴到Multi ElasticSearch Head插件里面,选择GET请求方式&#x…