RT-THREAD使用开发记录
Git 基本命令学习用户名设置项目级别仓库用户名设置:git config user.name xxxgit config user.email xxx@163.com查看仓库用户名设置cat .git/config系统级别仓库用户名设置:git config --global user.name xxxgit config --global user.email xxx@163.com查看系统仓
Git 基本命令学习
用户名设置
项目级别仓库用户名设置:
-
git config user.name xxx
-
git config user.email xxx@163.com
查看仓库用户名设置
- cat .git/config
系统级别仓库用户名设置:
- git config --global user.name xxx
- git config --global user.email xxx@163.com
查看系统仓库用户名设置
- cat ~/.gitconfig
基本操作
-
git status 查看工作区、暂存区状态
-
git add ./git add [文件名] 提交到暂存区,并且转换换行符
-
git rm -cached [文件名] 从暂存区撤回
-
git commit -m"commit message" [file name] 将暂存区的内容提交到本地库
-
git restore [文件名] 撤销某个文件修改的操作
-
git reset HEAD [file] 可以吧暂存区的修改撤销掉(unstage),重新放回工作区
查看历史记录
- git log 查看版本历史记录
- git log --pretty=oneline 每个历史只显示一行(hash值和日志)
- git log --oneline 每个历史只显示一行且显示hash的部分值
- git reflog 现实历史只显示一行,并且显示指针(要移动到版本多少步)
版本前进后退
- git reset --hard [局部索引值]
- git reset --hard HEAD^^ 注:一个^表示后退一步,n 个^表示后退 n 步
- git reset --hard HEAD~n 注:表示后退 n 步
比较文件差异
git diff [文件名] 将工作区中的文件和暂存区进行比较
git diff [本地库中的文件和本地库历史记录比较]
分支管理
- git branch [分支名] 创建分支
- git branch -v 查看分支
- git checkout [分支名] 切换分支
- git merge [有新内容分支名] 合并分支
- git branch -d [分支名] 删除分支
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0xAu5fM-1650875915363)(F:\rt-thread\documentation\git_notes\git_note.assets\image-20210707193138830.png)]
合并分支方法
git checkout [被合并分支名master] /*切换分支
第二步:执行 merge 命令 (合并分支指令)
git merge [有新内容分支名*]**
冲突原因: 2个分支,修改同一文件,同一位置,修改内容不一样时.
冲突的解决:
第一步:编辑文件,删除特殊符号
第二步:把文件修改到满意的程度,保存退出
第三步:git add [文件名]
第四步:git commit -m “日志信息”
注意:此时 commit 一定不能带具体文件名
远程仓库
- git remote -v 查看当前所有远程地址别名
- git remote add [别名 origin] [远程地址]
- git push [别名] [分支名] or git push origin master
- $ git config --global http.sslVerify “false” 重新登录
- git clone [远程地址] 克隆仓库
克隆效果:
完整的把远程库下载到本地
创建 origin 远程地址别名 (git remote -v查看远程库别名)
初始化本地库(就是:git init) - git pull = fetch+merge
git fetch [远程库地址别名origin] [远程分支名master] /*抓去下来
git checkout origin/master /*切换到链接地址(别名)的master(可查看抓取下来内容
切换回 git checkout master
git merge [远程库地址别名origin/master远程分支名] /*合并
git pull [远程库地址别名] [远程分支名] /*等于上面步骤
GitFlow工作流
- 主干分支 master
主要负责管理正在运行的生产环境代码,永远保持与正在运行的生产环境完全一致 - 开发分支 develop
主要负责管理正在开发过程中的代码。一般情况下应该是最新的代码。 - bug 修理分支 hotfix
主要负责管理生产环境下出现的紧急修复的代码。从主干分支分出,修理完毕并测试上线后,并回主干分支。并回后,视情况可以删除该分支。 - 准生产分支(预发布分支) release
较大的版本上线前,会从开发分支中分出准生产分支,进行最后阶段的集成测试。该版本上线后,会合并到主干分支。生产环境运行一段阶段较稳定后可以视情况删除。 - 功能分支 feature
为了不影响较短周期的开发工作,一般把中长期开发模块,会从开发分支中独立出来。开发完成后会合并到开发分支。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z6xmxnoK-1650875915364)(F:\rt-thread\documentation\git_notes\git_note.assets\image-20210707194107228.png)]
团队协作
略
Vim
创建文本 vim 文件名.txt
保存并退出 Esc :wq 回车
设置签名
RTT开发记录
stm32f407vet6
日志ulog
#define DBG_TAG "MAIN"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
/*
* The macro definitions for debug
*
* These macros are defined in static. If you want to use debug macro, you can
* use as following code:
*
* In your C/C++ file, enable/disable DEBUG_ENABLE macro, and then include this
* header file.
*
* #define DBG_TAG "MOD_TAG"
* #define DBG_LVL DBG_INFO
* #include <rtdbg.h> // must after of DBG_LVL, DBG_TAG or other options
*
* Then in your C/C++ file, you can use LOG_X macro to print out logs:
* LOG_D("this is a debug log!");
* LOG_I("this is a info log!");
* LOG_W("this is a warning log!");
* LOG_E("this is a error log!");
*/
使用SFUD挂载W25Q128与easyflash
使用sfud挂载W25Q128参考链接:https://blog.csdn.net/sundm75/article/details/106455095?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-4.highlightwordscore&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-4.highlightwordscore
RT-Thread:在W25Q128上搭载文件系统:https://blog.csdn.net/weixin_41738023/article/details/113247550
#include <rtthread.h>
#include <spi_flash.h>
#include <spi_flash_sfud.h>
#include "drv_spi.h"
static int rt_hw_spi_flash_init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
/*往总线spi3挂载一个spi30的设备*/
rt_hw_spi_device_attach("spi3", "spi30", GPIOA, GPIO_PIN_10);
/*使用SFUD探测 spi30从设备,并将spi30连接的flash初始化为块设备,名称为:W25Q128*/
if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi30"))
{
return -RT_ERROR;
};
return RT_EOK;
}
/*导出到自动初始化*/
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ar8O6sKZ-1650877195462)(F:\rt-thread\documentation\programming record.assets\image-20211229091032301.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kFIIVqUx-1650877195463)(F:\rt-thread\documentation\programming record.assets\image-20211229091051230.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nxBxNZ8Q-1650877195464)(F:\rt-thread\documentation\programming record.assets\image-20211229091108686.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SKkTEmc2-1650877195464)(F:\rt-thread\documentation\programming record.assets\image-20211229091205152.png)]
SFUD与easyflash 区别:https://blog.csdn.net/h451884098/article/details/118544347
SFUD+FAL+EasyFlash典型场景需求分析:https://www.cnblogs.com/happybirthdaytoyou/p/12303872.html
RT-Thread 配置片外Flash与EasyFlash组件:https://www.datasheep.cn/44.html
硬件RTC驱动
配置硬件RTC时钟树更新时钟代码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uOgIa3uW-1650877195465)(F:\rt-thread\documentation\programming record.assets\image-20211229104447685.png)]
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 6;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U3US0oOA-1650877195465)(F:\rt-thread\documentation\programming record.assets\image-20211229105056067.png)]
配置Kconfig宏定义
config BSP_USING_ONCHIP_RTC
bool "Enable RTC"
select RT_USING_RTC
select RT_USING_LIBC
default n
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5oSdRwHz-1650877195466)(F:\rt-thread\documentation\programming record.assets\image-20211229105120931.png)]
RTC设备代码参考链接:https://blog.csdn.net/weixin_43810563/article/details/116813301?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&utm_relevant_index=2
RTC设备api
//设置rtc日期
/*year:设置的年 month:设置的月 day:设置的日*/
rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day)
//设置rtc时间
/*hour:设置的时 minute:设置的分 second:设置的秒*/
rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
//获取当前时间
time_t time(time_t *t
RTC设备示例
#include <rtthread.h>
#include <rtdevice.h>
static int rtc_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
time_t now;
/* 设置日期 */
ret = set_date(2018, 12, 3);
if (ret != RT_EOK)
{
rt_kprintf("set RTC date failed\n");
return ret;
}
/* 设置时间 */
ret = set_time(11, 15, 50);
if (ret != RT_EOK)
{
rt_kprintf("set RTC time failed\n");
return ret;
}
/* 延时3秒 */
rt_thread_mdelay(3000);
/* 获取时间 */
now = time(RT_NULL);
rt_kprintf("%s\n", ctime(&now));
return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(rtc_sample, rtc sample);
-
dynmem_sample
-
event sample 事件最大值?
-
semaphore_sample
static 变量只初始化一次。
-
idlehook_sample
钩子函数作用参考https://www.freesion.com/article/7308411124/
-
interrupt sample
-
mutex_sample
-
mailbox_sample
信号量、互斥量、事件集
-
信号量
以生活中的停车场为例来理解信号量的概念:
①当停车场空的时候,停车场的管理员发现有很多空车位,此时会让外面的车陆续进入停车场获得停车位;
②当停车场的车位满的时候,管理员发现已经没有空车位,将禁止外面的车进入停车场,车辆在外排队等候;
③当停车场内有车离开时,管理员发现有空的车位让出,允许外面的车进入停车场;待空车位填满后,又禁止外部车辆进入。
在此例子中,管理员就相当于信号量,管理员手中空车位的个数就是信号量的值(非负数,动态变化);停车位相当于公共资源(临界区),车辆相当于线程。车辆通过获得管理员的允许取得停车位,就类似于线程通过获得信号量访问公共资源。
-
互斥量
互斥量又叫相互排斥的信号量,是一种特殊的二值信号量。互斥量类似于只有一个车位的停车场:当有一辆车进入的时候,将停车场大门锁住,其他车辆在外面等候。当里面的车出来时,将停车场大门打开,下一辆车才可以进入。 -
事件集
事件集也是线程间同步的机制之一,一个事件集可以包含多个事件,利用事件集可以完成一对多,多对多的线程间同步。下面以坐公交为例说明事件,在公交站等公交时可能有以下几种情况:
①P1 坐公交去某地,只有一种公交可以到达目的地,等到此公交即可出发。
②P1 坐公交去某地,有 3 种公交都可以到达目的地,等到其中任意一辆即可出发。
③P1 约另一人 P2 一起去某地,则 P1 必须要等到 “同伴 P2 到达公交站” 与“公交到达公交站”两个条件都满足后,才能出发。
这里,可以将 P1 去某地视为线程,将 “公交到达公交站”、“同伴 P2 到达公交站” 视为事件的发生,情况①是特定事件唤醒线程;情况②是任意单个事件唤醒线程;情况③是多个事件同时发生才唤醒线程。
空闲钩子函数是空闲线程的钩子函数,如果设置了空闲钩子函数,就可以在系统执行空闲线程时,自动执行空闲钩子函数来做一些其他事情,比如系统指示灯、功耗管理、看门狗喂狗、CPU使用率。可以设置4个空闲钩子函数
volatile关键字:如果一个寄存器或者变量表示一个端口或者多个线程的共享数据,就容易出错,所以volatile可以保证对特殊地址的稳定访问。这样修改以后循环条件就不会被优化掉,当值改变的时候系统将会检测到。
优点:防止编译器对代码优化,变量值是直接从变量地址中读取和存储的。缺点: 这种使用过多会导致代码十分庞大。
解释 https://blog.csdn.net/weixin_44363885/article/details/92838607
指针解释:https://www.runoob.com/cprogramming/c-pointers.html
CmBacktrace工具使用
工具复制到OBJ目录,打开EVN工具,复制run后面参数。如果rtthread.axf找不到头文件,将rt-thread.axf改为rtthread.axf或修改执行名称
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-14vQkqcs-1650877195466)(F:\rt-thread\documentation\programming record.assets\image-20211231153526731.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2fvrgUk-1650877195467)(F:\rt-thread\documentation\programming record.assets\image-20211231141711323.png)]
补码:https://blog.csdn.net/weixin_38958597/article/details/86631639
更多推荐
所有评论(0)