先贴代码
//看门狗物理地址
#define WATCHDOG_BASE 0x01C20000 //基地址
#define BLOCK_SIZE 0X1000 //4K大小
#define rWDOG0_IRQ_EN 0xCA0
#define rWDOG0_IRQ_STA 0xCA4
#define rWDOG0_CTRL 0xCB0
#define rWDOG0_CFG 0xCB4
#define rWDOG0_MODE 0xCB8
/**
*@brief 看门狗和time定时
*/
void *wdog_timer(void *b)
{
int mem_fd = -1;
unsigned char *wdog_map = NULL;
volatile unsigned int *WDOG0_IRQ_EN = NULL;
volatile unsigned int *WDOG0_IRQ_STA = NULL;
volatile unsigned int *WDOG0_CTRL = NULL;
volatile unsigned int *WDOG0_CFG = NULL;
volatile unsigned int *WDOG0_MODE = NULL;
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR | O_CREAT, 0666)) < 0)
{
printf("can't open /dev/mem \n");
exit(-1);
}
/* mmap WDOG0 */
wdog_map = (unsigned char *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, WATCHDOG_BASE);
close(mem_fd);
if (wdog_map == MAP_FAILED)
{
printf("mmap error %d\n", (int)wdog_map);
exit(-1);
}
// Always use volatile pointer!
WDOG0_IRQ_EN = (volatile unsigned int *)(wdog_map + rWDOG0_IRQ_EN);
WDOG0_IRQ_STA = (volatile unsigned int *)(wdog_map + rWDOG0_IRQ_STA);
WDOG0_CTRL = (volatile unsigned int *)(wdog_map + rWDOG0_CTRL);
WDOG0_CFG = (volatile unsigned int *)(wdog_map + rWDOG0_CFG);
WDOG0_MODE = (volatile unsigned int *)(wdog_map + rWDOG0_MODE);
*(volatile unsigned int *)WDOG0_IRQ_EN = 0x01;
*(volatile unsigned int *)WDOG0_CFG = 0x01;
*(volatile unsigned int *)WDOG0_MODE = 0x30; //看门狗3秒
*(volatile unsigned int *)WDOG0_MODE |= 0X01;
while(1)
{
//添加自己的程序
//这里可以加一个判断,如果正常返回,我们就关闭看门狗,否则退出就重启了
if(join_thread_flag == 1) //如果标志置1,我们就正常返回,关闭看门狗
{
*(volatile unsigned int *)WDOG0_MODE &= ~(0X01 << 0);
*(volatile unsigned int *)WDOG0_IRQ_EN = 0x0;
munmap(0, BLOCK_SIZE);
break;
}
*(volatile unsigned int *)WDOG0_CTRL |= ((0XA57 << 1) | (0X01 << 0)); //喂狗
}
}
mmap系统调用的过程:
void *addr;
addr = mmap(0,0x1000, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0);
参数1:如果是0,内核帮找一块内存区域,起始地址是返回值addr
参数2:虚拟内存的大小,0x1000一页(如果申请的内存空间没有对齐,内核会帮我们对齐,会经过一次if/else判断,浪费开销)
参数3:权限
参数4:权限
参数5:fd,将该文件映射到该区域
参数6:映射的偏移量
通过数据手册我查到看门狗的基地址0x01C20C00,但是我们通过mmap函数传参的地址只能传页(4k)的整数倍,所以我传的地址是0x01C20000,然后这个函数给我们返回了一个指针,通过操作这个指针,加上实际物理地址的偏移量,我们就能操作寄存器了,比如我的寄存器rWDOG0_IRQ_EN的偏移量是0xA0,但是我传参时少传了一个0xC00,所以偏移量加上这个即可,就成了0xCA0,以此类推
linux操作系统添加看门狗定时
用户评价(0)
暂无评价,你也可以发布评价哦:)
登录 | 立即注册