UART通信を用いた組み込みデバッグ用途向けメモリモニタ
Revisión | 253fc56fdb3c85f82deb393ee66458110e9c1544 (tree) |
---|---|
Tiempo | 2018-05-03 21:21:23 |
Autor | Yasushi Tanaka <tanaka_yasushi2008@yaho...> |
Commiter | Yasushi Tanaka |
漢字表示まで確認
@@ -0,0 +1,84 @@ | ||
1 | +/* | |
2 | + * Debug Monitor Framework | |
3 | + * Author: Yasushi Tanaka | |
4 | + * | |
5 | + * [ モニタエリア ] | |
6 | + */ | |
7 | + | |
8 | +#include "header.h" | |
9 | +#include "screen.h" | |
10 | +#include "monitor.h" | |
11 | + | |
12 | +/* | |
13 | + * 定数 | |
14 | + */ | |
15 | + | |
16 | +/* ウィンドウキャプション */ | |
17 | +#define MONITOR_WINDOW_NAME L"モニタ" | |
18 | + | |
19 | +/* | |
20 | + * static変数 | |
21 | + */ | |
22 | + | |
23 | +/* スクリーンオブジェクト */ | |
24 | +static SCREEN_OBJECT g_monitor_screen; | |
25 | + | |
26 | +/* | |
27 | + * モニタエリア | |
28 | + * 初期化 | |
29 | + */ | |
30 | +BOOL monitor_init(HWND parent, int x, int y, int width, int height) | |
31 | +{ | |
32 | + /* スクリーンオブジェクトを初期化 */ | |
33 | + memset(&g_monitor_screen, 0, sizeof(g_monitor_screen)); | |
34 | + | |
35 | + /* パラメータをセット */ | |
36 | + g_monitor_screen.name = MONITOR_WINDOW_NAME; | |
37 | + g_monitor_screen.parent = parent; | |
38 | + g_monitor_screen.x = x; | |
39 | + g_monitor_screen.y = y; | |
40 | + g_monitor_screen.width = width; | |
41 | + g_monitor_screen.height = height; | |
42 | + g_monitor_screen.fore_def = GetSysColor(COLOR_WINDOWTEXT); | |
43 | + g_monitor_screen.back_def = GetSysColor(COLOR_WINDOW); | |
44 | + g_monitor_screen.vscroll = FALSE; | |
45 | + | |
46 | + /* スクリーンを作成 */ | |
47 | + return screen_create(&g_monitor_screen); | |
48 | +} | |
49 | + | |
50 | +/* | |
51 | + * モニタエリア | |
52 | + * リサイズ | |
53 | + */ | |
54 | +void monitor_resize(int x, int y, int width, int height) | |
55 | +{ | |
56 | + /* パラメータをセット */ | |
57 | + g_monitor_screen.x = x; | |
58 | + g_monitor_screen.y = y; | |
59 | + g_monitor_screen.width = width; | |
60 | + g_monitor_screen.height = height; | |
61 | + | |
62 | + /* スクリーンをリサイズ */ | |
63 | + screen_resize(&g_monitor_screen); | |
64 | +} | |
65 | + | |
66 | +/* | |
67 | + * モニタエリア | |
68 | + * アイドル | |
69 | + */ | |
70 | +void monitor_idle(void) | |
71 | +{ | |
72 | + SYSTEMTIME st; | |
73 | + | |
74 | + GetLocalTime(&st); | |
75 | + screen_locate(&g_monitor_screen, 0, 0); | |
76 | + screen_printf(&g_monitor_screen, "%02d:%02d:%02d\n", st.wHour, st.wMinute, st.wSecond); | |
77 | + | |
78 | + screen_locate(&g_monitor_screen, 1, 1); | |
79 | + screen_printfw(&g_monitor_screen, L"width=%d\n", g_monitor_screen.width); | |
80 | + screen_printfw(&g_monitor_screen, L"height=%d\n", g_monitor_screen.height); | |
81 | + screen_printf(&g_monitor_screen, "文字幅=%d\n", g_monitor_screen.real.width_chr); | |
82 | + screen_printf(&g_monitor_screen, "文字高さ=%d\n", g_monitor_screen.real.height_chr); | |
83 | + screen_printf(&g_monitor_screen, "表示キャラクタ数=%04d\n", g_monitor_screen.chrs_draw); | |
84 | +} |
@@ -0,0 +1,18 @@ | ||
1 | +/* | |
2 | + * Debug Monitor Framework | |
3 | + * Author: Yasushi Tanaka | |
4 | + * | |
5 | + * [ モニタエリア ] | |
6 | + */ | |
7 | + | |
8 | +#pragma once | |
9 | + | |
10 | +/* 初期化 */ | |
11 | +BOOL monitor_init(HWND parent, int x, int y, int width, int height); | |
12 | + | |
13 | +/* リサイズ */ | |
14 | +void monitor_resize(int x, int y, int width, int height); | |
15 | + | |
16 | +/* アイドル */ | |
17 | +void monitor_idle(void); | |
18 | + |
@@ -45,7 +45,7 @@ static BOOL screen_chr_is_equal(const SCREEN_CHR *chr1, const SCREEN_CHR *chr2) | ||
45 | 45 | } |
46 | 46 | |
47 | 47 | /* 左右フラグ */ |
48 | - if (chr1->right == chr2->right) | |
48 | + if (chr1->right != chr2->right) | |
49 | 49 | { |
50 | 50 | return FALSE; |
51 | 51 | } |
@@ -144,6 +144,11 @@ static BOOL screen_realchr_draw(HDC hDC, SCREEN_REAL_CHR *chr, SCREEN_OBJECT *ob | ||
144 | 144 | /* 描画キャラクタを現在のキャラクタに更新 */ |
145 | 145 | chr->draw = chr->current; |
146 | 146 | |
147 | +#ifdef _DEBUG | |
148 | + /* 描画数++ */ | |
149 | + object->chrs_draw++; | |
150 | +#endif /* _DEBUG */ | |
151 | + | |
147 | 152 | /* TRUEを返し、描画したことを示す */ |
148 | 153 | return TRUE; |
149 | 154 | } |
@@ -435,6 +440,71 @@ static void screen_realline_invalidate(SCREEN_REAL_LINE *line) | ||
435 | 440 | |
436 | 441 | /* |
437 | 442 | * スクリーン |
443 | + * 表示ラインに文字セット | |
444 | + */ | |
445 | +static UINT screen_realline_setchr(SCREEN_REAL_LINE *line, SCREEN_OBJECT *object, wchar_t chr) | |
446 | +{ | |
447 | + UINT x; | |
448 | + | |
449 | + assert(NULL != line); | |
450 | + assert(NULL != object); | |
451 | + assert(0x0020 <= chr); | |
452 | + | |
453 | + /* x位置を取得 */ | |
454 | + x = object->real.x; | |
455 | + | |
456 | + /* x位置が範囲を超えていれば何もしない */ | |
457 | + if (line->chrs <= x) | |
458 | + { | |
459 | + return 0; | |
460 | + } | |
461 | + | |
462 | + /* 文字種類で分ける */ | |
463 | + if (0x0100 <= chr) | |
464 | + { | |
465 | + /* x位置が終端か */ | |
466 | + if (x == (line->chrs - 1)) | |
467 | + { | |
468 | + /* 半角スペースをセット */ | |
469 | + line->buf[x].current.chr = L' '; | |
470 | + line->buf[x].current.right = FALSE; | |
471 | + line->buf[x].current.fore = object->real.fore; | |
472 | + line->buf[x].current.back = object->real.back; | |
473 | + | |
474 | + object->real.x++; | |
475 | + return 1; | |
476 | + } | |
477 | + else | |
478 | + { | |
479 | + /* 全角文字をセット */ | |
480 | + line->buf[x + 0].current.chr = chr; | |
481 | + line->buf[x + 0].current.right = FALSE; | |
482 | + line->buf[x + 0].current.fore = object->real.fore; | |
483 | + line->buf[x + 0].current.back = object->real.back; | |
484 | + line->buf[x + 1].current.chr = chr; | |
485 | + line->buf[x + 1].current.right = TRUE; | |
486 | + line->buf[x + 1].current.fore = object->real.fore; | |
487 | + line->buf[x + 1].current.back = object->real.back; | |
488 | + | |
489 | + object->real.x += 2; | |
490 | + return 2; | |
491 | + } | |
492 | + } | |
493 | + else | |
494 | + { | |
495 | + /* 半角文字をセット */ | |
496 | + line->buf[x].current.chr = chr; | |
497 | + line->buf[x].current.right = FALSE; | |
498 | + line->buf[x].current.fore = object->real.fore; | |
499 | + line->buf[x].current.back = object->real.back; | |
500 | + | |
501 | + object->real.x++; | |
502 | + return 1; | |
503 | + } | |
504 | +} | |
505 | + | |
506 | +/* | |
507 | + * スクリーン | |
438 | 508 | * 表示スクリーンのリサイズ |
439 | 509 | */ |
440 | 510 | static void screen_real_resize(SCREEN_OBJECT *object) |
@@ -575,6 +645,7 @@ static BOOL screen_real_is_equal(SCREEN_OBJECT *object) | ||
575 | 645 | */ |
576 | 646 | static void screen_real_draw(HDC hDC, SCREEN_OBJECT *object) |
577 | 647 | { |
648 | + HFONT hDefFont; | |
578 | 649 | SCREEN_REAL_LINE *line; |
579 | 650 | BOOL result; |
580 | 651 | COLORREF fore_prev; |
@@ -604,6 +675,19 @@ static void screen_real_draw(HDC hDC, SCREEN_OBJECT *object) | ||
604 | 675 | } |
605 | 676 | object->back_draw = object->back_def; |
606 | 677 | |
678 | + /* フォントを選択 */ | |
679 | + hDefFont = (HFONT)SelectObject(hDC, g_hFont); | |
680 | + assert(NULL != hDefFont); | |
681 | + if (NULL == hDefFont) | |
682 | + { | |
683 | + return; | |
684 | + } | |
685 | + | |
686 | +#ifdef _DEBUG | |
687 | + /* 表示キャラクタ数をクリア */ | |
688 | + object->chrs_draw = 0; | |
689 | +#endif /* _DEBUG */ | |
690 | + | |
607 | 691 | /* ラインが存在する限りループ */ |
608 | 692 | while (NULL != line) |
609 | 693 | { |
@@ -619,6 +703,9 @@ static void screen_real_draw(HDC hDC, SCREEN_OBJECT *object) | ||
619 | 703 | /* 次のラインを得る */ |
620 | 704 | line = (SCREEN_REAL_LINE*)line->bdlist.bdlist_next; |
621 | 705 | } |
706 | + | |
707 | + /* フォントを復元 */ | |
708 | + SelectObject(hDC, hDefFont); | |
622 | 709 | } |
623 | 710 | |
624 | 711 | /* |
@@ -673,6 +760,37 @@ static void screen_real_invalidate(SCREEN_OBJECT *object) | ||
673 | 760 | } |
674 | 761 | |
675 | 762 | /* |
763 | + * スクリーン | |
764 | + * 表示スクリーンからラインを得る | |
765 | + */ | |
766 | +static SCREEN_REAL_LINE* screen_real_getline(SCREEN_OBJECT *object, UINT y) | |
767 | +{ | |
768 | + UINT loop; | |
769 | + SCREEN_REAL_LINE *line; | |
770 | + | |
771 | + assert(NULL != object); | |
772 | + | |
773 | + /* 行が超えていればNULLを返す */ | |
774 | + if (y >= object->real.lines) | |
775 | + { | |
776 | + return NULL; | |
777 | + } | |
778 | + | |
779 | + /* 最初のラインを得る */ | |
780 | + line = object->real.head; | |
781 | + | |
782 | + /* ループ */ | |
783 | + for (loop = 0; loop < y; loop++) | |
784 | + { | |
785 | + /* 次のラインを得る */ | |
786 | + line = (SCREEN_REAL_LINE*)line->bdlist.bdlist_next; | |
787 | + assert(NULL != line); | |
788 | + } | |
789 | + | |
790 | + return line; | |
791 | +} | |
792 | + | |
793 | +/* | |
676 | 794 | * スクリーン |
677 | 795 | * 仮想ラインのリサイズ |
678 | 796 | */ |
@@ -1149,9 +1267,9 @@ static LRESULT CALLBACK screen_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM | ||
1149 | 1267 | return 0; |
1150 | 1268 | |
1151 | 1269 | /* 背景を再描画する */ |
1152 | - case WM_ERASEBKGND: | |
1153 | - /* 自力でを背景を描画した場合は非ゼロを返す必要がある */ | |
1154 | - return 1; | |
1270 | +// case WM_ERASEBKGND: | |
1271 | +// /* 自力でを背景を描画した場合は非ゼロを返す必要がある */ | |
1272 | +// return 1; | |
1155 | 1273 | |
1156 | 1274 | /* ウィンドウを再描画する */ |
1157 | 1275 | case WM_PAINT: |
@@ -1260,17 +1378,15 @@ BOOL screen_create(SCREEN_OBJECT *screen) | ||
1260 | 1378 | /* スクリーン側が管理する領域 */ |
1261 | 1379 | bdlist_init((BDLIST_ENTRY*)screen); |
1262 | 1380 | memset(&screen->real, 0, sizeof(SCREEN_REAL_SCREEN)); |
1381 | + screen->real.fore = screen->fore_def; | |
1382 | + screen->real.back = screen->back_def; | |
1263 | 1383 | memset(&screen->virt, 0, sizeof(SCREEN_VIRT_SCREEN)); |
1264 | - screen->x_real = 0; | |
1265 | - screen->y_real = 0; | |
1266 | - screen->fore_real = screen->fore_def; | |
1267 | - screen->back_real = screen->back_def; | |
1268 | 1384 | screen->update = FALSE; |
1269 | 1385 | screen->destroy = FALSE; |
1270 | 1386 | screen->hwnd = NULL; |
1271 | 1387 | |
1272 | 1388 | /* ウィンドウスタイルの決定 */ |
1273 | - dwStyle = WS_CHILD | WS_VISIBLE; | |
1389 | + dwStyle = WS_CAPTION | WS_CHILD | WS_VISIBLE; | |
1274 | 1390 | if (FALSE != screen->vscroll) |
1275 | 1391 | { |
1276 | 1392 | /* 垂直スクロールバーを追加する */ |
@@ -1353,31 +1469,121 @@ void screen_locate(SCREEN_OBJECT *screen, UINT x, UINT y) | ||
1353 | 1469 | assert(NULL != screen); |
1354 | 1470 | |
1355 | 1471 | /* 記憶のみ */ |
1356 | - screen->x_real = x; | |
1357 | - screen->y_real = y; | |
1472 | + screen->real.x = x; | |
1473 | + screen->real.y = y; | |
1358 | 1474 | } |
1359 | 1475 | |
1360 | 1476 | /* |
1361 | 1477 | * スクリーン |
1362 | - * 表示ラインに書式つき出力 | |
1478 | + * 表示スクリーンへ書式つき出力 | |
1479 | + * ヘルパ関数 | |
1480 | + */ | |
1481 | +static void screen_printf_helper(SCREEN_OBJECT *screen, SCREEN_REAL_LINE *line, const wchar_t *buf) | |
1482 | +{ | |
1483 | + size_t len; | |
1484 | + UINT loop; | |
1485 | + UINT x; | |
1486 | + | |
1487 | + assert(NULL != screen); | |
1488 | + assert(NULL != line); | |
1489 | + assert(NULL != buf); | |
1490 | + | |
1491 | + /* 最初のx位置を記憶 */ | |
1492 | + x = screen->real.x; | |
1493 | + | |
1494 | + /* 文字ループ */ | |
1495 | + len = wcslen(buf); | |
1496 | + for (loop = 0; loop < len; loop++) | |
1497 | + { | |
1498 | + /* 改行か */ | |
1499 | + if (buf[loop] == L'\n') | |
1500 | + { | |
1501 | + /* 改行 */ | |
1502 | + screen->real.x = x; | |
1503 | + screen->real.y++; | |
1504 | + } | |
1505 | + else | |
1506 | + { | |
1507 | + /* セット */ | |
1508 | + screen_realline_setchr(line, screen, buf[loop]); | |
1509 | + } | |
1510 | + } | |
1511 | + | |
1512 | + /* スクリーンの更新を要求 */ | |
1513 | + screen_update_object(screen); | |
1514 | +} | |
1515 | + | |
1516 | +/* | |
1517 | + * スクリーン | |
1518 | + * 表示スクリーンへ書式つき出力(wchar_t) | |
1363 | 1519 | */ |
1364 | 1520 | void screen_printfw(SCREEN_OBJECT *screen, const wchar_t *format, ...) |
1365 | 1521 | { |
1366 | 1522 | wchar_t buf[0x400]; |
1367 | 1523 | va_list ap; |
1368 | 1524 | SCREEN_REAL_LINE *line; |
1369 | - UINT loop; | |
1370 | 1525 | |
1371 | 1526 | assert(NULL != screen); |
1372 | 1527 | assert(NULL != format); |
1373 | 1528 | |
1374 | - /* screen->y_realだけ移動したlineを得る */ | |
1529 | + /* lineを得る */ | |
1530 | + line = screen_real_getline(screen, screen->real.y); | |
1531 | + if (NULL == line) | |
1532 | + { | |
1533 | + return; | |
1534 | + } | |
1375 | 1535 | |
1376 | 1536 | /* フォーマット */ |
1377 | - va_satrt(ap, format); | |
1537 | + va_start(ap, format); | |
1378 | 1538 | vswprintf_s(buf, _countof(buf), format, ap); |
1379 | 1539 | buf[_countof(buf) - 1] = L'\0'; |
1380 | 1540 | va_end(ap); |
1381 | 1541 | |
1382 | - /* */ | |
1542 | + /* ヘルパ関数 */ | |
1543 | + screen_printf_helper(screen, line, buf); | |
1544 | +} | |
1545 | + | |
1546 | +/* | |
1547 | + * スクリーン | |
1548 | + * 表示スクリーンへ書式つき出力(char) | |
1549 | + */ | |
1550 | +void screen_printf(SCREEN_OBJECT *screen, const char *format, ...) | |
1551 | +{ | |
1552 | + char multibyte[0x400]; | |
1553 | + wchar_t buf[0x400]; | |
1554 | + va_list ap; | |
1555 | + SCREEN_REAL_LINE *line; | |
1556 | + int result; | |
1557 | + | |
1558 | + assert(NULL != screen); | |
1559 | + assert(NULL != format); | |
1560 | + | |
1561 | + /* lineを得る */ | |
1562 | + line = screen_real_getline(screen, screen->real.y); | |
1563 | + if (NULL == line) | |
1564 | + { | |
1565 | + return; | |
1566 | + } | |
1567 | + | |
1568 | + /* フォーマット */ | |
1569 | + va_start(ap, format); | |
1570 | + vsprintf_s(multibyte, _countof(multibyte), format, ap); | |
1571 | + multibyte[_countof(multibyte) - 1] = '\0'; | |
1572 | + va_end(ap); | |
1573 | + | |
1574 | + /* ワイド文字へ変換 */ | |
1575 | + result = MultiByteToWideChar( | |
1576 | + CP_ACP, | |
1577 | + MB_PRECOMPOSED, | |
1578 | + multibyte, | |
1579 | + -1, | |
1580 | + buf, | |
1581 | + _countof(buf)); | |
1582 | + if (0 == result) | |
1583 | + { | |
1584 | + return; | |
1585 | + } | |
1586 | + | |
1587 | + /* ヘルパ関数 */ | |
1588 | + screen_printf_helper(screen, line, buf); | |
1383 | 1589 | } |
@@ -77,6 +77,18 @@ typedef struct _SCREEN_REAL_SCREEN | ||
77 | 77 | /* ラインの数 */ |
78 | 78 | UINT lines; |
79 | 79 | |
80 | + /* カーソル位置のx座標 */ | |
81 | + UINT x; | |
82 | + | |
83 | + /* カーソル位置のy座標 */ | |
84 | + UINT y; | |
85 | + | |
86 | + /* カーソル位置のフォアグラウンドカラー */ | |
87 | + COLORREF fore; | |
88 | + | |
89 | + /* カーソル位置のバックグラウンドカラー */ | |
90 | + COLORREF back; | |
91 | + | |
80 | 92 | /* 最初のライン */ |
81 | 93 | SCREEN_REAL_LINE *head; |
82 | 94 | } SCREEN_REAL_SCREEN; |
@@ -144,7 +156,7 @@ typedef struct _SCREEN_OBJECT | ||
144 | 156 | /* デフォルトのフォアグラウンドカラー */ |
145 | 157 | COLORREF fore_def; |
146 | 158 | |
147 | - /* デフォルトのバックグラウンドカラー */ | |
159 | + /* デフ4ォルトのバックグラウンドカラー */ | |
148 | 160 | COLORREF back_def; |
149 | 161 | |
150 | 162 | /* |
@@ -163,17 +175,10 @@ typedef struct _SCREEN_OBJECT | ||
163 | 175 | /* 描画中のバックグラウンドカラー */ |
164 | 176 | COLORREF back_draw; |
165 | 177 | |
166 | - /* 表示スクリーンのx座標 */ | |
167 | - UINT x_real; | |
168 | - | |
169 | - /* 表示スクリーンのy座標 */ | |
170 | - UINT y_real; | |
171 | - | |
172 | - /* 表示スクリーンのフォアグラウンドカラー */ | |
173 | - COLORREF fore_real; | |
174 | - | |
175 | - /* 表示スクリーンのバックグラウンドカラー */ | |
176 | - COLORREF back_real; | |
178 | +#ifdef _DEBUG | |
179 | + /* 描画したキャラクタ数 */ | |
180 | + UINT chrs_draw; | |
181 | +#endif /* _DEBUG */ | |
177 | 182 | |
178 | 183 | /* 更新要求フラグ */ |
179 | 184 | BOOL update; |
@@ -204,5 +209,8 @@ void screen_idle(void); | ||
204 | 209 | /* 表示スクリーンの位置を指定 */ |
205 | 210 | void screen_locate(SCREEN_OBJECT *screen, UINT x, UINT y); |
206 | 211 | |
207 | -/* 表示スクリーンへ書式つき出力 */ | |
212 | +/* 表示スクリーンへ書式つき出力(wchar_t) */ | |
208 | 213 | void screen_printfw(SCREEN_OBJECT *screen, const wchar_t *format, ...); |
214 | + | |
215 | +/* 表示スクリーンへ書式つき出力(char) */ | |
216 | +void screen_printf(SCREEN_OBJECT *screen, const char *format, ...); |
@@ -602,6 +602,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine | ||
602 | 602 | else |
603 | 603 | { |
604 | 604 | /* アイドル処理 */ |
605 | + screen_idle(); | |
605 | 606 | monitor_idle(); |
606 | 607 | |
607 | 608 | /* 必ずSleepを入れる */ |