Implemented iwdg as xiuos device and chained reset

This commit is contained in:
KirisameMashiro 2024-12-31 17:59:34 +08:00
parent 8e2baf1ee3
commit 4358ce4d9f
10 changed files with 292 additions and 8 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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中读取的配置信息指针

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_wdt.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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;
}