Implemented iwdg as xiuos device and chained reset
This commit is contained in:
parent
8e2baf1ee3
commit
4358ce4d9f
|
@ -10,11 +10,78 @@
|
|||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// #include <user_api.h>
|
||||
#include <transform.h>
|
||||
|
||||
#ifdef BSP_USING_WDT
|
||||
|
||||
atomic_uint_fast8_t task_status = 0;
|
||||
static int watchdog_fd;
|
||||
static pthread_t watch_dog_task;
|
||||
static pthread_mutex_t task_status_lock;
|
||||
|
||||
// receiveDataFromSENSORTask(0x01)、sendDataToServerTask(0x02)
|
||||
#define TASK_NUM 0x03
|
||||
|
||||
void SetTaskStatus(uint8_t task_idx) {
|
||||
atomic_fetch_or(&task_status, task_idx);
|
||||
}
|
||||
|
||||
static void ClearTaskStatus() {
|
||||
atomic_store(&task_status, 0);
|
||||
}
|
||||
|
||||
static void* FeedWatchdogTask(void* parameter) {
|
||||
uint8_t status = 0;
|
||||
|
||||
while (1) {
|
||||
status = atomic_load(&task_status);
|
||||
|
||||
// task status
|
||||
if (TASK_NUM == status) {
|
||||
/* keep watchdog alive */
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = WDT_TYPE;
|
||||
ioctl_cfg.args = NULL;
|
||||
|
||||
PrivIoctl(watchdog_fd, OPER_WDT_KEEPALIVE, &ioctl_cfg);
|
||||
|
||||
ClearTaskStatus();
|
||||
}
|
||||
|
||||
PrivTaskDelay(4000);
|
||||
}
|
||||
}
|
||||
|
||||
int WatchdogInit(uint16_t timeout) {
|
||||
int ret = 0;
|
||||
|
||||
PrivMutexCreate(&task_status_lock, 0);
|
||||
watchdog_fd = PrivOpen("/dev/wdt0_dev", O_RDWR);
|
||||
|
||||
/* set watchdog timeout time */
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = WDT_TYPE;
|
||||
ioctl_cfg.args = &timeout;
|
||||
|
||||
PrivIoctl(watchdog_fd, OPER_WDT_SET_TIMEOUT, &ioctl_cfg);
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 22;
|
||||
attr.stacksize = 2048;
|
||||
|
||||
PrivTaskCreate(&watch_dog_task, &attr, &FeedWatchdogTask, NULL);
|
||||
PrivTaskStartup(&watch_dog_task);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int FrameworkInit();
|
||||
extern void ApplicationOtaTaskInit(void);
|
||||
|
||||
|
@ -26,10 +93,10 @@ extern int OtaTask(void);
|
|||
extern int webserver(void);
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
printf("\nHello, world!\n");
|
||||
FrameworkInit();
|
||||
|
||||
#ifdef APPLICATION_OTA
|
||||
ApplicationOtaTaskInit();
|
||||
#endif
|
||||
|
@ -38,6 +105,12 @@ int main(void)
|
|||
OtaTask();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_WDT
|
||||
// the actual timeout is around 32s when tick is 0xfff
|
||||
uint16_t timeout = 0xfff; /* timeout time 0xfff ticks */
|
||||
WatchdogInit(timeout);
|
||||
#endif
|
||||
|
||||
#ifdef APPLICATION_WEBSERVER
|
||||
webserver();
|
||||
#endif
|
||||
|
@ -45,5 +118,3 @@ int main(void)
|
|||
return 0;
|
||||
}
|
||||
// int cppmain(void);
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "connect_lte.h"
|
||||
#include "connect_rs485.h"
|
||||
#include "connect_uart.h"
|
||||
#include "connect_wdt.h"
|
||||
#include "core_riscv.h"
|
||||
#include "wchble.h"
|
||||
#include "xsconfig.h"
|
||||
|
@ -81,6 +82,22 @@ void readRomConfiguration(void) {
|
|||
NVIC_SystemReset(); // 复位ch32v208
|
||||
}
|
||||
|
||||
if (CFG->resetStage == 0) {
|
||||
CFG->resetStage = 1;
|
||||
CFG_WRITE(PAGE_WRITE_START_ADDR, (u8 *)CFG, MODULE_CFG_LEN);
|
||||
} else {
|
||||
CFG->resetStage = 0;
|
||||
CFG_WRITE(PAGE_WRITE_START_ADDR, (u8 *)CFG, MODULE_CFG_LEN);
|
||||
KPrintf("Chained reset: wait for 1s to reset again\n");
|
||||
|
||||
// wait for 1s
|
||||
extern uint32_t SystemCoreClock;
|
||||
for (uint32_t i = 0; i < SystemCoreClock; i += 2) {
|
||||
__NOP();
|
||||
}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/* 输出配置信息 */
|
||||
KPrintf("\n*************rom configuration****************\n");
|
||||
KPrintf("moduleName:\t%s\n", CFG->moduleName);
|
||||
|
@ -241,6 +258,10 @@ void InitBoardHardware() {
|
|||
InitHwLte();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_WDT
|
||||
InitHwWdt();
|
||||
#endif
|
||||
|
||||
KPrintf("memory address range: [0x%08x - 0x%08x] SRAM_SIZE: %ld, ssize: %ld\n", (x_ubase)MEMORY_START_ADDRESS,
|
||||
(x_ubase)MEMORY_END_ADDRESS, SRAM_SIZE, __stack_size);
|
||||
KPrintf("board init done.\n");
|
||||
|
|
|
@ -109,5 +109,13 @@ menuconfig BSP_USING_LTE
|
|||
config LTE_DEVICE_NAME_1
|
||||
string "lte bus device 1 name"
|
||||
default "lte_dev1"
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_WDT
|
||||
bool "Using WATCHDOG TIMER device"
|
||||
default n
|
||||
select RESOURCES_WDT
|
||||
if BSP_USING_WDT
|
||||
source "$BSP_DIR/third_party_driver/wdt/Kconfig"
|
||||
endif
|
||||
|
||||
|
|
|
@ -22,4 +22,7 @@ endif
|
|||
ifeq ($(CONFIG_BSP_USING_LTE),y)
|
||||
SRC_DIR += lte
|
||||
endif
|
||||
ifeq ($(CONFIG_BSP_USING_WDT),y)
|
||||
SRC_DIR += wdt
|
||||
endif
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -40,7 +40,8 @@ __attribute__((aligned(4))) module_cfg defaultConfiguration = {.moduleName = "Xi
|
|||
.stopBits_Rs485 = 1,
|
||||
.parity_Rs485 = 1,
|
||||
.cfgFlag[0] = checkcode1,
|
||||
.cfgFlag[1] = checkcode2}; // 默认配置信息
|
||||
.cfgFlag[1] = checkcode2,
|
||||
.resetStage = 0}; // 默认配置信息
|
||||
|
||||
u8 Configbuf[MODULE_CFG_LEN]; // 从flash中读取的配置信息数组
|
||||
pmodule_cfg CFG = (pmodule_cfg)Configbuf; // 从flash中读取的配置信息指针
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#define FLASH_PAGE_SIZE 1024
|
||||
|
||||
#define NET_MODULE_DATA_LENGTH 60 // Maximum length of the data area
|
||||
#define MODULE_CFG_LEN 272 // The length of configuration buff
|
||||
|
||||
/*Communication command code*/
|
||||
#define NET_MODULE_CMD_SET 0X01 // Configure module parameters
|
||||
|
@ -86,8 +85,11 @@ typedef struct MODULE_CFG {
|
|||
unsigned char stopBits_Rs485; // stop bits of RS485, `1` -> `0x01`|`2` -> `0x02`
|
||||
unsigned char parity_Rs485; // parity of RS485, `None` -> `0x01`|` Odd` -> `0x02`|`Even` -> `0x03`
|
||||
unsigned char cfgFlag[2]; // Verification code, used to verify configuration information
|
||||
unsigned char resetStage; // tell if this reset should do nothing at all, and wait for 1s to reset again (chained reset); 0 means normal reset, 1 means chained reset
|
||||
} module_cfg, *pmodule_cfg;
|
||||
|
||||
#define MODULE_CFG_LEN sizeof(module_cfg) // The length of configuration buff
|
||||
|
||||
extern u8 Configbuf[MODULE_CFG_LEN];
|
||||
|
||||
extern module_cfg defaultConfiguration;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan
|
||||
* PSL v2. You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
|
||||
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the
|
||||
* Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_wdt.h
|
||||
* @brief define ch32v208rbt6 watchdog function and struct
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024-12-31
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_WDT_H
|
||||
#define CONNECT_WDT_H
|
||||
|
||||
#include <ch32v20x_wwdg.h>
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int InitHwWdt(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
if BSP_USING_WDT
|
||||
config WDT_BUS_NAME_0
|
||||
string "watchdog bus 0 name"
|
||||
default "wdt0"
|
||||
|
||||
config WDT_DRIVER_NAME_0
|
||||
string "watchdog driver 0 name"
|
||||
default "wdt0_drv"
|
||||
|
||||
config WDT_0_DEVICE_NAME_0
|
||||
string "watchdog device 0 name"
|
||||
default "wdt0_dev0"
|
||||
endif
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := connect_wdt.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan
|
||||
* PSL v2. You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
|
||||
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
* NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the
|
||||
* Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_wdt.c
|
||||
* @brief support ch32v208rbt6 watchdog function and register to bus
|
||||
* framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2024-12-31
|
||||
*/
|
||||
|
||||
#include <connect_wdt.h>
|
||||
|
||||
#define SCALE 256
|
||||
#define PRESCALER IWDG_Prescaler_256
|
||||
|
||||
static const uint16_t IWDG_CNT = 0xFFF;
|
||||
static uint16_t timeout = IWDG_CNT;
|
||||
|
||||
static void IWDG_FeedInit(u16 prescale, u16 reload_cnt) {
|
||||
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
|
||||
IWDG_SetPrescaler(prescale);
|
||||
IWDG_SetReload(reload_cnt);
|
||||
IWDG_ReloadCounter();
|
||||
IWDG_Enable();
|
||||
}
|
||||
|
||||
static uint32 WdtOpen(void* dev) {
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static void WdtFeed(void) { IWDG_ReloadCounter(); }
|
||||
|
||||
static uint32 WdtConfigure(void* drv, struct BusConfigureInfo* args) {
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(args);
|
||||
|
||||
uint16_t timeout = *((uint32_t*)args->private_data);
|
||||
|
||||
switch (args->configure_cmd) {
|
||||
case OPER_WDT_SET_TIMEOUT:
|
||||
IWDG_FeedInit(PRESCALER, timeout);
|
||||
break;
|
||||
case OPER_WDT_KEEPALIVE:
|
||||
WdtFeed();
|
||||
|
||||
break;
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static const struct WdtDevDone dev_done = {
|
||||
WdtOpen,
|
||||
NONE,
|
||||
NONE,
|
||||
NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Watchdog function
|
||||
* @return success: EOK, failure: other
|
||||
*/
|
||||
int StartWatchdog(void) {
|
||||
// add feed watchdog task function
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
int InitHwWdt(void) {
|
||||
x_err_t ret = EOK;
|
||||
|
||||
static struct WdtBus wdt0;
|
||||
|
||||
ret = WdtBusInit(&wdt0, WDT_BUS_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Watchdog bus init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct WdtDriver drv0;
|
||||
drv0.configure = WdtConfigure;
|
||||
|
||||
ret = WdtDriverInit(&drv0, WDT_DRIVER_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Watchdog driver init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_0, WDT_BUS_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Watchdog driver attach error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct WdtHardwareDevice dev0;
|
||||
dev0.dev_done = &dev_done;
|
||||
|
||||
ret = WdtDeviceRegister(&dev0, WDT_0_DEVICE_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Watchdog device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = WdtDeviceAttachToBus(WDT_0_DEVICE_NAME_0, WDT_BUS_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("Watchdog device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue