标签: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