awtk/docs/porting_to_stm32f103ze.md

212 lines
5.5 KiB
Markdown
Raw Normal View History

2019-11-09 11:37:56 +08:00
## 将 AWTK 移植到 STM32f103ze 裸系统
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
AWTK 的可移植性很高在移植时只需要实现平台初始化、lcd 和 mainloop 三个方面的东西。本文以 STM32f103ze 为例介绍移植 AWTK 到新平台的过程。
2018-05-13 11:39:08 +08:00
### 一、平台初始化
2020-01-02 14:59:56 +08:00
除了基本的libc函数外AWTK对平台没有特别要求实现获取当前时间的函数get\_time\_ms64和sleep_ms函数即可。另外需要给GUI分配一块内存空间并调用tk\_mem\_init。
2018-06-03 11:38:15 +08:00
2019-11-09 11:37:56 +08:00
我们使用 systick 来实现 get\_time\_ms64 和 sleep\_ms 两个函数,裸系统上只需加入 src/platforms/raw/sys\_tick.c 并初始化 sys\_tick 即可。
2018-05-13 11:39:08 +08:00
2019-11-12 17:41:23 +08:00
> 以下是初始化内存的代码。
2018-06-03 11:38:15 +08:00
2019-11-09 11:37:56 +08:00
```
2019-11-12 17:41:23 +08:00
ret_t platform_prepare(void) {
2019-11-14 10:15:54 +08:00
static bool_t inited = FALSE;
static uint32_t s_heam_mem[4000];
if (!inited) {
inited = TRUE;
2019-11-12 17:41:23 +08:00
tk_mem_init(s_heam_mem, sizeof(s_heam_mem));
2019-11-14 10:15:54 +08:00
}
2019-11-12 17:41:23 +08:00
return RET_OK;
}
```
2018-06-01 18:49:53 +08:00
2019-11-12 17:41:23 +08:00
> 参考awtk-port/platform.c
2019-11-14 10:15:54 +08:00
> 以下是初始化 systick 的代码(在板子提供代码上修改而来)。
2019-11-12 17:41:23 +08:00
```
static u8 fac_us = 0;
static u16 fac_ms = 0;
2018-05-27 12:27:57 +08:00
2019-11-12 17:41:23 +08:00
void systick_enable_int(void) {
2018-06-01 18:49:53 +08:00
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD = fac_ms;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
2018-05-13 11:39:08 +08:00
}
2019-11-12 17:41:23 +08:00
void SysTick_Init(void) {
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us = SystemCoreClock / 8000000;
fac_ms = (u16)fac_us * 1000;
}
void delay_us(u32 nus) {
u32 temp = 0;
2019-11-14 10:15:54 +08:00
SysTick->LOAD = nus * fac_us;
SysTick->VAL = 0x00;
2019-11-12 17:41:23 +08:00
do {
temp = SysTick->CTRL;
2019-11-14 10:15:54 +08:00
} while ((temp & 0x01) && !(temp & (1 << 16)));
2019-11-12 17:41:23 +08:00
}
void delay_ms(u16 nms) {
u32 temp = 0;
2019-11-14 10:15:54 +08:00
SysTick->LOAD = (u32)nms * fac_ms;
SysTick->VAL = 0x00;
2019-11-12 17:41:23 +08:00
do {
temp = SysTick->CTRL;
2019-11-14 10:15:54 +08:00
} while ((temp & 0x01) && !(temp & (1 << 16)));
2018-05-13 11:39:08 +08:00
}
```
2019-11-12 17:41:23 +08:00
> 参考awtk-port/SysTick.c
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
### 二、实现 lcd
2018-05-13 11:39:08 +08:00
2019-11-14 10:15:54 +08:00
lcd\_t 接口提供基本的显示功能AWTK 提供基于*寄存器*、*帧缓冲*和*片段帧缓冲*三种缺省实现,在此基础上实现自己的 lcd\_t 接口非常方便。
2018-05-13 11:39:08 +08:00
2019-11-14 10:15:54 +08:00
stm32f103ze 使用基于*片段帧缓冲*的 lcd 的缺省实现,只需要提供 set\_window\_func 和 write\_data\_func 两个函数/宏即可。这里直接使用了 TFT\_SetWindow 和 TFT\_WriteData 两个函数。
2018-05-13 11:39:08 +08:00
2019-11-14 10:15:54 +08:00
> 直接写寄存器的方式容易闪烁,而帧缓冲又需要大量内存,片段帧缓冲能有效解决低内存平台的闪烁问题。
2018-05-27 12:27:57 +08:00
2019-11-14 10:15:54 +08:00
```
#include "tftlcd.h"
2019-11-09 11:37:56 +08:00
#include "tkc/mem.h"
2019-11-14 10:15:54 +08:00
#include "lcd/lcd_mem_fragment.h"
2018-05-13 11:39:08 +08:00
2018-05-27 12:27:57 +08:00
typedef uint16_t pixel_t;
2019-11-09 11:37:56 +08:00
#define LCD_FORMAT BITMAP_FMT_BGR565
2019-11-14 10:15:54 +08:00
#define pixel_from_rgb(r, g, b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define pixel_to_rgba(p) \
{ (0xff & ((p >> 11) << 3)), (0xff & ((p >> 5) << 2)), (0xff & (p << 3)) }
2019-11-09 11:37:56 +08:00
2019-11-14 10:15:54 +08:00
#define set_window_func LCD_Set_Window
#define write_data_func LCD_WriteData_Color
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
#include "base/pixel.h"
2018-05-27 12:27:57 +08:00
#include "blend/pixel_ops.inc"
2019-11-14 10:15:54 +08:00
#include "lcd/lcd_mem_fragment.inc"
2019-11-09 11:37:56 +08:00
2018-05-13 11:39:08 +08:00
```
> 参考 awtk-port/lcd\_stm32\_raw.c
2019-11-09 11:37:56 +08:00
### 三、实现 main\_loop
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
main\_loop 主要负责事件分发和绘制这个不断循环的过程。main\_loop\_raw.inc 里实现了裸系统 main\_loop 的基本功能,在移植时加上输入事件的的分发即可:
2018-05-13 11:39:08 +08:00
```
2019-11-14 10:15:54 +08:00
#include "key.h"
#include "led.h"
#include "rtc.h"
#include "stdlib.h"
#include "tftlcd.h"
#include "touch.h"
#include "usart.h"
#include "base/idle.h"
#include "base/timer.h"
#include "tkc/platform.h"
#include "base/main_loop.h"
#include "base/event_queue.h"
#include "base/font_manager.h"
#include "lcd/lcd_mem_fragment.h"
#include "main_loop/main_loop_simple.h"
ret_t platform_disaptch_input(main_loop_t *l) { return RET_OK; }
static lcd_t *platform_create_lcd(wh_t w, wh_t h) {
return lcd_mem_fragment_create(w, h);
2019-11-09 11:37:56 +08:00
}
2018-05-13 11:39:08 +08:00
2019-11-14 10:15:54 +08:00
void dispatch_input_events(void) {
int key = KEY_Scan(0);
switch (key) {
case KEY_UP: {
key = TK_KEY_UP;
break;
}
case KEY_DOWN: {
key = TK_KEY_DOWN;
break;
}
case KEY_LEFT: {
key = TK_KEY_RETURN;
break;
}
case KEY_RIGHT: {
key = TK_KEY_BACK;
break;
}
default: { key = 0; }
}
if (key) {
main_loop_post_key_event(main_loop(), TRUE, key);
} else {
main_loop_post_key_event(main_loop(), FALSE, key);
}
if (TOUCH_Scan() == 0) {
main_loop_post_pointer_event(main_loop(), TRUE, TouchData.lcdx,
TouchData.lcdy);
} else {
main_loop_post_pointer_event(main_loop(), FALSE, TouchData.lcdx,
TouchData.lcdy);
}
2019-11-09 11:37:56 +08:00
}
2018-05-13 11:39:08 +08:00
void TIM3_IRQHandler(void) {
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
2019-11-14 10:15:54 +08:00
dispatch_input_events();
2018-05-13 11:39:08 +08:00
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
}
#include "main_loop/main_loop_raw.inc"
```
2018-05-27 12:27:57 +08:00
> 参考 awtk-port/main\_loop\_stm32\_raw.c
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
四、Keil 设置
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
* 1. 勾选 c99
* 2. 定义 HAS\_AWTK\_CONFIG
* 3. 增加如下头文件路径:
2018-05-13 11:39:08 +08:00
2019-11-09 11:37:56 +08:00
```
2019-11-14 10:15:54 +08:00
awtk\src
awtk\3rd
awtk-port
2019-11-09 11:37:56 +08:00
```
2018-05-13 11:39:08 +08:00
2019-11-12 17:41:23 +08:00
> 请根据项目文件位置进行调整。
2019-11-09 11:37:56 +08:00
五、其它配置
其它配置请参考 awtk-port/awtk_config.h
注:目前以 [普中科技 STM32F103ZET6 开发实验板](https://item.taobao.com/item.htm?spm=a230r.1.14.1.50a130e8TMKYMC&id=558855281660&ns=1&abbucket=5#detail) 为载体移植,其它开发板应该差不多。
完整项目和源码请参考:[awtk-stm32f103ze-raw](https://github.com/zlgopen/awtk-stm32f103ze-raw)
2019-11-12 17:41:23 +08:00
六、常见问题
2019-11-14 10:15:54 +08:00
* 1.莫名其妙的崩溃,可能是栈溢出。请修 Stack_Size 的大小。
2019-11-12 17:41:23 +08:00
```
Stack_Size EQU 0x00001000
```
2019-11-14 10:15:54 +08:00
* 2.如果出现 wcsxxx 之类的函数没有定义时,请在 awtk-port/awtk\_config.h 中定义 WITH\_WCSXXX。