arm/tlsr82: ble performance optimize and problems solve.
RF and system timer interrupt are used for ble. tlsr82_flash.c: 1. BLE will loss packets during flash operation beacause the interrupt is disabled and the operation take too long (especially erasing, about 100ms), so allow RF and system timer interrupt during flash operation; 2. Add sched_lock()/sched_unlock() to avoid the task switch in ble and system timer interrupt; flash_boot_ble.ld: 3. Because of 1, the code executes in RF and system timer interrupt must be in ram to avoid bus error. The sem_post() will be called and const variable g_tasklisttable will be accessed in RF and system timer interrupt handler; 4. To improve the performance, copy some frequently called function to ram as well, such as: sem_take(), sched_lock(), sched_unlock(), some lib functions, some zephyr ble functions and some tinycrypt functions; 5. The RF and system timer interrupt handler will call some libgcc functions, so copy all the libgcc functions to ram exclude _divdi3.o, _udivdi3.o and _umoddi3.o; tlsr82_serial.c 6. Make up_putc() be thread safe, add enter/leave_critical_section() in function uart_send_byte(); tc32_doirq.c 7. Increase the RF and system timer interrupt response priority; Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
parent
b88a8cf39f
commit
360e319959
@ -78,6 +78,15 @@ static int locate_code(".ram_code") tc32_getirq(void)
|
||||
|
||||
value = IRQ_SRC_REG & IRQ_MASK_REG;
|
||||
|
||||
if ((value & BIT(NR_RF_IRQ)) != 0)
|
||||
{
|
||||
return NR_RF_IRQ;
|
||||
}
|
||||
else if ((value & BIT(NR_SYSTEM_TIMER_IRQ)) != 0)
|
||||
{
|
||||
return NR_SYSTEM_TIMER_IRQ;
|
||||
}
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
irq = NR_IRQS;
|
||||
@ -102,7 +111,7 @@ static int locate_code(".ram_code") tc32_getirq(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm_ack_irq(int irq)
|
||||
void locate_code(".ram_code") arm_ack_irq(int irq)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include "hardware/tlsr82_mspi.h"
|
||||
#include "hardware/tlsr82_irq.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@ -88,6 +89,69 @@
|
||||
#define FLASH_CMD_READ_UID1 0x4b
|
||||
#define FLASH_CMD_READ_UID2 0x5a
|
||||
|
||||
/* Flash lock/unlock macros definitions */
|
||||
|
||||
#ifndef CONFIG_TLSR8278_BLE_SDK
|
||||
|
||||
#define FLASH_LOCK_INIT() \
|
||||
irqstate_t _flags;
|
||||
|
||||
#define FLASH_LOCK() \
|
||||
do \
|
||||
{ \
|
||||
_flags = enter_critical_section(); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define FLASH_UNLOCK() \
|
||||
do \
|
||||
{ \
|
||||
leave_critical_section(_flags); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#else
|
||||
|
||||
/* When enable the ble sdk, we can not disable the system timer
|
||||
* and rf(ble) interrupt to avoid loss of ble packets. We also
|
||||
* need to call sched_lock()/sched_unlock() to avoid task switch
|
||||
* beacause sem_post() will be called in ble interrupt (Task
|
||||
* switch may leads that the chip execute code in flash during
|
||||
* the operation of flash).
|
||||
*/
|
||||
|
||||
#define IRQ_MASK_RF_SYSTIMER ((1 << NR_SYSTEM_TIMER_IRQ) | \
|
||||
(1 << NR_RF_IRQ))
|
||||
|
||||
#define FLASH_LOCK_INIT() \
|
||||
irqstate_t _flags; \
|
||||
uint32_t _mask;
|
||||
|
||||
#define FLASH_LOCK() \
|
||||
do \
|
||||
{ \
|
||||
sched_lock(); \
|
||||
_flags = enter_critical_section(); \
|
||||
_mask = IRQ_MASK_REG & \
|
||||
(~IRQ_MASK_RF_SYSTIMER); \
|
||||
IRQ_MASK_REG &= IRQ_MASK_RF_SYSTIMER; \
|
||||
leave_critical_section(_flags); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define FLASH_UNLOCK() \
|
||||
do \
|
||||
{ \
|
||||
_flags = enter_critical_section(); \
|
||||
IRQ_MASK_REG = _mask | \
|
||||
(IRQ_MASK_REG & IRQ_MASK_RF_SYSTIMER); \
|
||||
leave_critical_section(_flags); \
|
||||
sched_unlock(); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -222,9 +286,10 @@ void locate_code(".ram_code") tlsr82_flash_read(uint8_t cmd, uint32_t addr,
|
||||
uint8_t *buf, uint32_t len)
|
||||
{
|
||||
int i;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
FLASH_LOCK_INIT();
|
||||
|
||||
FLASH_LOCK();
|
||||
|
||||
flash_send_cmd(cmd);
|
||||
|
||||
@ -265,7 +330,7 @@ void locate_code(".ram_code") tlsr82_flash_read(uint8_t cmd, uint32_t addr,
|
||||
|
||||
MSPI_CS_HIGH();
|
||||
|
||||
leave_critical_section(flags);
|
||||
FLASH_UNLOCK();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -290,9 +355,10 @@ void locate_code(".ram_code") tlsr82_flash_write(uint8_t cmd, uint32_t addr,
|
||||
uint32_t len)
|
||||
{
|
||||
int i;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
FLASH_LOCK_INIT();
|
||||
|
||||
FLASH_LOCK();
|
||||
|
||||
flash_send_cmd(FLASH_CMD_WRITE_ENABLE);
|
||||
flash_send_cmd(cmd);
|
||||
@ -320,7 +386,7 @@ void locate_code(".ram_code") tlsr82_flash_write(uint8_t cmd, uint32_t addr,
|
||||
|
||||
flash_wait_done();
|
||||
|
||||
leave_critical_section(flags);
|
||||
FLASH_UNLOCK();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -611,15 +611,30 @@ static inline uint8_t uart_read_byte(int uart_num)
|
||||
****************************************************************************/
|
||||
|
||||
static inline void uart_send_byte(uint8_t byte)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
while (UART_GET_TX_BUF_CNT() > 7);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
if (UART_GET_TX_BUF_CNT() <= 7)
|
||||
{
|
||||
UART_BUF(uart_txindex) = byte;
|
||||
|
||||
/* Cycle the four register 0x90 0x91 0x92 0x93 */
|
||||
|
||||
uart_txindex++;
|
||||
uart_txindex &= 0x03;
|
||||
|
||||
leave_critical_section(flags);
|
||||
return;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -22,7 +22,11 @@ include $(TOPDIR)/.config
|
||||
include $(TOPDIR)/tools/Config.mk
|
||||
include $(TOPDIR)/arch/arm/src/tlsr82/Toolchain.defs
|
||||
|
||||
ifeq ($(CONFIG_TLSR8278_BLE_SDK),y)
|
||||
ARCHSCRIPT = $(BOARD_DIR)$(DELIM)scripts$(DELIM)flash_boot_ble.ld
|
||||
else
|
||||
ARCHSCRIPT = $(BOARD_DIR)$(DELIM)scripts$(DELIM)flash_boot.ld
|
||||
endif
|
||||
|
||||
ARCHCFLAGS += -DMCU_CORE_B87=1 -fms-extensions -std=gnu99
|
||||
ARCHPICFLAGS += -fpic
|
||||
|
213
boards/arm/tlsr82/tlsr8278adk80d/scripts/flash_boot_ble.ld
Normal file
213
boards/arm/tlsr82/tlsr8278adk80d/scripts/flash_boot_ble.ld
Normal file
@ -0,0 +1,213 @@
|
||||
/****************************************************************************
|
||||
* board/arm/src/tlsr82/tlsr8278adk80d/scripts/flash_boot_ble.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* to tell the linker the program begin from __start label in cstartup.s,
|
||||
* thus do not treat it as a unused symbol
|
||||
*/
|
||||
|
||||
ENTRY(__start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x0;
|
||||
.vectors :
|
||||
{
|
||||
*(.vectors)
|
||||
|
||||
/* MUST as follows, when compile with -ffunction-sections
|
||||
* -fdata-sections, session name may changed
|
||||
*/
|
||||
|
||||
*(.vectors.*)
|
||||
}
|
||||
|
||||
.ram_code :
|
||||
{
|
||||
PROVIDE(_sramcode = ABSOLUTE(.));
|
||||
*(.ram_code)
|
||||
*(.ram_code.*)
|
||||
|
||||
/* RF and system timer interrupt handler may call the libgcc
|
||||
* functions, to make sure the RF and system timer interrupt
|
||||
* handler do not execute falsh code, copy all the libgcc code
|
||||
* to ram (exclude _divdi3, _udivdi3 and _umoddi3).
|
||||
*/
|
||||
|
||||
*libgcc.a:*(EXCLUDE_FILE(_divdi3.o _udivdi3.o _umoddi3.o) .text)
|
||||
|
||||
/* Copy some scheduler related functions and read only data to ram
|
||||
* to improve the performance and make sure the RF and system timer
|
||||
* interrupt handler do not execute falsh code.
|
||||
*/
|
||||
|
||||
*libarch.a:arm_interruptcontext.o(.text .text.*)
|
||||
*libarch.a:arm_doirq.o(.text .text.*)
|
||||
*libarch.a:arm_unblocktask.o(.text .text.*)
|
||||
*libarch.a:arm_blocktask.o(.text .text.*)
|
||||
*libarch.a:arm_releasepending.o(.text .text.*)
|
||||
|
||||
*libsched.a:nx_start.o(.rodata .rodata.g_tasklisttable)
|
||||
*libsched.a:sem_post.o(.text .text.*)
|
||||
*libsched.a:nxsem_post.o(.text .text.*)
|
||||
*libsched.a:sem_wait.o(.text .text.*)
|
||||
*libsched.a:nxsem_wait.o(.text .text.*)
|
||||
*libsched.a:wd_cancel.o(.text .text.*)
|
||||
*libsched.a:sched_removeblocked.o(.text .text.*)
|
||||
*libsched.a:sched_addreadytorun.o(.text .text.*)
|
||||
*libsched.a:sched_addprioritized.o(.text .text.*)
|
||||
*libsched.a:sched_mergepending.o(.text .text.*)
|
||||
*libsched.a:sched_lock.o(.text .text.*)
|
||||
*libsched.a:sched_unlock.o(.text .text.*)
|
||||
*libsched.a:irq_dispatch.o(.text .text.*)
|
||||
|
||||
/* Copy some libs fundamental functions to ram to improve the
|
||||
* performance.
|
||||
*/
|
||||
|
||||
*libc.a:dq_rem.o(.text .text.*)
|
||||
*libc.a:sq_remfirst.o(.text .text.*)
|
||||
*libc.a:sq_remafter.o(.text .text.*)
|
||||
*libc.a:lib_memcmp.o(.text .text.*)
|
||||
*libc.a:lib_memcpy.o(.text .text.*)
|
||||
*libc.a:lib_strlen.o(.text .text.*)
|
||||
*libc.a:lib_strcmp.o(.text .text.*)
|
||||
*libc.a:lib_strncmp.o(.text .text.*)
|
||||
|
||||
/* Copy some zephyr ble functions to ram_code to improve the
|
||||
* performance.
|
||||
*/
|
||||
|
||||
*libapps.a:*.zblue.o(.text.work_queue_main)
|
||||
*libapps.a:*.zblue.o(.text.work_timeout)
|
||||
|
||||
*libapps.a:*.zblue.o(.text.atomic_and)
|
||||
*libapps.a:*.zblue.o(.text.atomic_get)
|
||||
*libapps.a:*.zblue.o(.text.atomic_or)
|
||||
*libapps.a:*.zblue.o(.text.atomic_set)
|
||||
*libapps.a:*.zblue.o(.text.atomic_sub)
|
||||
|
||||
*libapps.a:*.zblue.o(.text.arch_irq_lock)
|
||||
*libapps.a:*.zblue.o(.text.arch_irq_unlock)
|
||||
|
||||
*libapps.a:*.zblue.o(.text.k_sem_give)
|
||||
|
||||
*libapps.a:*.zblue.o(.text.net_buf_simple_add)
|
||||
*libapps.a:*.zblue.o(.text.net_buf_simple_pull)
|
||||
|
||||
/* Copy some tinycrypt functions to ram_code to improve the
|
||||
* performance.
|
||||
*/
|
||||
|
||||
*libapps.a:*.tinycrypt.o(.text.uECC_vli_add)
|
||||
*libapps.a:*.tinycrypt.o(.text.uECC_vli_sub)
|
||||
*libapps.a:*.tinycrypt.o(.text.uECC_vli_set)
|
||||
PROVIDE(_eramcode = ABSOLUTE(.));
|
||||
}
|
||||
|
||||
PROVIDE(_ramcode_size_ = . );
|
||||
PROVIDE(_ramcode_size_div_16_ = (. + 15 ) / 16);
|
||||
PROVIDE(_ramcode_size_div_256_ = (. + 255) / 256);
|
||||
PROVIDE(_ramcode_size_div_16_align_256_ = ( (. + 255) / 256) * 16);
|
||||
PROVIDE(_ramcode_size_align_256_ = ( (. + 255) / 256) * 256);
|
||||
|
||||
. = _ramcode_size_align_256_ ; /* >= (_ictag_start_ - 0x840000)*/
|
||||
|
||||
.text :
|
||||
{
|
||||
PROVIDE(_stext = ABSOLUTE(.));
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
PROVIDE(_etext = ABSOLUTE(.));
|
||||
}
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_rstored_ = . );
|
||||
PROVIDE(_code_size_ = .);
|
||||
|
||||
/* __LOAD_FLASH for MCU RUN IN Flash 0x100 alighned, must greater
|
||||
* than or equal to : 0x808000 + ram_code_size + irq_vector(0x100) +
|
||||
* IC_tag(0x100) + IC_cache(0x800) == 0x808a00 + ram_code_size
|
||||
*
|
||||
* __LOAD_DUT for MCU RUN IN SRAM, this setting is used for DUT
|
||||
* Test and bin size is limited to 8k
|
||||
*
|
||||
* __LOAD_RAM for MCU RUN IN SRAM
|
||||
*/
|
||||
|
||||
. = (0x840000 + ((0x900 + _ramcode_size_align_256_) * __LOAD_FLASH) + (0x400 * __LOAD_DUT) + (_rstored_ * __LOAD_RAM));
|
||||
|
||||
.retention_data : AT ( _rstored_ )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_retention_data_start_ = . );
|
||||
*(.retention_data)
|
||||
*(.retention_data.*)
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_retention_data_end_ = . );
|
||||
}
|
||||
PROVIDE(_dstored_ = _rstored_ + _retention_data_end_ - _retention_data_start_);
|
||||
|
||||
.my_code(NOLOAD) :
|
||||
{
|
||||
*(.spi_slave_buff)
|
||||
}
|
||||
|
||||
.data : AT ( _dstored_ )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_start_data_ = . );
|
||||
*(.data);
|
||||
*(.data.*);
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_end_data_ = . );
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE(_sbss = .);
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
}
|
||||
|
||||
/* data in ram but no need to clean in .s*/
|
||||
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.noinit)
|
||||
*(.noinit.*)
|
||||
}
|
||||
. = ALIGN(4);
|
||||
|
||||
PROVIDE(_ebss = .);
|
||||
PROVIDE(_bin_size_ = _code_size_ + _end_data_ - _start_data_ + _retention_data_end_ - _retention_data_start_ );
|
||||
PROVIDE(_bin_size_div_16 = ( _bin_size_ + 15 ) / 16 );
|
||||
PROVIDE(_ictag_start_ = 0x840000 + _ramcode_size_align_256_ );
|
||||
PROVIDE(_ictag_end_ = 0x840000 + _ramcode_size_align_256_ + 0x100);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user