1、RTC 配置
调一个 RTC,刚开始运行都正常,设置的时间跟读出的时间一样。但是换了一个芯片出现读出的年不对的情况,调试才发现是RTC设置的时候有些参数漏掉没填导致的。
T_S32 DRIVER_RTC_Ioctl(T_S32 s32Cmd, T_VOID *pvData)
{
switch(s32Cmd)
{
case E_RTC_IOCTL_CMD_SET_WAKE_INT:
{
//T_U16 u16Cnt = *((T_U16 *)pvData);
}
break;
case E_RTC_IOCTL_CMD_READ_TIME:
{
S_RtcIoctlRead *pstTime = (S_RtcIoctlRead *)pvData;
RTC_DateTypeDef stDate;
RTC_TimeTypeDef stTime;
HAL_RTC_GetTime(&RtcHandle, &stTime, RTC_FORMAT_BCD);
HAL_RTC_GetDate(&RtcHandle, &stDate, RTC_FORMAT_BCD);
pstTime->u8Year = stDate.Year;
pstTime->u8Month = stDate.Month;
pstTime->u8Date = stDate.Date;
pstTime->u8WeekDay = stDate.WeekDay;
pstTime->u8Hours = stTime.Hours;
pstTime->u8Minutes = stTime.Minutes;
pstTime->u8Seconds = stTime.Seconds;
}
break;
case E_RTC_IOCTL_CMD_WRITE_TIME:
{
S_RtcIoctlWrite *pstTime = (S_RtcIoctlWrite *)pvData;
RTC_DateTypeDef stDate;
RTC_TimeTypeDef stTime;
stDate.Year = pstTime->u8Year;
stDate.Month = pstTime->u8Month;
stDate.Date = pstTime->u8Date;
stDate.WeekDay = 0x01; //这个参数要设置下 避免不在 1-7的范围里面
stTime.Hours = pstTime->u8Hours;
stTime.Minutes = pstTime->u8Minutes;
stTime.Seconds = pstTime->u8Seconds;
stTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; //这个参数要设置下
stTime.StoreOperation = RTC_STOREOPERATION_RESET; //这个参数要设置下
HAL_RTC_SetTime(&RtcHandle, &stTime, RTC_FORMAT_BCD);
HAL_RTC_SetDate(&RtcHandle, &stDate, RTC_FORMAT_BCD);
}
break;
}
return RET_SUCCESS;
}
————————————————
版权声明:本文为CSDN博主「未知电子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cheng401733277/article/details/97785957
2、休眠启动
外设休眠后,启动时重新配置下
3、STM32F0系列 二级引导注意事项
STM32F0系列是M0的内核,没有VTOR的寄存器,所以在应用程序里面的配置还有些不一样
1)引导程序的KEIL配置
2)引导程序代码
/*********************************************
* @Îļþ: main.c
* @×÷Õß: cjx
* @°æ±¾: v1.0.0
* @ʱ¼ä: 2018-06-22
* @µç»°: 18770053277
* @¸ÅÒª:
*********************************************/
#include "ioctrl.h"
//Soft Update Explain
#define BOOT_SOFT_ADDR 0x08000000
#define APP_RUN_ADDR 0x08004000
#define FACTORY_BIN_ADDR 0x0800E800
#define VER_INFO_ADDR 0x0801B000
#define USER_INFO_ADDR 0x0801B800
#define EXT_APP_BIN_ADDR 0x00002000
#define APP_BIN_SIZE (50*1024)
#define FACTORY_VER 1
#define VER_FLAG_NULL 0
#define VER_FLAG_FACTORY 1
#define VER_FLAG_EXT 2
typedef struct{
T_U32 u32Ver;
T_U32 u32Flag;
}S_VerInfo;
S_VerInfo g_VerInfo;
S_FlashRead g_FlashRead;
S_FlashWrite g_FlashWrite;
S_FlashErase g_FlashErase;
S_ExtFlashRead g_ExtFlashRead;
S_ExtFlashWrite g_ExtFlashWrite;
S_ExtFlashErase g_ExtFlashErase;
T_U8 g_u8Cache[2*1024];
void UpdateFromFactory(void)
{
T_U32 u32i = 0;
//g_FlashErase.u32Addr = APP_RUN_ADDR;
//g_FlashErase.u32Pages = 18;//APP_BIN_SIZE/FLASH_PAGE_SIZE;
//DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashErase);
print_msg("\nErase_Okay!\n");
for(u32i = 0; u32i < (36*1024); u32i += sizeof(g_u8Cache))
{
g_FlashRead.u32Addr = FACTORY_BIN_ADDR + u32i;
g_FlashRead.pu8Data = (T_U8 *)g_u8Cache;
g_FlashRead.u32Len = sizeof(g_u8Cache);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_FlashRead);
g_FlashErase.u32Addr = APP_RUN_ADDR + u32i;;
g_FlashErase.u32Pages = 1;
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashErase);
g_FlashWrite.u32Addr = APP_RUN_ADDR + u32i;
g_FlashWrite.pu8Data = (T_U8 *)&g_u8Cache;
g_FlashWrite.u32Len = sizeof(g_u8Cache);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite);
}
print_msg("\nCopy_Factory_Okay!\n");
g_FlashErase.u32Addr = VER_INFO_ADDR;
g_FlashErase.u32Pages = 1;
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashErase);
g_VerInfo.u32Ver = FACTORY_VER;
g_VerInfo.u32Flag = VER_FLAG_NULL;
g_FlashWrite.u32Addr = VER_INFO_ADDR;
g_FlashWrite.pu8Data = (T_U8 *)&g_VerInfo;
g_FlashWrite.u32Len = sizeof(g_VerInfo);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite);
print_msg("\nVer_Info_Write_Okay!\n");
}
void UpdateFromExtFlash(void)
{
T_U32 u32i = 0;
g_FlashErase.u32Addr = APP_RUN_ADDR;
g_FlashErase.u32Pages = APP_BIN_SIZE/FLASH_PAGE_SIZE;
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_ERASE, (T_VOID *)&g_FlashWrite);
for(u32i = 0; u32i < APP_BIN_SIZE; u32i += sizeof(g_u8Cache))
{
g_ExtFlashRead.u32Addr = EXT_APP_BIN_ADDR + u32i;
g_ExtFlashRead.pu8Data = (T_U8 *)g_u8Cache;
g_ExtFlashRead.u32Len = sizeof(g_u8Cache);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_ExtFlashRead);
g_FlashWrite.u32Addr = APP_RUN_ADDR + u32i;
g_FlashWrite.pu8Data = (T_U8 *)&g_u8Cache;
g_FlashWrite.u32Len = sizeof(g_u8Cache);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite);
}
g_FlashRead.u32Addr = VER_INFO_ADDR;
g_FlashRead.pu8Data = (T_U8 *)&g_VerInfo;
g_FlashRead.u32Len = sizeof(g_VerInfo);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_FlashRead);
//g_VerInfo.u32Ver = FACTORY_VER;
g_VerInfo.u32Flag = VER_FLAG_NULL;
g_FlashWrite.u32Addr = VER_INFO_ADDR;
g_FlashWrite.pu8Data = (T_U8 *)&g_VerInfo;
g_FlashWrite.u32Len = sizeof(g_VerInfo);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_WRITE, (T_VOID *)&g_FlashWrite);
}
typedef void (*pFunction)(void);
void Jump_Address(void)
{
if (((*(volatile u32*)APP_RUN_ADDR) & 0x2FFE0000 ) == 0x20000000)
{
T_U32 test,JumpAddress;
pFunction Jump_To_Application;
test = (*(volatile u32*)APP_RUN_ADDR);
JumpAddress = *(volatile u32*) (APP_RUN_ADDR + 4);
Jump_To_Application = (pFunction) JumpAddress;
print_msg("\nGoto_App!=0x%4x\n", JumpAddress);
__set_MSP(*(volatile u32*) APP_RUN_ADDR);
Jump_To_Application();
print_msg("\nNULL\n");
}
}
int main(void)
{
DRIVER_SYS_Open();
DRIVER_FLASH_Open();
DRIVER_EXTFLASH_Open();
DRIVER_SYS_EnableInterrupt();
//while(1);
T_U32 u32Delay = 1000000;
while(u32Delay--);
g_FlashRead.u32Addr = VER_INFO_ADDR;
g_FlashRead.pu8Data = (T_U8 *)&g_VerInfo;
g_FlashRead.u32Len = sizeof(g_VerInfo);
DRIVER_FLASH_Ioctl(E_FLASH_IOCTL_CMD_READ, (T_VOID *)&g_FlashRead);
print_msg("\nBoot_Start!\n");
if(100 == g_VerInfo.u32Flag){
}else if(VER_FLAG_FACTORY == g_VerInfo.u32Flag){
UpdateFromFactory();
}else if(VER_FLAG_EXT == g_VerInfo.u32Flag){
UpdateFromExtFlash();
}else{
UpdateFromFactory();
}
Jump_Address();
while(1);
return 0;
}
————————————————
版权声明:本文为CSDN博主「未知电子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cheng401733277/article/details/97785957
3)应用程序的配置
这里机的把RAM编译的起始地址也改下,预留前面一段用来存中断向量地址
4)应用程序代码
/*********************************************
* @Îļþ: main.c
* @×÷Õß: cjx
* @°æ±¾: v1.0.0
* @ʱ¼ä: 2018-06-22
* @µç»°: 18770053277
* @¸ÅÒª:
*********************************************/
#include "apll.h"
#include "ioctrl.h"
int main(void)
{
memcpy((uint32_t*)0x20000000, (uint32_t*)0x08004000, 48*4);
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
uint32_t tmpctrl;
tmpctrl = SYSCFG->CFGR1;
tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
tmpctrl |= (uint32_t) 0x03;
SYSCFG->CFGR1 |= tmpctrl;
T_VOID *pvAllHandle = T_NULL;
if(RET_SUCCESS != ALL_Init(&pvAllHandle))
{
return -1;
}
ALL_Run(pvAllHandle);
ALL_DeInit(pvAllHandle);
}
————————————————
版权声明:本文为CSDN博主「未知电子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cheng401733277/article/details/97785957
5)Keil生成bin
https://download.csdn.net/download/everbright6666/9961053
6)bin合并工具
https://download.csdn.net/download/cheng401733277/11504294
7)合并