기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
안녕하세요! 오랜만에 또 다시 질문을 올리게 되네요! ㅎㅎ
S3C6410 board로 watchdog을 구현하고 있는데, 잘 안되네요~ ㅠㅠ;;
[환경] - Kernel 2.6.28을 사용.
[질문1] Software Watchdog 구현 질문
1. make menuconfig에서 Device Drivers -> Watchdog Timer Support 에서 Software watchdog을 선택함
2. 부팅 message에서도
"Software Watchdog Timer: 0.07 initialized. soft_noboot=0 soft_margin=60 sec (nowayout= 0)"
라구 잘 나옵니다.
3. 그런데 전혀 동작을 하지 않습니다. 이유가 무엇이며 어떻게 해야 동작을 하는지요?
drivers/watchdog/softdog.c 소스를 보니, watchdog_init() function에서 별다른 initialize를 하지 않는것 같습니다.
또한 Softdog_open() function이 불려져야 동작할 것 같으며,
60초 안에 일정한 시간동안 softdog_keepalive() function이 불려져야 할 것 같은데,
별도로 application을 만들어야 하는지요??
아래는 softdog.c 소스에서 watchdog_init()를 적어 놓았습니다. 참고하시기 바랍니다.
[질문2] SoC Watchdog 구현 질문
1. make menuconfig에서 Device Drivers -> Watchdog Timer Support에서 Samsung SoC Watchdog을 선택함
2. 부팅하면 바로 reset 이 됩니다. 이유가 무엇이며 어떻게 해야 무리없이 동작하는지요?
drivers/watchdog/s3c2410_wdt.c 소스에 보면,
50 #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
이렇게 되어 있기 때문에 최소 15초는 기다리다 reboot 되어야 하는거 아닌지요??
참고로 아래에 s3c2410_wdt.c 소스에서 int s3c2410wdt_probe()를 기술하였습니다.
감사합니다.
꼬~옥 고수님들의 조언을 부탁드립니다. 꾸뻑~^^;;
static int __init watchdog_init(void)
278 {
279 int ret;
280
281 /* Check that the soft_margin value is within it's range;
282 if not reset to the default */
283 if (softdog_set_heartbeat(soft_margin)) {
284 softdog_set_heartbeat(TIMER_MARGIN);
285 printk(KERN_INFO PFX
286 "soft_margin must be 0 < soft_margin < 65536, using %d\n",
287 TIMER_MARGIN);
288 }
289
290 ret = register_reboot_notifier(&softdog_notifier);
291 if (ret) {
292 printk(KERN_ERR PFX
293 "cannot register reboot notifier (err=%d)\n", ret);
294 return ret;
295 }
296
297 ret = misc_register(&softdog_miscdev);
298 if (ret) {
299 printk(KERN_ERR PFX
300 "cannot register miscdev on minor=%d (err=%d)\n",
301 WATCHDOG_MINOR, ret);
302 unregister_reboot_notifier(&softdog_notifier);
303 return ret;
304 }
305
306 printk(banner, soft_noboot, soft_margin, nowayout);
307
308 return 0;
309 }
334 static int s3c2410wdt_probe(struct platform_device *pdev)
335 {
336 struct resource *res;
337 struct device *dev;
338 unsigned int wtcon;
339 int started = 0;
340 int ret;
341 int size;
342
343 DBG("%s: probe=%p\n", __func__, pdev);
344
345 dev = &pdev->dev;
346 wdt_dev = &pdev->dev;
347
348 /* get the memory region for the watchdog timer */
349
350 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
351 if (res == NULL) {
352 dev_err(dev, "no memory resource specified\n");
353 return -ENOENT;
354 }
355
356 size = (res->end - res->start) + 1;
357 wdt_mem = request_mem_region(res->start, size, pdev->name);
358 if (wdt_mem == NULL) {
359 dev_err(dev, "failed to get memory region\n");
360 ret = -ENOENT;
361 goto err_req;
362 }
363
364 wdt_base = ioremap(res->start, size);
365 if (wdt_base == NULL) {
366 dev_err(dev, "failed to ioremap() region\n");
367 ret = -EINVAL;
368 goto err_req;
369 }
370
371 DBG("probe: mapped wdt_base=%p\n", wdt_base);
372
373 wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
374 if (wdt_irq == NULL) {
375 dev_err(dev, "no irq resource specified\n");
376 ret = -ENOENT;
377 goto err_map;
378 }
379
380 ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
381 if (ret != 0) {
382 dev_err(dev, "failed to install irq (%d)\n", ret);
383 goto err_map;
384 }
385
386 wdt_clock = clk_get(&pdev->dev, "watchdog");
387 if (IS_ERR(wdt_clock)) {
388 dev_err(dev, "failed to find watchdog clock source\n");
389 ret = PTR_ERR(wdt_clock);
390 goto err_irq;
391 }
392
393 clk_enable(wdt_clock);
394
395 /* see if we can actually set the requested timer margin, and if
396 * not, try the default value */
397
398 if (s3c2410wdt_set_heartbeat(tmr_margin)) {
399 started = s3c2410wdt_set_heartbeat(
400 CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
401
402 if (started == 0)
403 dev_info(dev,
404 "tmr_margin value out of range, default %d used\n",
405 CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME);
406 else
407 dev_info(dev, "default timer value is out of range, cannot start\n");
408 }
409
410 ret = misc_register(&s3c2410wdt_miscdev);
411 if (ret) {
412 dev_err(dev, "cannot register miscdev on minor=%d (%d)\n",
413 WATCHDOG_MINOR, ret);
414 goto err_clk;
415 }
416
417 if (tmr_atboot && started == 0) {
418 dev_info(dev, "starting watchdog timer\n");
419 s3c2410wdt_start();
420 } else if (!tmr_atboot) {
421 /* if we're not enabling the watchdog, then ensure it is
422 * disabled if it has been left running from the bootloader
423 * or other source */
424
425 s3c2410wdt_stop();
426 }
427
428 /* print out a statement of readiness */
429
430 wtcon = readl(wdt_base + S3C2410_WTCON);
431
432 dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n",
433 (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in",
434 (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis",
435 (wtcon & S3C2410_WTCON_INTEN) ? "" : "en");
436
437 return 0;
438
439 err_clk:
440 clk_disable(wdt_clock);
441 clk_put(wdt_clock);
442
443 err_irq:
444 free_irq(wdt_irq->start, pdev);
445
446 err_map:
447 iounmap(wdt_base);
448
449 err_req:
450 release_resource(wdt_mem);
451 kfree(wdt_mem);
452
453 return ret;
454 }
watchdog은 보통 reset 코드에 대부분 들어 있습니다.
저도 24xx와 6410 시리즈에서 해당 드라이버를 써 본적은 없는데, watchdog 코드는 24xx 시리즈 때서부터 architecture reset 코드에 들어 있습니다.
예전의 경우 reboot 걸면 24xx 시리즈는 100ms watchdog을 enable시켜서 리부트 하게 되어 있었습니다.
해당 코드를 먼저 보시기 바랍니다.
코드 내용물에 대한 미구현 issue일 수도 있으니...