码迷,mamicode.com
首页 > 其他好文 > 详细

十七、完成调整时间的功能

时间:2019-02-18 22:53:04      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:thread   handler   大小   文件描述符   结构   ota   虚拟   timezone   map   

先上代码,最后讲解。

draw.c

  1 #include <stdio.h>
  2 #include <linux/fb.h>
  3 #include <sys/types.h>
  4 #include <sys/stat.h>
  5 #include <fcntl.h>
  6 #include <sys/mman.h>
  7 #include "draw.h"
  8 
  9 static struct fb_var_screeninfo __g_vinfo;    /* 显示信息 */
 10 static color_t *__gp_frame;                    /* 虚拟屏幕首地址 */
 11 static color_t __g_pen_color;                /* 画笔颜色 */
 12 static color_t __g_bk_color;                /* 背景颜色 */
 13 static font_size_t __g_font_size;            /* 当前字体大小 */
 14 
 15 /* 定义绘制不同字体的函数和字体大小 */
 16 extern int draw_one_char_fs16 (unsigned int x, unsigned int y, char dat);
 17 extern int draw_one_char_fs24 (unsigned int x, unsigned int y, char dat);
 18 extern int draw_one_char_fs32 (unsigned int x, unsigned int y, char dat);
 19 extern int draw_one_char_fs48 (unsigned int x, unsigned int y, char dat);
 20 extern int draw_one_char_fs64 (unsigned int x, unsigned int y, char dat);
 21     
 22 static struct struct_draw_font __g_draw_font_tab[] = {
 23     {draw_one_char_fs16, FONT_SIZE_16},
 24     {draw_one_char_fs24, FONT_SIZE_24},
 25     {draw_one_char_fs32, FONT_SIZE_32},
 26     {draw_one_char_fs48, FONT_SIZE_48},
 27     {draw_one_char_fs64, FONT_SIZE_64},
 28 };
 29 
 30 /**
 31  * \brief framebuffer初始化
 32  */
 33 int framebuffer_init (void)
 34 {
 35     int fd = 0;
 36 
 37     fd = open("/dev/fb0", O_RDWR);
 38     if (fd == -1) {
 39         perror("fail to open /dev/fb0\n");
 40         return -1;
 41     }
 42 
 43     ioctl(fd, FBIOGET_VSCREENINFO, &__g_vinfo);                    /* 获取显示信息 */
 44     printf("bits_per_pixel = %d\n", __g_vinfo.bits_per_pixel);    /* 得到一个像素点对应的位数 */
 45 
 46     __gp_frame = mmap(NULL,                             /* 映射区的开始地址,为NULL表示由系统决定映射区的起始地址 */
 47                       __g_vinfo.xres_virtual * __g_vinfo.yres_virtual * __g_vinfo.bits_per_pixel / 8,    /* 映射区大小 */
 48                       PROT_WRITE | PROT_READ,            /* 内存保护标志(可读可写) */
 49                       MAP_SHARED,                        /* 映射对象类型(与其他进程共享) */
 50                       fd,                                /* 有效的文件描述符 */
 51                       0);                                /* 被映射内容的偏移量 */
 52     if (__gp_frame == NULL) {
 53         perror("fail to mmap\n");
 54         return -1;
 55     }
 56 
 57     return 0;
 58 }
 59 
 60 /**
 61  * \brief 填充整屏
 62  */
 63 void full_screen (color_t color)
 64 {
 65     int i;
 66     color_t *p = __gp_frame;
 67 
 68     for (i = 0; i < __g_vinfo.xres_virtual * __g_vinfo.yres_virtual; i++) {
 69         *p++ = color;
 70     }
 71 }
 72 
 73 /**
 74  * \brief 设置画笔颜色
 75  */
 76 void set_pen_color (color_t color)
 77 {
 78     __g_pen_color = color;
 79 }
 80 
 81 /**
 82  * \brief 获得画笔颜色
 83  */
 84 color_t get_pen_color (void)
 85 {
 86     return __g_pen_color;
 87 }
 88 
 89 /**
 90  * \brief 设置背景颜色
 91  */
 92 void set_bk_color (color_t color)
 93 {
 94     __g_bk_color = color;
 95 }
 96 
 97 /**
 98  * \brief 获得画笔颜色
 99  */
100 color_t get_bk_color (void)
101 {
102     return __g_bk_color;
103 }
104 
105 /**
106  * \brief 绘制一个点
107  *
108  * \retval 成功返回0,失败返回-1
109  */
110 int draw_point (unsigned int x, unsigned int y)
111 {
112     color_t *p_color;
113 
114     if ((x > __g_vinfo.xres_virtual) || (y > __g_vinfo.yres_virtual)) {
115         return -1;
116     }
117 
118     p_color = __gp_frame + y * __g_vinfo.xres_virtual + x;
119     *p_color = __g_pen_color;
120 
121     return 0;
122 }
123 
124 /**
125  * \brief 绘制一个背景点
126  *
127  * \retval 成功返回0,失败返回-1
128  */
129 int draw_bk_point (unsigned int x, unsigned int y)
130 {
131     color_t *p_color;
132 
133     if ((x > __g_vinfo.xres_virtual) || (y > __g_vinfo.yres_virtual)) {
134         return -1;
135     }
136 
137     p_color = __gp_frame + y * __g_vinfo.xres_virtual + x;
138     *p_color = __g_bk_color;
139 
140     return 0;
141 }
142 
143 /**
144  * \brief 设置字体大小
145  *
146  * \retval 成功返回0,失败返回-1
147  */
148 int set_font_size (font_size_t font)
149 {
150     if (font >= MAX_FONT_SIZE) {
151         return -1;
152     }
153 
154     __g_font_size = font;
155 
156     return 0;
157 }
158 
159 /**
160  * \brief 获取字体大小
161  *
162  * \retval 字体大小
163  */
164 font_size_t get_font_size (void)
165 {
166     return __g_font_size;    
167 }
168 
169 /**
170  * \brief 绘制一个英文字符
171  *
172  * \retval 成功返回0,失败返回-1
173  */
174 int draw_one_char (unsigned int x, unsigned int y, char dat)
175 {
176     int i;
177 
178     for (i = 0; i < sizeof(__g_draw_font_tab) / sizeof(__g_draw_font_tab[0]); i++) {
179         if (__g_draw_font_tab[i].font_size == __g_font_size) {
180             return __g_draw_font_tab[i].draw_one_char_fn(x, y, dat);
181         }
182     }
183 
184     return -1;
185 }
186 
187 /**
188  * \brief 绘制一个字符串
189  *
190  * \retval 返回成功绘制的字符个数
191  */
192 int draw_str (unsigned int x, unsigned int y, char *p_str)
193 {
194     int ret = 0;
195     int char_num = 0;
196     font_size_t font_size;
197 
198     font_size = get_font_size();
199 
200     while (*p_str) {
201         if (0 == draw_one_char(x + char_num * font_size / 2, y, *p_str)) {
202             ret++;
203         }
204         char_num++;
205         p_str++;
206     }
207 
208     return ret;
209 }

draw.h

  1 typedef unsigned short color_t;                /* 定义颜色类型,根据实际情况修改,此处为unsigned short是565的屏 */
  2 
  3 /**< \brief 定义常用颜色 */
  4 #define LCD_BLACK    0x0000                    /* 黑色 */
  5 #define LCD_BLUE    0x001F                    /* 蓝色 */
  6 #define LCD_GREEN    0x07E0                    /* 绿色 */
  7 #define LCD_RED        0xF800                    /* 红色 */
  8 #define LCD_CYAN    (LCD_BLUE | LCD_GREEN)    /* 青色 */
  9 #define LCD_MAGENTA    (LCD_BLUE | LCD_RED)    /* 洋红 */
 10 #define LCD_YELLOW    (LCD_GREEN | LCD_RED)    /* 黄色 */
 11 #define LCD_WHITE    (LCD_CYAN | LCD_RED)    /* 白色 */
 12 
 13 /**< \brief 定义支持的字体类型 */
 14 typedef enum enum_font_size {
 15     FONT_SIZE_16 = 16,
 16     FONT_SIZE_24 = 24,
 17     FONT_SIZE_32 = 32,
 18     FONT_SIZE_48 = 48,
 19     FONT_SIZE_64 = 64,
 20 
 21     MAX_FONT_SIZE    /* 最大字体号,该项放在最后即可 */
 22 } font_size_t;
 23 
 24 /* 定义绘制字符的函数指针类型 */
 25 typedef int (* draw_one_char_t) (unsigned int x, unsigned int y, char dat);
 26 
 27 /* 定义绘制字体的函数和字体大小结构 */
 28 struct struct_draw_font {
 29     draw_one_char_t draw_one_char_fn;    /* 绘制函数 */
 30     font_size_t font_size;                /* 字体大小 */
 31 };
 32 
 33 /**
 34  * \brief framebuffer初始化
 35  */
 36 extern int framebuffer_init (void);
 37 
 38 /**
 39  * \brief 填充整屏
 40  */
 41 extern void full_screen (color_t color);
 42 
 43 /**
 44  * \brief 设置画笔颜色
 45  */
 46 extern void set_pen_color (color_t color);
 47 
 48 /**
 49  * \brief 获得画笔颜色
 50  */
 51 extern color_t get_pen_color (void);
 52 
 53 /**
 54  * \brief 设置背景颜色
 55  */
 56 extern void set_bk_color (color_t color);
 57 
 58 /**
 59  * \brief 获得背景颜色
 60  */
 61 extern color_t get_bk_color (void);
 62 
 63 /**
 64  * \brief 绘制一个点
 65  *
 66  * \retval 成功返回0,失败返回-1
 67  */
 68 extern int draw_point (unsigned int x, unsigned int y);
 69 
 70 /**
 71  * \brief 绘制一个背景点
 72  *
 73  * \retval 成功返回0,失败返回-1
 74  */
 75 extern int draw_bk_point (unsigned int x, unsigned int y);
 76 
 77 /**
 78  * \brief 设置字体大小
 79  *
 80  * \retval 成功返回0,失败返回-1
 81  */
 82 extern int set_font_size (font_size_t font);
 83 
 84 /**
 85  * \brief 获取字体大小
 86  *
 87  * \retval 字体大小
 88  */
 89 extern font_size_t get_font_size (void);
 90 
 91 /**
 92  * \brief 绘制一个英文字符
 93  *
 94  * \retval 成功返回0,失败返回-1
 95  */
 96 extern int draw_one_char (unsigned int x, unsigned int y, char dat);
 97 
 98 /**
 99  * \brief 绘制一个字符串
100  *
101  * \retval 返回成功绘制的字符个数
102  */
103 extern int draw_str (unsigned int x, unsigned int y, char *p_str);

font_size_48.c

注:编译时除了48号字体外还有16,24,32,64等字体,但是我使用的是48号字体

  1 /* 支持的字符 */
  2 static const char char_fs48[] = {"0123456789:- "};
  3 
  4 /* 字模 */
  5 static const char font_size_48[][16 * 9] = {
  6 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  7  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x80,0xC3,0x01,0xC0,0x01,
  8  0x03,0xC0,0x00,0x07,0x60,0x00,0x06,0x70,0x00,0x0E,0x30,0x00,0x0C,0x38,0x00,0x1C,
  9  0x38,0x00,0x1C,0x38,0x00,0x1C,0x18,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,
 10  0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,
 11  0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x18,0x00,0x18,0x38,0x00,0x1C,
 12  0x38,0x00,0x1C,0x38,0x00,0x1C,0x30,0x00,0x0C,0x70,0x00,0x0E,0x60,0x00,0x06,0xC0,
 13  0x00,0x07,0xC0,0x01,0x03,0x00,0xC3,0x01,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,
 14  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"0",0*/
 15 
 16 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 17  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x38,
 18  0x00,0xC0,0x3F,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,
 19  0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,
 20  0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,
 21  0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,
 22  0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,
 23  0x38,0x00,0x00,0x38,0x00,0x00,0x7C,0x00,0xC0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,
 24  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",1*/
 25 
 26 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 27  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x80,0xC1,0x03,0x60,0x00,
 28  0x07,0x30,0x00,0x0E,0x30,0x00,0x0E,0x38,0x00,0x1C,0x38,0x00,0x1C,0x38,0x00,0x1C,
 29  0x78,0x00,0x1C,0x78,0x00,0x1C,0x70,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,
 30  0x00,0x07,0x00,0x00,0x07,0x00,0x80,0x03,0x00,0xC0,0x01,0x00,0xE0,0x00,0x00,0x70,
 31  0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x80,0x03,0x00,
 32  0xC0,0x01,0x00,0xE0,0x00,0x10,0x60,0x00,0x10,0x30,0x00,0x18,0x38,0x00,0x08,0x1C,
 33  0x00,0x0E,0xFC,0xFF,0x0F,0xFC,0xFF,0x0F,0xFC,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,
 34  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",2*/
 35 
 36 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 37  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x80,0xC1,0x01,0x40,0x80,
 38  0x03,0x20,0x00,0x07,0x30,0x00,0x07,0x30,0x00,0x0E,0x70,0x00,0x0E,0x70,0x00,0x0E,
 39  0x60,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x03,0x00,
 40  0x80,0x01,0x00,0xE0,0x00,0x00,0x3E,0x00,0x00,0xE0,0x00,0x00,0x80,0x03,0x00,0x00,
 41  0x07,0x00,0x00,0x0E,0x00,0x00,0x0C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,
 42  0x30,0x00,0x1C,0x78,0x00,0x1C,0x78,0x00,0x1C,0x78,0x00,0x0C,0x38,0x00,0x0E,0x30,
 43  0x00,0x06,0x60,0x00,0x03,0xC0,0xC0,0x01,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,
 44  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",3*/
 45 
 46 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 47  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0xC0,0x01,0x00,0xC0,
 48  0x01,0x00,0xE0,0x01,0x00,0xF0,0x01,0x00,0xD0,0x01,0x00,0xC8,0x01,0x00,0xC8,0x01,
 49  0x00,0xC4,0x01,0x00,0xC6,0x01,0x00,0xC2,0x01,0x00,0xC3,0x01,0x00,0xC1,0x01,0x80,
 50  0xC0,0x01,0xC0,0xC0,0x01,0x40,0xC0,0x01,0x60,0xC0,0x01,0x20,0xC0,0x01,0x30,0xC0,
 51  0x01,0x18,0xC0,0x01,0x18,0xC0,0x01,0x0C,0xC0,0x01,0xFC,0xFF,0x3F,0x00,0xC0,0x01,
 52  0x00,0xC0,0x01,0x00,0xC0,0x01,0x00,0xC0,0x01,0x00,0xC0,0x01,0x00,0xC0,0x01,0x00,
 53  0xC0,0x01,0x00,0xC0,0x01,0x00,0xE0,0x03,0x00,0xFE,0x3F,0x00,0x00,0x00,0x00,0x00,
 54  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"4",4*/
 55 
 56 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 57  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x0F,0xE0,0xFF,0x0F,0xE0,0xFF,
 58  0x0F,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,
 59  0x30,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0xFE,0x00,0x30,
 60  0xFF,0x01,0xB0,0x81,0x07,0xF0,0x00,0x07,0x70,0x00,0x0E,0x30,0x00,0x0E,0x00,0x00,
 61  0x1E,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x30,0x00,0x1C,
 62  0x78,0x00,0x1C,0x78,0x00,0x1C,0x78,0x00,0x0C,0x38,0x00,0x0E,0x30,0x00,0x0E,0x30,
 63  0x00,0x07,0x60,0x00,0x03,0xC0,0xC1,0x01,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,
 64  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",5*/
 65 
 66 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 67  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0x00,0x07,0x02,0x80,0x01,
 68  0x06,0xC0,0x00,0x0E,0x60,0x00,0x0E,0x60,0x00,0x0E,0x30,0x00,0x00,0x30,0x00,0x00,
 69  0x38,0x00,0x00,0x38,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x1C,0xFC,0x00,0x1C,
 70  0xFF,0x03,0x9C,0x83,0x07,0xDC,0x00,0x0E,0x7C,0x00,0x1C,0x3C,0x00,0x1C,0x3C,0x00,
 71  0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,0x1C,0x00,0x38,
 72  0x18,0x00,0x38,0x38,0x00,0x38,0x38,0x00,0x18,0x30,0x00,0x1C,0x70,0x00,0x1C,0xE0,
 73  0x00,0x0C,0xC0,0x01,0x06,0x80,0x83,0x03,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
 74  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"6",6*/
 75 
 76 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 77  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x1F,0xF0,0xFF,0x1F,0xF0,0xFF,
 78  0x0F,0x70,0x00,0x0C,0x30,0x00,0x04,0x18,0x00,0x02,0x18,0x00,0x03,0x08,0x00,0x01,
 79  0x00,0x80,0x01,0x00,0x80,0x00,0x00,0xC0,0x00,0x00,0x40,0x00,0x00,0x60,0x00,0x00,
 80  0x60,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,
 81  0x00,0x00,0x1C,0x00,0x00,0x0C,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,
 82  0x00,0x0E,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,
 83  0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
 84  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",7*/
 85 
 86 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 87  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0xC0,0x81,0x03,0xE0,0x00,
 88  0x07,0x70,0x00,0x0E,0x70,0x00,0x0E,0x38,0x00,0x1C,0x38,0x00,0x1C,0x38,0x00,0x1C,
 89  0x38,0x00,0x1C,0x78,0x00,0x1C,0x78,0x00,0x0C,0xF0,0x00,0x0E,0xE0,0x03,0x07,0xE0,
 90  0x87,0x03,0x80,0xDF,0x01,0x00,0x7F,0x00,0xC0,0xFD,0x00,0xE0,0xF0,0x03,0x70,0xC0,
 91  0x07,0x30,0x80,0x07,0x38,0x00,0x0F,0x38,0x00,0x0E,0x1C,0x00,0x1E,0x1C,0x00,0x1C,
 92  0x1C,0x00,0x1C,0x1C,0x00,0x1C,0x1C,0x00,0x1C,0x18,0x00,0x0C,0x38,0x00,0x0E,0x30,
 93  0x00,0x06,0x60,0x00,0x03,0xC0,0x81,0x01,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,
 94  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",8*/
 95 
 96 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 97  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0xC0,0xC1,0x00,0x60,0x80,
 98  0x01,0x70,0x00,0x03,0x38,0x00,0x06,0x38,0x00,0x06,0x18,0x00,0x0E,0x1C,0x00,0x0C,
 99  0x1C,0x00,0x0C,0x1C,0x00,0x1C,0x1C,0x00,0x1C,0x1C,0x00,0x1C,0x1C,0x00,0x1C,0x1C,
100  0x00,0x1C,0x3C,0x00,0x1E,0x38,0x00,0x1F,0x38,0x00,0x1D,0x78,0x80,0x1D,0xF0,0xE1,
101  0x1C,0xE0,0x7F,0x1C,0x80,0x1F,0x1C,0x00,0x00,0x0E,0x00,0x00,0x0E,0x00,0x00,0x0E,
102  0x00,0x00,0x0E,0x00,0x00,0x06,0x00,0x00,0x07,0x70,0x00,0x03,0x70,0x80,0x03,0x70,
103  0xC0,0x01,0x70,0xE0,0x00,0x60,0x70,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,
104  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"9",9*/
105 
106 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
107  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,
110  0x3E,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,
113  0x3E,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,
114  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",10*/
115 
116 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120  0x00,0x00,0x00,0x00,0x00,0xFC,0xFF,0x3F,0xFC,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,
121  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
124  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",11*/
125 
126 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
129  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",12*/
135 };
136 
137 /**
138  * \brief 通过输入的字符获取在字模表的偏移量
139  *
140  * \retval 字母表中有该字符则返回偏移量,否则返回-1
141  */
142 static int __get_tab_offset (char dat)
143 {
144     int i;
145 
146     for (i = 0; i < sizeof(char_fs48) - 1; i++) {
147         if (dat == char_fs48[i]) {
148             return i;
149         }
150     }
151 
152     return -1;
153 }
154 
155 /**
156  * \brief 绘制一个英文字符,48号字体
157  *
158  * \retval 成功返回0,失败返回-1
159  */
160 int draw_one_char_fs48 (unsigned int x, unsigned int y, char dat)
161 {
162     int offset = 0;
163     int i, j;
164     char tmp = 0;
165     
166     offset = __get_tab_offset(dat);
167     if (offset == -1) {
168         return -1;
169     }
170 
171     for (i = 0; i < 48; i++) {
172         tmp = font_size_48[offset][i * 3];
173         for (j = 0 ; j < 8; j++) {
174             if (tmp & 0x01) {
175                 draw_point(x + j, y + i);
176             } else {
177                 draw_bk_point(x + j, y + i);
178             }
179     
180             tmp    >>= 1;
181         }
182         
183         tmp = font_size_48[offset][i * 3 + 1];
184         for (; j < 16; j++) {
185             if (tmp & 0x01) {
186                 draw_point(x + j, y + i);
187             } else {
188                 draw_bk_point(x + j, y + i);
189             }
190     
191             tmp    >>= 1;
192         }
193         
194         tmp = font_size_48[offset][i * 3 + 2];
195         for (; j < 24; j++) {
196             if (tmp & 0x01) {
197                 draw_point(x + j, y + i);
198             } else {
199                 draw_bk_point(x + j, y + i);
200             }
201     
202             tmp    >>= 1;
203         }
204     }
205     
206     return 0;
207 }

main.c

  1 #include <stdio.h>
  2 #include <time.h>
  3 #include <sys/time.h>
  4 #include <pthread.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <stdlib.h>
  9 #include "draw.h"
 10 #include "figure.h"
 11 
 12 /* 定义按键值 */
 13 #define KEY_OK        0
 14 #define KEY_LEFT    2
 15 #define KEY_RIGHT    3
 16 #define KEY_UP        4
 17 #define KEY_DOWN    5
 18 
 19 typedef struct struct_cursor {
 20     unsigned int x1;
 21     unsigned int y1;
 22     unsigned int x2;
 23     unsigned int y2;
 24     
 25     unsigned int offset_pix;    /* 一个字符所占的像素点 */
 26     int last_offset;            /* 上次偏移量 */
 27 } cursor_t;
 28 cursor_t __g_cursor;
 29 
 30 unsigned int __g_show_x, __g_show_y;    /* 时钟显示的位置 */
 31 
 32 #define MAX_CURSOR_OFFSET    5    /* 最大光标偏移量 */
 33  
 34 /**
 35  * \brief 初始化光标
 36  *
 37  * \param[in] (x1, y1), (x2, y2):第一个游标的对角线坐标
 38  */
 39 void init_cursor (unsigned int x1, 
 40                   unsigned int y1, 
 41                   unsigned int x2, 
 42                   unsigned int y2)
 43 {
 44     __g_cursor.x1 = x1;
 45     __g_cursor.x2 = x2;
 46     __g_cursor.y1 = y1;
 47     __g_cursor.y2 = y2;
 48 
 49     if (x2 > x1) {
 50         __g_cursor.offset_pix = x2 - x1 + 1;
 51     } else {
 52         __g_cursor.offset_pix = x1 - x2 + 1;
 53     }
 54 
 55     //__g_cursor.last_offset = MAX_CURSOR_OFFSET;    /* 光标初始在最右 */
 56     __g_cursor.last_offset = 0;    /* 光标初始在最左 */
 57 }
 58 
 59 /**
 60  * \brief 绘制光标
 61  *
 62  * \param[in] offset:光标偏移量,以字符为单位
 63  */
 64 void draw_cursor (unsigned int offset)
 65 {
 66     if (offset == 0) {
 67         draw_rectangle(__g_cursor.x1,
 68                        __g_cursor.y1,
 69                        __g_cursor.x2 + __g_cursor.offset_pix * 3,
 70                        __g_cursor.y2);
 71         draw_rectangle(__g_cursor.x1 + 1,
 72                        __g_cursor.y1 + 1,
 73                        __g_cursor.x2 + __g_cursor.offset_pix * 3 - 1,
 74                        __g_cursor.y2 - 1);
 75     } else {
 76         draw_rectangle(__g_cursor.x1 + __g_cursor.offset_pix * (2 + 3 * offset),
 77                        __g_cursor.y1,
 78                        __g_cursor.x1 + __g_cursor.offset_pix * (4 + 3 * offset),
 79                        __g_cursor.y2);
 80         draw_rectangle(__g_cursor.x1 + __g_cursor.offset_pix * (2 + 3 * offset) + 1,
 81                        __g_cursor.y1,
 82                        __g_cursor.x1 + __g_cursor.offset_pix * (4 + 3 * offset) - 1,
 83                        __g_cursor.y2);
 84     }
 85 }
 86 
 87 /**
 88  * \brief 删除光标
 89  *
 90  * \param[in] offset:光标偏移量,以字符为单位
 91  */
 92 void delete_cursor (unsigned int offset)
 93 {
 94     color_t old_pen_color;
 95 
 96     old_pen_color = get_pen_color();
 97     set_pen_color(get_bk_color());
 98 
 99     draw_cursor(offset);
100     set_pen_color(old_pen_color);
101 }
102 
103 /**
104  * \brief 移动光标
105  *
106  * \param[in] dir:光标移动方向,-1左移一位,1右移一位,其他值无效
107  */
108 void move_cursor (int dir)
109 {
110     if ((dir == -1) && (__g_cursor.last_offset != 0)) {
111         delete_cursor(__g_cursor.last_offset);
112         __g_cursor.last_offset--;
113         draw_cursor(__g_cursor.last_offset);
114     } else if ((dir == 1) && (__g_cursor.last_offset != MAX_CURSOR_OFFSET)) {
115         delete_cursor(__g_cursor.last_offset);
116         __g_cursor.last_offset++;
117         draw_cursor(__g_cursor.last_offset);
118     }
119 }
120 
121 /**
122  * \brief 调整时间
123  *
124  * \param[in] adj:为1表示加1,为-1表示减1,其他值无效
125  */
126 void adj_time (int adj)
127 {
128     struct timeval  tv;
129     struct timezone tz;
130     struct tm *p_tm = NULL;
131 
132     if ((adj != 1) && (adj != -1)) {
133         return;
134     }
135 
136     gettimeofday(&tv, &tz);
137     p_tm = localtime(&tv.tv_sec);
138     if (p_tm == NULL) {
139         return;
140     }
141 
142     switch (__g_cursor.last_offset) {
143     case 5:     /**/
144         p_tm->tm_sec += adj;
145     break;
146 
147     case 4:     /**/
148         p_tm->tm_mon += adj;
149     break;
150         
151     case 3:     /**/
152         p_tm->tm_hour += adj;
153     break;
154 
155     case 2:        /**/
156         p_tm->tm_mday += adj;
157     break;
158 
159     case 1:        /**/
160         p_tm->tm_mon += adj;
161     break;
162 
163     case 0:        /**/
164         p_tm->tm_year += adj;
165     break;
166     }
167 
168     tv.tv_sec = mktime(p_tm);
169 
170     settimeofday(&tv, &tz);
171 }
172 
173 /**
174  * \brief 显示时间
175  */
176 void show_time (void)
177 {
178     char show_buf[32] = { 0 };
179     time_t total_sec;
180     struct tm *p_tm = NULL;
181     static int last_sec = 60;    /* 赋一个不可能达到的秒数值,确保第一秒能显示 */
182     
183     time(&total_sec);
184     p_tm = localtime(&total_sec);
185     if (p_tm == NULL) {
186         return;
187     }
188         
189     if (last_sec != p_tm->tm_sec) {
190         last_sec = p_tm->tm_sec;
191 
192         sprintf(show_buf,
193                 "%4d-%02d-%02d %02d:%02d:%02d",
194                 p_tm->tm_year + 1900,                
195                 p_tm->tm_mon  + 1,
196                 p_tm->tm_mday,
197                 p_tm->tm_hour,                
198                 p_tm->tm_min,
199                 p_tm->tm_sec);
200         
201         draw_str(__g_show_x, __g_show_y, show_buf);
202 
203         draw_cursor(__g_cursor.last_offset);
204     }
205 }
206 
207 /**
208  * \brief 按键处理函数
209  */
210 void key_handler (int key_val)
211 {
212     switch (key_val) {
213         case KEY_LEFT:
214             move_cursor(-1);
215         break;
216 
217         case KEY_RIGHT:
218             move_cursor(1);
219         break;
220 
221         case KEY_UP:
222             adj_time(1);
223             show_time();
224         break;
225 
226         case KEY_DOWN:
227             adj_time(-1);
228             show_time();
229         break;
230 
231         case KEY_OK:
232             exit(1);
233         break;
234     }
235 }
236 
237 /**
238  * \brief 该线程负责检测按键动作并移动光标,同时记录光标位置
239  */
240 void * cursor_pthread (void *p_arg)
241 {
242     int fd;
243     int key_val;
244     int ret;
245 
246     fd = open("/dev/mykey", O_RDWR);
247     if (fd == -1) {
248         printf("fail to open\n");
249     }
250 
251     while (1) {
252         read(fd, &key_val, 4);    /* 阻塞 */
253         key_handler(key_val);
254     }
255 }
256 
257 
258 int main(int argc, const char *argv[])
259 {
260     //int i = 0;
261     font_size_t font_size = FONT_SIZE_48;
262     int x, y;
263     pthread_t id;
264 
265     if (framebuffer_init()) {
266         return 0;
267     }
268 
269     full_screen(LCD_YELLOW);
270     set_pen_color(LCD_RED);
271     set_bk_color(LCD_WHITE);
272 
273     set_font_size(font_size);
274 
275     x = (480 - 19 * font_size / 2) / 2;    /* 此处的19为要显示的19个字符 */
276     if (x < 0) {
277         x = 0;
278     }
279     y = (272 - font_size) / 2;
280     __g_show_x = x;
281     __g_show_y = y;
282 
283     init_cursor(x, y, x + font_size / 2 - 1, y + font_size - 1);
284 
285     pthread_create(&id, NULL, cursor_pthread, NULL);
286 
287     while (1) {
288         show_time();
289 
290         //usleep(200 * 1000);
291         sleep(1);
292     }
293 
294     return 0;
295 }

Makefile

 1 CC = arm-none-linux-gnueabi-
 2 OBJS = main.o draw.o font_size_16.o font_size_24.o font_size_32.o  3        font_size_48.o font_size_64.o figure.o
 4 OBJ = a.out
 5 $(OBJ):$(OBJS)
 6     $(CC)gcc $^ -lpthread -o $@
 7 
 8 %.o:%.c
 9     $(CC)gcc -c $< -o $@
10 
11 .PHONY: 
12 clean:
13     rm $(OBJ) *.o
14 
15 cp:
16     sudo cp $(OBJ) ../../rootfs/home/test

figure.c

  1 #include "draw.h"
  2 
  3 /**
  4  * \brief 指定两点画一条直线
  5  */
  6 void draw_line (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
  7 {
  8     int t; 
  9     int xerr=0, yerr=0, delta_x, delta_y, distance; 
 10     int incx, incy, urow, ucol; 
 11 
 12     delta_x = x2 - x1;                             /* 计算坐标增量 */
 13     delta_y = y2 - y1; 
 14     urow = x1;
 15     ucol = y1;
 16     
 17     if(delta_x > 0) {
 18         incx = 1;                     /* 设置单步方向 */
 19     } else if (delta_x == 0) {
 20         incx = 0;                    /* 垂直线 */
 21     } else {
 22         incx = -1; 
 23         delta_x = -delta_x;
 24     }
 25     
 26     if (delta_y > 0) {
 27         incy = 1; 
 28     } else if (delta_y == 0) {
 29         incy = 0;                    /* 水平线 */
 30     } else {
 31         incy = -1; 
 32         delta_y = -delta_y;
 33     } 
 34     
 35     if (delta_x > delta_y) {
 36         distance = delta_x;         /* 选取基本增量坐标轴 */
 37     } else {
 38         distance = delta_y; 
 39     }
 40     
 41     for (t = 0; t <= distance + 1; t++)    {        /* 画线输出 */
 42         draw_point(urow , ucol);                /* 画点 */
 43         
 44         xerr += delta_x ; 
 45         yerr += delta_y ; 
 46         if (xerr > distance) { 
 47             xerr -= distance; 
 48             urow += incx; 
 49         } 
 50         if (yerr > distance) {
 51             yerr -= distance; 
 52             ucol += incy; 
 53         }
 54     }
 55 }
 56 
 57 /**
 58  * \brief 绘制一个矩形
 59  *
 60  * \param[in] (x1, y1),(x2, y2):对角坐标
 61  */
 62 void draw_rectangle (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
 63 {
 64     int i , temp;
 65 
 66     if (x1 > x2)    {
 67         temp = x1;    
 68         x1 = x2; 
 69         x2 = temp;
 70     }
 71     if (y1 > y2) {
 72         temp = y1;
 73         y1 = y2; 
 74         y2 = temp;
 75     }
 76 
 77     for (i = x1; i <= x2; i++) {
 78         draw_point(i , y1);
 79         draw_point(i , y2);
 80     }
 81     for(i = y1 + 1; i < y2; i++) {
 82         draw_point(x1 , i);
 83         draw_point(x2 , i);
 84     }
 85 }
 86 
 87 
 88 /**
 89  * \brief 绘制实心一个三角形
 90  *
 91  * \param[in] x, y:三角形顶点的坐标
 92  * \param[in] layers:组成三角形的横线数目
 93  */
 94 void draw_triangle (unsigned int x, unsigned int y, unsigned int layers)
 95 {
 96     int line_x1, line_x2, line_y;
 97     int i;
 98     
 99     if (layers > 1) {
100         draw_point(x, y);
101         layers++;
102         line_x1 = x - 1;
103         line_x2 = x + 1;
104         line_y = y + 1;
105         
106         for (i = 0; i < layers; i++) {
107             draw_line(line_x1, line_y, line_x2, line_y);
108             
109             line_x1--;
110             line_x2++;
111             line_y++;
112         }
113     }
114 }
115 
116 /**
117  * \brief 绘制一个实心倒三角形
118  *
119  * \param[in] x, y:三角形顶点的坐标
120  * \param[in] layers:组成三角形的横线数目
121  */
122 void draw_inverted_triangle (unsigned int x, unsigned int y, unsigned int layers)
123 {
124     int line_x1, line_x2, line_y;
125     int i;
126     
127     if (layers > 1) {
128         draw_point(x, y);
129         layers--;
130         line_x1 = x - 1;
131         line_x2 = x + 1;
132         line_y = y - 1;
133         
134         for (i = 0; i < layers; i++) {
135             draw_line(line_x1, line_y, line_x2, line_y);
136             
137             line_x1--;
138             line_x2++;
139             line_y--;
140         }
141     }
142 }

figure.h

 1 /**
 2  * \brief 指定两点画一条直线
 3  */
 4 extern void draw_line (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
 5 
 6 /**
 7  * \brief 绘制一个矩形
 8  *
 9  * \param[in] (x1, y1),(x2, y2):对角坐标
10  */
11 extern void draw_rectangle (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);
12 
13 /**
14  * \brief 绘制实心一个三角形
15  *
16  * \param[in] x, y:三角形顶点的坐标
17  * \param[in] layers:组成三角形的横线数目
18  */
19 extern void draw_triangle (unsigned int x, unsigned int y, unsigned int layers);
20 
21 /**
22  * \brief 绘制一个实心倒三角形
23  *
24  * \param[in] x, y:三角形顶点的坐标
25  * \param[in] layers:组成三角形的横线数目
26  */
27 extern void draw_inverted_triangle (unsigned int x, unsigned int y, unsigned int layers);

在使用时要先将用 insmod key.ko将第十二章编写好的按键驱动加载到内核中,然后运行a.out,通过按键就可以调整时间了。调整时间的关键是main.c中第126行的adj_time函数,该函数在switch语句里面直接对p_tm里的值进行加一或减一操作,无需检查数据是否符合要求。比如平年的2月是没有29号的,将2月29号用mktime函数转换得到的自动就是3月1号的值。

 

十七、完成调整时间的功能

标签:thread   handler   大小   文件描述符   结构   ota   虚拟   timezone   map   

原文地址:https://www.cnblogs.com/Suzkfly/p/10398348.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!