实现独立看门狗IWDT驱动,创建喂狗线程,实现喂狗功能
工程环境:stm32cubeIDE
开发板:STM32 F103 ZET6最小系统
仿真器:st-link V2
cubeIDE 基于eclipse环境,继承了cubemx,使用gcc编译程序
基本配置步骤与keil类似,参考老师视频与官网cubemx移植教程
基本流程与官网移植教程相同,题目要求配置看门狗,所以在cubemx里配置了iwdg;同时配置了E5、B5两个GPIO口,用于控制两个LED灯的闪烁。
生成工程后需要在ld文件内添加如下内容,否则components.c文件内INIT_EXPORT等宏会不起作用。也会导致FinSH控制台无法初始化,从周六开始就在研究RT-Thread,一直无法启动FinSH,多日查询资料后发现如下解决办法。
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
在startup 启动文件内将main改为entry,由于在工程里不能直接更改所以需要打开相应的文件夹,使用记事本更改。
添加输出输入支持,代码与官网教程相同
char rt_hw_console_getchar(void)
{
int ch = -1;
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
{
ch = huart1.Instance->DR & 0xff;
}
else
{
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) != RESET)
{
__HAL_UART_CLEAR_OREFLAG(&huart1);
}
rt_thread_mdelay(10);
}
return ch;
}
void rt_hw_console_output(const char *str)
{
rt_size_t i = 0, size = 0;
char a = '\r';
__HAL_UNLOCK(&huart1);
size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if (*(str + i) == '\n')
{
ITM_SendChar(a);
HAL_UART_Transmit(&huart1, (uint8_t*) &a, 1, 1);
}
HAL_UART_Transmit(&huart1, (uint8_t*) (str + i), 1, 1);
}
}
在board.c 文件内添加原本位于main函数内的初始化函数
main函数内容
void myMain();
int main(void)
{
MX_IWDG_Init();
rt_kputs("start iwdg");
myMain();
while (1)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
rt_thread_mdelay(500);
}
}
myMain.c 文件内容
#include "main.h"
#include "rtthread.h"
static char iwdg_stack[128];
static struct rt_thread iwdg;
void iwdgThread();
void myMain()
{
rt_thread_init(&iwdg, //线程句柄
"iwdgTd", //线程的名称;
iwdgThread, //线程的入口函数
RT_NULL, //线程的入口函数
&iwdg_stack[0], //线程堆栈的起始地址
sizeof(iwdg_stack), //线程栈大小
25, //优先级
50); //时间片大小
rt_thread_startup(&iwdg);
}
void iwdgThread()
{
int i = 0;
while (1)
{
HAL_IWDG_Refresh(&hiwdg);
rt_kprintf("iwdg:%d\n", i++);
rt_thread_mdelay(200);
}
}
运行结果: