Firefly开源社区

123
发表新贴

[技术分享]Firefly-rk3288定时开机实现!

888

积分

4

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
888
发表于 2016-7-11 17:39:25     
本帖最后由 Livvol 于 2016-7-13 17:47 编辑

如题,先上实现效果:
我板子上跑的是ubuntu 14.04系统。
查看下RTC硬件时钟的时间,如果与当前系统时间不符,那么将系统时间同步到RTC硬件
时钟即可:
  1. firefly@firefly:~$ sudo hwclock -r
  2. Mon 11 Jul 2016 07:42:39 AM UTC  -0.432840 seconds
  3. firefly@firefly:~$ sudo hwclock -w
复制代码

给硬件时钟写入定时开机时间:

  1. sudo ./on_off 2016.07.11.08.00.00
复制代码
on_off 是一个简单的C程序,负责从节点/dev/alarm 给硬件时钟写入定时开机时间。

可以查看一下内核打印信息,看一下开机时间是否已经写进去:

  1. firefly@firefly:~$ dmesg

  2. [  364.964700] hym8563_rtc_set_alarm:diff_sec= 1007s , use alarm
  3. [  364.967412] alarm_release: clear alarm, pending 0
复制代码
如果出现上面信息,就说明开机时间已经顺利写进去,关机,然后静静等待,到时间后系统会自动启动,完美~。



接下来讲下实现方法,主要修改内核的两个个文件即可。ubuntu14.04 使用的内核版本跟Android 4.4的内核版本基本一致,可以利用我们的Android 4.4 SDK的内核来进行修改和编译。

首先需要修改:
kernel/drivers/rtc/rtc-HYM8563.c


@@ -25,6 +25,7 @@
#include "rtc-HYM8563.h"
#include <linux/of_gpio.h>
#include <linux/irqdomain.h>
+#include <linux/kernel.h>
#define RTC_SPEED      200 * 1000

struct hym8563 {

@@ -36,6 +37,7 @@ struct hym8563 {
        struct wake_lock wake_lock;
};
static struct i2c_client *gClient = NULL;
+static struct hym8563 *g_hym8563 = NULL;

static int i2c_master_reg8_send(const struct i2c_client *client, const char reg, const char *buf, int count, int scl_rate)
{

@@ -543,6 +546,7 @@ static int  hym8563_probe(struct i2c_client *client, const struct i2c_device_id

        int rc = 0;
        u8 reg = 0;
        struct hym8563 *hym8563;
+       struct rtc_wkalrm alarm;
        struct rtc_device *rtc = NULL;
        struct rtc_time tm_read, tm = {
                .tm_wday = 6,

@@ -609,7 +613,8 @@ static int  hym8563_probe(struct i2c_client *client, const struct i2c_device_id
                goto exit;
        }
        hym8563->rtc = rtc;
+       g_hym8563 = hym8563;
+       hym8563_rtc_read_alarm(&gClient->dev,&alarm);

        return 0;

exit:

@@ -629,7 +634,7 @@ static int  hym8563_remove(struct i2c_client *client)
}
-void hym8563_shutdown(struct i2c_client * client)
+/*void hym8563_shutdown(struct i2c_client * client)

{      u8 regs[2];
     int ret;
     //disable clkout

@@ -637,6 +642,28 @@ void hym8563_shutdown(struct i2c_client * client)
     ret=hym8563_i2c_set_regs(client, RTC_CLKOUT, regs, 1);
     if(ret<0)
         printk("rtc shutdown is error\n");
+}*/
+static void hym8563_shutdown(struct i2c_client * client)
+{
+       struct device *pdev = &client->dev;
+       struct rtc_wkalrm alarm;
+       struct rtc_device *rtc_dev = g_hym8563->rtc;
+       u8 regs[4];
+      
+       rtc_read_alarm(rtc_dev,&alarm);
+      
+       if(alarm.enabled == 1){
+               printk("%s this in shutdowm,the alarm.enabled = 1 \n",__func__);
+       }
+       hym8563_i2c_read_regs(client,RTC_CTL2,regs,1);
+       regs[0] |= AIE;
+       hym8563_i2c_set_regs(client, RTC_CTL2,regs,1);
+       hym8563_i2c_read_regs(client,RTC_CTL2,regs,1);
+      
+       regs[0] |=TIE;
+       hym8563_i2c_set_regs(client,RTC_CTL2,regs,1);
+       hym8563_i2c_read_regs(client,RTC_CTL2,regs,1);
+

}

@@ -661,16 +688,19 @@ struct i2c_driver hym8563_driver = {
        .probe          = hym8563_probe,
        .remove         = hym8563_remove,
        //.shutdown=hym8563_shutdown,
+       .shutdown=hym8563_shutdown,
        .id_table       = hym8563_id,
};

接下来修改:
kernel/drivers/staging/android/alarm-dev.c


@@ -110,18 +110,35 @@ static void alarm_clear(enum android_alarm_type alarm_type)

}
  static void alarm_set(enum android_alarm_type alarm_type,
                                                        struct timespec *ts)
{
        uint32_t alarm_type_mask = 1U << alarm_type;
        unsigned long flags;

+       struct rtc_time time;
+       struct rtc_device *rtc_dev;
+       struct rtc_wkalrm alarm;


        spin_lock_irqsave(&alarm_slock, flags);
        alarm_dbg(IO, "alarm %d set %ld.%09ld\n",
                        alarm_type, ts->tv_sec, ts->tv_nsec);
        alarm_enabled |= alarm_type_mask;
        devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
        spin_unlock_irqrestore(&alarm_slock, flags);
+       if(alarm_type == 4){
+        rtc_time_to_tm(ts->tv_sec,&time);
+        rtc_dev = alarmtimer_get_rtcdev();
+        alarm.time.tm_year = time.tm_year;
+        alarm.time.tm_mon = time.tm_mon;
+        alarm.time.tm_mday = time.tm_mday;
+        alarm.time.tm_wday = time.tm_wday;
+        alarm.time.tm_hour = time.tm_hour;
+        alarm.time.tm_min = time.tm_min;
+        alarm.time.tm_sec = time.tm_sec;
+        alarm.enabled = 1;
+        rtc_set_alarm(rtc_dev,&alarm);
+        }

}

static int alarm_wait(void)

以上是我从整理好的patch里面搬下来的,有点乱。大家改的时候耐心点,别看错:P~以上两个文件修改完后,编译好内核,并烧到板子上即可。
修改好的这两个文件我已上传,见附件。




然后,就可以写个简单的C程序,来验证下修改是否有效啦。
以下为代码的部分内容,其余大家可以自行发挥编辑,我就不贴上来了:

  1. #define type_4 1074291010

  2. fd = open("/dev/alarm", O_RDWR);
  3.     if(fd < 0) {
  4.         printf("Unable to open alarm driver: %s\n", strerror(errno));
  5.         return -1;
  6.     }
  7.     ts.ts_sec = (int)timep;
  8.     ts.ts_nsec =0;
  9.     res = ioctl(fd,type_4,&ts);
  10.     if(res < 0) {
  11.         printf("Unable to set rtc to %ld: %s\n", ts.ts_sec, strerror(errno));
  12.         close(fd);
  13.         return 0;
  14.     }
复制代码
以上为Firefly-rk3288定时开机的基本实现!:victory:,如有不妥的地方,欢迎大家来吐槽:lol。
有定时开机就有定时关机,至于定时关机,比较简单的思路是写个程序循环判定设置的时间是否与当前时间相等,相等就调用系统指令poweroff关机即可。大家可以试试~




ScheduledPowerOn.tar.gz

7.3 KB, 下载次数: 175, 下载积分: 灯泡 -1 , 经验 -1

修改后的文件

回复

使用道具 举报

1570

积分

3

威望

0

贡献

中级创客

Rank: 4

积分
1570

突出贡献

QQ
发表于 2016-7-11 18:10:16     
学习 。。
回复

使用道具 举报

发表于 2016-7-12 11:57:28     
好贴,加精支持!
暴走的创客!
回复

使用道具 举报

164

积分

0

威望

0

贡献

技术小白

积分
164
发表于 2016-8-10 14:13:29     
厉害,学习,学习
回复

使用道具 举报

38

积分

0

威望

0

贡献

游客

积分
38
发表于 2016-8-11 22:12:07     
有人试过没有~~~
回复

使用道具 举报

888

积分

4

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
888
发表于 2016-8-15 14:43:38     
abcxyztt 发表于 2016-8-15 13:50
在Android层就可以实现 定时开关

这是ubuntu哦,另外在android下实现定时开机也需要底层驱动支持的。
回复

使用道具 举报

26

积分

0

威望

0

贡献

技术小白

积分
26
发表于 2016-8-23 12:29:37     
学习,学习
回复

使用道具 举报

239

积分

0

威望

0

贡献

禁止发言

积分
239
发表于 2016-10-20 12:13:27     
板子断电后在加电,硬件时钟还是会变,怎么办?要加纽扣电池吗 ?
回复

使用道具 举报

888

积分

4

威望

0

贡献

技术大神

Rank: 3Rank: 3

积分
888
发表于 2016-10-21 15:21:18     
ohyeah521 发表于 2016-10-20 12:13
板子断电后在加电,硬件时钟还是会变,怎么办?要加纽扣电池吗 ?

对,断电后再加电,时钟是会回复为默认时间的,这个只能加电池了
回复

使用道具 举报

239

积分

0

威望

0

贡献

禁止发言

积分
239
发表于 2016-10-21 18:59:57     
Livvol 发表于 2016-10-21 15:21
对,断电后再加电,时钟是会回复为默认时间的,这个只能加电池了

怎么加?求一个教程,不知道能不能写的详细点,我看群里也有几个朋友问如何添加rtc的问题。
还需要采购什么东西?方便的话,给个你买的淘宝链接。谢谢。
回复

使用道具 举报

返回列表
123
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表