先贴代码 //看门狗物理地址 #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操作系统添加看门狗定时
猜你喜欢
转载自blog.csdn.net/a3535719/article/details/80768716
今日推荐
周排行