#define RT_APP_PART_ADDR 0x08010000
extern const struct fal_flash_dev stm32_onchip_flash;
/* flash device table */
#define FAL_FLASH_DEV_TABLE \
{ \
&stm32_onchip_flash, \
}
/* ====================== Partition Configuration ========================== */
#ifdef FAL_PART_HAS_TABLE_CFG
/* partition table */
#define FAL_PART_TABLE \
{ \
{FAL_PART_MAGIC_WROD, "app", "onchip_flash", 64* 1024, 512 * 1024, 0}, \
{FAL_PART_MAGIC_WROD, "download", "onchip_flash", 576* 1024, 384 * 1024, 0}, \
}
#endif /* FAL_PART_HAS_TABLE_CFG */
#endif /* _FAL_CFG_H_ */
后发现是我使用了硬件SPI的u8g2,导致片内flash擦写失败,提示:[E/FAL] (fal_partition_erase:510) Partition erase error! Flash device(onchip_flash) erase error!
去掉u8g2线程初始化就正常擦写,后来新建工程只添加硬件SPI 和FAL,还是同样的状况,使用的是ST官方的L496ZG开发板,rtt4.0.2,最新软件包
u8g2程序:
#include "menu.h"
struct menu_entry_type
{
const uint8_t *font;
uint16_t icon;
const char *name;
};
struct menu_state
{
int16_t menu_start; /* in pixel */
int16_t frame_position; /* in pixel */
uint8_t position; /* position, array index */
};
/*
Icon configuration
Width and height must match the icon font size
GAP: Space between the icons
BGAP: Gap between the display border and the cursor.
*/
#define ICON_WIDTH 32
#define ICON_HEIGHT 32
#define ICON_GAP 4
#define ICON_BGAP 16
#define ICON_Y 32+ ICON_GAP
static struct menu_entry_type menu_entry_list[] =
{
{ u8g2_font_open_iconic_play_4x_t, 77,"音乐播放" },
{ u8g2_font_open_iconic_mime_4x_t, 64,"收音机" },
{ u8g2_font_open_iconic_embedded_4x_t, 70,"心率检测" },
{ u8g2_font_open_iconic_embedded_4x_t, 74,"蓝牙连接" },
{ u8g2_font_open_iconic_embedded_4x_t, 66,"关于" },
{ NULL, 0, NULL }
};
static void draw(struct menu_state *state)
{
int16_t x;
uint8_t i;
x = state->menu_start;
i = 0;
while( menu_entry_list[i].icon > 0 )
{
if ( x >= -ICON_WIDTH && x < u8g2.getDisplayWidth() )
{
u8g2.setFont(menu_entry_list[i].font);
u8g2.drawGlyph(x, ICON_Y, menu_entry_list[i].icon );
}
i++;
x += ICON_WIDTH + ICON_GAP;
}
u8g2.drawFrame(state->frame_position-1, ICON_Y-ICON_HEIGHT-1, ICON_WIDTH+2, ICON_WIDTH+2);
u8g2.drawFrame(state->frame_position-2, ICON_Y-ICON_HEIGHT-2, ICON_WIDTH+4, ICON_WIDTH+4);
u8g2.drawFrame(state->frame_position-3, ICON_Y-ICON_HEIGHT-3, ICON_WIDTH+6, ICON_WIDTH+6);
}
static void to_right(struct menu_state *state)
{
if ( menu_entry_list[state->position+1].font != NULL )
{
if ( (int16_t)state->frame_position+ 2*(int16_t)ICON_WIDTH + (int16_t)ICON_BGAP < (int16_t)u8g2.getDisplayWidth() )
{
state->position++;
state->frame_position += ICON_WIDTH + (int16_t)ICON_GAP;
}
else
{
state->position++;
state->frame_position = (int16_t)u8g2.getDisplayWidth() - (int16_t)ICON_WIDTH - (int16_t)ICON_BGAP;
state->menu_start = state->frame_position - state->position*((int16_t)ICON_WIDTH + (int16_t)ICON_GAP);
}
}
}
static void to_left(struct menu_state *state)
{
if ( state->position > 0 )
{
if ( (int16_t)state->frame_position >= (int16_t)ICON_BGAP+(int16_t)ICON_WIDTH+ (int16_t)ICON_GAP )
{
state->position--;
state->frame_position -= ICON_WIDTH + (int16_t)ICON_GAP;
}
else
{
state->position--;
state->frame_position = ICON_BGAP;
state->menu_start = state->frame_position - state->position*((int16_t)ICON_WIDTH + (int16_t)ICON_GAP);
}
}
}
static uint8_t towards_int16(int16_t *current, int16_t dest)
{
if ( *current < dest )
{
(*current)++;
return 1;
}
else if ( *current > dest )
{
(*current)--;
return 1;
}
return 0;
}
static uint8_t towards(struct menu_state *current, struct menu_state *destination)
{
uint8_t r = 0;
r |= towards_int16( &(current->frame_position), destination->frame_position);
r |= towards_int16( &(current->frame_position), destination->frame_position);
r |= towards_int16( &(current->menu_start), destination->menu_start);
r |= towards_int16( &(current->menu_start), destination->menu_start);
return r;
}
static struct menu_state current_state = { ICON_BGAP, ICON_BGAP, 0 };
static struct menu_state destination_state = { ICON_BGAP, ICON_BGAP, 0 };
static void music_entry(void)
{
...
}
static void fm_entry(void)
{
...
}
static void health_entry(void)
{
...
}
static void bluetooth_entry(void)
{
...
}
static void menu_entry(void *parameter)
{
u8g2.begin(/*Select=*/ U8G2_PIN_SELECT, /*Right/Next=*/ U8G2_PIN_RIGHT, /*Left/Prev=*/ U8G2_PIN_LEFT, /*Up=*/ U8G2_PIN_UP, /*Down=*/ U8G2_PIN_DOWN, /*Home/Cancel=*/ U8G2_PIN_HOME);
u8g2.enableUTF8Print();
u8g2.setFont(u8g2_font_wqy14_t_gb2312);
u8g2.setContrast(128);
u8g2.clearBuffer();
u8g2.setCursor(30, 20);
u8g2.print("欢迎使用");
u8g2.sendBuffer();
rt_thread_mdelay(5000);
u8g2.clearBuffer();
u8g2.setCursor(30, 20);
u8g2.print("初始化中");
u8g2.setCursor(0, 50);
u8g2.print("请耐心等待系统启动");
u8g2.sendBuffer();
rt_sem_take(init_sem, RT_WAITING_FOREVER);
while(1)
{
int8_t event;
do
{
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x12_tr);
draw(¤t_state);
u8g2.setFont(u8g2_font_wqy14_t_gb2312);
u8g2.setCursor((u8g2.getDisplayWidth()-u8g2.getUTF8Width(menu_entry_list[destination_state.position].name))/2,u8g2.getDisplayHeight()-5);
u8g2.print(menu_entry_list[destination_state.position].name);
u8g2.sendBuffer();
rt_thread_mdelay(10);
event = u8g2.getMenuEvent();
if ( event == U8X8_MSG_GPIO_MENU_NEXT )
to_right(&destination_state);
if ( event == U8X8_MSG_GPIO_MENU_PREV )
to_left(&destination_state);
if ( event == U8X8_MSG_GPIO_MENU_UP )
rt_device_write(serial, 0, "AT+CE\r\n", sizeof("AT+CE\r\n"));
if ( event == U8X8_MSG_GPIO_MENU_DOWN )
rt_device_write(serial, 0, "AT+CF\r\n", sizeof("AT+CF\r\n"));
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
{
if ( destination_state.position == 0 )
{
music_entry();
}
else if ( destination_state.position == 1 )
fm_entry();
else if ( destination_state.position == 2 )
health_entry();
else if ( destination_state.position == 3 )
bluetooth_entry();
else if ( destination_state.position == 4 )
{
u8g2.userInterfaceMessage(menu_entry_list[destination_state.position].name,"", "", " Ok ");
}
else
{
rt_kprintf ("position : %10d\r\n",destination_state.position);
}
}
} while ( towards(¤t_state, &destination_state) );
rt_thread_mdelay(10);
}
}
int rt_hw_menu_port(void)
{
menu = rt_thread_create("menu",
menu_entry, RT_NULL,
2048,
3, 10);
if (menu != RT_NULL)
rt_thread_startup(menu);
return 0;
}
INIT_APP_EXPORT(rt_hw_menu_port);
MSH_CMD_EXPORT(rt_hw_menu_port,1);
你的BootLoader设置的download区大小跟程序里设置好像不太一样。
BootLoader里是0x70000,程序里是0x60000。
把这两个地方改一致试试看能不能解决你的问题吧。
用的那款mcu
@JQRR_7669 您好,我试了一下,还是失败
fal probe download
Probed a flash partition | download | flash_dev: onchip_flash | offset: 589824 | len: 458752 |.
msh />fal erase 0 4906
[E/FAL] (fal_partition_erase:510) Partition erase error! Flash device(onchip_flash) erase error!
This operate has an error. Error code: -1.
msh />
找到问题原因了,使用硬件SPI 的u8g2之后flash无法擦写,注释掉u8g2初始化线程就正常擦写
您好,我之前设置是一样的,后来想改小点试试才变小的
我尝试手动清除也失败
@Silly_roe_deer 你这手动清除地址+长度太大了,都超过了最大地址,肯定失败