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等命令都不能用,下一步要实现文件系统和网络,让这几个命令正常工作。 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

api接口1688商品详情接口采集商品详情数据商品价格详情页数据可支持高并发调用演示示例

接入1688商品详情API接口的步骤如下: 注册账号:首先,你需要在1688开放平台注册一个账号。 创建应用:登录后,在控制台中找到“我的应用”,点击“创建应用”。 获取API密钥:创建应用后&#xff…

使用vue脚手架构建项目

一、前言 * 创建好vue-cli的环境,下载好vue包依赖* 本文使用环境:vue/cli 5.0.8二、步骤 创建vueTest文件夹,管理员身份运行cmd , 进入到vueTest文件夹 执行命令vue create 你的项目名 ,这里我定义的项目名为: my-project 基于…

第九节HarmonyOS 常用基础组件22-Marquee

1、描述 跑马灯组件,用于滚动展示一段单行文本,仅当文本内容宽度超过跑马灯组件宽度时滚动。 2、接口 Marquee(value:{start:boolean, step?:number, loop?:number, fromStart?: boolean ,src:string}) 3、参数 参数名 参数类型 必填 描述 st…

Java EE 5 SDK架构

Java EE 5 SDK架构 大型组织每天都要处理大量数据和多用户的相关事务。为管理该组织如此大型而又复杂的系统,开发了企业应用程序。企业应用程序是在服务器上托管的应用程序,通过计算机网络同时向大量用户提供服务。这种应用程序可采用各种技术开发,如Java EE 5。Java EE 5平…

使用Markdown写作的魔力

今年的年终总结报告,我是用Markdown写的,只花了大概2.5天的时间,包括统计任务数据,时效,总结成果,挖掘不足,提出改善措施和计划。 将全部文字内容的.md文档,导出为word,然后用了做PPT的AI,设计了PPT,再修改了半天,就完成了。 上周为两个代码工程,用Markdown写了r…

测试环境搭建整套大数据系统(一:基础配置,修改hostname,hosts,免密,时间同步)

一:使用服务器配置。 二:修改服务器名称hostname,hosts。 在 Linux 系统中,hostname 和 /etc/hosts 文件分别用于管理主机名和主机名解析。 在三台服务器上,分别执行以下命令。 vim /etc/hostnamexdso-hadoop-test-0…

Qt QWidget Loading界面并覆盖在其他控件上面

目录 一、效果图二、Loading三、使用 一、效果图 界面中有一个Label&#xff0c;一个Button 点击Buttion&#xff0c;显示Loading的界面&#xff0c;并覆盖到Label和Button上面 二、Loading loadingwidget.h #ifndef LOADINGWIDGET_H #define LOADINGWIDGET_H#include <…

C#——三角形面积公式

已知三角形的三个边&#xff0c;求面积&#xff0c;可以使用海伦公式。 因此&#xff0c;可以执行得到三角形面积公式的计算方法代码如下&#xff1a; /** / <summary>* / 三角形面积公式* / </summary>* / <param name"a">边长a</param>*…

etcd自动化安装配置教程

文章目录 前言一、简介1. 简介2. 特点3. 端口介绍 二、etcd安装教程&#xff08;单机版&#xff09;1. 复制脚本2. 增加执行权限3. 执行脚本4. 查看启动状态5. 卸载etcd 三、etcd安装教程&#xff08;集群版&#xff09;1. 复制脚本2. 增加执行权限3. 分发脚本4. 执行脚本5. 启…

【HarmonyOS】鸿蒙开发之HTTP网络请求——第5章

HTTP网络请求封装 network/request.ets import { configInterface } from ./type import http from ohos.net.http import { getToken } from ../utils/storage//网络请求封装 export const request (config:configInterface)>{let httpRequest:http.HttpRequest http.c…

模拟实现哈希表 - HashMap(Java版本)

目录 1. 概念 2. 冲突-概念 3. 冲突-避免 4. 冲突-避免-哈希函数设计 5. 冲突-避免-负载因子调节 ⭐⭐⭐⭐⭐ 6. 冲突-解决 6.1 冲突-解决-闭散列 6.2 冲突-解决-开散列/哈希桶 ⭐⭐⭐⭐⭐ 7. 冲突严重时的解决办法 8. 模拟实现 1. 概念 顺序结构以及平衡树中&#…

代码随想录day16--二叉树的应用4

LeetCode513.找树左下角的值 题目描述&#xff1a; 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 解题思…