- 2024-12-21
-
回复了主题帖:
少量几片有BGA封装的PCB,可以不沉金吗
BGA封装的芯片最好还是采用沉金工艺的裸板,喷锡工艺的裸板如果仔细对比会发现焊盘上喷锡精度较差容易导致引脚短路(针对一般工艺精度的裸板厂),BGA封装引脚短路的话还不容易检查
-
发表了主题帖:
《Linux内核深度解析》 U-Boot初次编译
本次在ubuntu上对U-Boot进行实际编译。
因为是新安装的ubuntu用于本次活动,所以需要先在ubuntu上安装gcc编译器:sudo apt install gcc-arm-linux-gnueabihf
清理U-Boot源码:make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm distclean
再查看U-Boot源码文件夹,目前没有MLO和u-boot.img文件
接着利用U-Boot源码中的“configs/am335x_evm_defconfig”文件对U-Boot编译选项进行配置,并保存编译选项配置信息至当前目录新生成的.config文件中。
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am335x_evm_defconfig
启动menuconfig配置界面,根据需要进行配置后保存即可
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
编译U-Boot: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j 4
编译完成后在U-Boot源码根目录下生成U-Boot镜像文件MLO、u-boot.img(如下图所示)。U-Boot启动过程可以分第一阶段和第二阶段,其中MLO是启动第一阶段镜像文件,u-boot.img是启动第二阶段镜像文件,在上一节的 《Linux内核深度解析》 U-Boot程序之程序启动流程简介及SPL阶段芯片配置 已经进行过简单介绍 :https://bbs.eeworld.com.cn/thread-1302342-1-1.html。
-
回复了主题帖:
《Linux内核深度解析》 ---- 序言阅读及相关资源获取
oxlm_1 发表于 2024-12-21 09:42
指南在这
收到,谢谢。这个没有中文版?英文版可以直接下载,内容太多了,看起来太费时间
- 2024-12-20
-
发表了主题帖:
《Linux内核深度解析》 书籍封面及目录
收到书籍后先阅读了部分内容,书籍对于内核源码讲解的非常详细,对照着本书去阅读源码对于linux内核会有更深层次的理解,以下是书籍封面及目录
-
回复了主题帖:
嵌入linux的学习方法
发表于2009-6-17 14:38 ,楼主牛!那时候刚毕业,还在玩51单片机,楼主已经搞起了linux
-
回复了主题帖:
《Linux内核深度解析》 ---- 序言阅读及相关资源获取
这本书讲的很细,跟着书籍去看代码挺不错的。
顺带请问 下面这个电子档能帮忙放在附件吗?直接下载来看看。那个论坛没有账号
-
回复了主题帖:
《Linux内核深度解析》 ---- 序言阅读及相关资源获取
一直用source insight看代码的,有时在source insight上面修改好再传到ubuntu,感觉挺好用的
-
回复了主题帖:
想问一下我想做一个这样的机械蝴蝶玩,用stm32控制器行吗,零基础怎么从0开始
这种方案能搞定,用低功耗小封装单片机,小尺寸电机,锂电池供电,不过从零学着弄就有点牛了
-
回复了主题帖:
松下伺服电机连接Ethercat转profinet网关
bigbat 发表于 2024-12-20 09:42
因为西门子的PLC不支持Ethercat。然而西门子又绕不过去。国产厂家多数都是codesys的系统,基本上都是支持 ...
这的确是,有些大公司(尤其国外客户)指定需要用西门子的PLC(因为他们会用,或者是只会用西门子PLC)。国内现在做的运动控制器直接集成了运动控制和PLC功能,不需要额外的PLC了
-
回复了主题帖:
PIC 单片机 C 程序 MAPLAB 编译出错是什么原因?
fcluy 发表于 2024-12-19 22:29
是源程序过长的原因吗?
应该不是源程序过长的问题,看起来像是头文件或者变量名缺失。
如果程序可以外传,放源代码到附件看看
- 2024-12-19
-
回复了主题帖:
松下伺服电机连接Ethercat转profinet网关
Ethercat通信协议应该是目前工业通信总线中最主流和通信速率最快的,为什么还需要将ethercat转Profinet?
-
发表了主题帖:
《Linux内核深度解析》 U-Boot程序之程序启动流程简介及SPL阶段芯片配置
ARM芯片启动简单流程如下,所以U-Boot也分为SPL和U-Boot程序。
SPL: Secondary Program Loader, 第二阶段程序加载器,主要负责初始化内存和存储设备驱动,然后把正常的U-Boot镜像从存储设备读到内存中执行。
在实际项目中经常需要在SPL阶段配置芯片引脚,尤其是GPIO的初始化配置。因为在程序还未加载内核的设备树之前,需要GPIO的输出引脚保持指定状态(高/低电平输出)以免造成错误状态输出,结合之前的项目经验进行简单分享
以TI公司的AM33XX芯片举例:
SPL程序可以在u-boot-2017.09/arch/arm/mach-omap2/am33xx/board.c 进行修改,如下图程序中备注
Am33xx芯片中board.c源代码如下
/*
* board.c
*
* Common board functions for AM33XX based boards
*
* Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <debug_uart.h>
#include <errno.h>
#include <ns16550.h>
#include <spl.h>
#include <asm/arch/cpu.h>
#include <asm/arch/hardware.h>
#include <asm/arch/omap.h>
#include <asm/arch/ddr_defs.h>
#include <asm/arch/clock.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mem.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <asm/emif.h>
#include <asm/gpio.h>
#include <asm/omap_common.h>
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
#include <linux/errno.h>
#include <linux/compiler.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/musb.h>
#include <asm/omap_musb.h>
#include <asm/davinci_rtc.h>
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
sdram_init();
#endif
/* dram_init must store complete ramsize in gd->ram_size */
gd->ram_size = get_ram_size(
(void *)CONFIG_SYS_SDRAM_BASE,
CONFIG_MAX_RAM_BANK_SIZE);
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_dram[0].size = gd->ram_size;
return 0;
}
#if !CONFIG_IS_ENABLED(OF_CONTROL)
static const struct ns16550_platdata am33xx_serial[] = {
{ .base = CONFIG_SYS_NS16550_COM1, .reg_shift = 2,
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
# ifdef CONFIG_SYS_NS16550_COM2
{ .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2,
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
# ifdef CONFIG_SYS_NS16550_COM3
{ .base = CONFIG_SYS_NS16550_COM3, .reg_shift = 2,
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
{ .base = CONFIG_SYS_NS16550_COM4, .reg_shift = 2,
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
{ .base = CONFIG_SYS_NS16550_COM5, .reg_shift = 2,
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
{ .base = CONFIG_SYS_NS16550_COM6, .reg_shift = 2,
.clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, },
# endif
# endif
};
U_BOOT_DEVICES(am33xx_uarts) = {
{ "ns16550_serial", &am33xx_serial[0] },
# ifdef CONFIG_SYS_NS16550_COM2
{ "ns16550_serial", &am33xx_serial[1] },
# ifdef CONFIG_SYS_NS16550_COM3
{ "ns16550_serial", &am33xx_serial[2] },
{ "ns16550_serial", &am33xx_serial[3] },
{ "ns16550_serial", &am33xx_serial[4] },
{ "ns16550_serial", &am33xx_serial[5] },
# endif
# endif
};
#ifdef CONFIG_DM_GPIO
static const struct omap_gpio_platdata am33xx_gpio[] = {
{ 0, AM33XX_GPIO0_BASE },
{ 1, AM33XX_GPIO1_BASE },
{ 2, AM33XX_GPIO2_BASE },
{ 3, AM33XX_GPIO3_BASE },
#ifdef CONFIG_AM43XX
{ 4, AM33XX_GPIO4_BASE },
{ 5, AM33XX_GPIO5_BASE },
#endif
};
U_BOOT_DEVICES(am33xx_gpios) = {
{ "gpio_omap", &am33xx_gpio[0] },
{ "gpio_omap", &am33xx_gpio[1] },
{ "gpio_omap", &am33xx_gpio[2] },
{ "gpio_omap", &am33xx_gpio[3] },
#ifdef CONFIG_AM43XX
{ "gpio_omap", &am33xx_gpio[4] },
{ "gpio_omap", &am33xx_gpio[5] },
#endif
};
#endif
#endif
#ifndef CONFIG_DM_GPIO
static const struct gpio_bank gpio_bank_am33xx[] = {
{ (void *)AM33XX_GPIO0_BASE },
{ (void *)AM33XX_GPIO1_BASE },
{ (void *)AM33XX_GPIO2_BASE },
{ (void *)AM33XX_GPIO3_BASE },
#ifdef CONFIG_AM43XX
{ (void *)AM33XX_GPIO4_BASE },
{ (void *)AM33XX_GPIO5_BASE },
#endif
};
const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
#endif
#if defined(CONFIG_MMC_OMAP_HS)
int cpu_mmc_init(bd_t *bis)
{
int ret;
ret = omap_mmc_init(0, 0, 0, -1, -1);
if (ret)
return ret;
return omap_mmc_init(1, 0, 0, -1, -1);
}
#endif
/* AM33XX has two MUSB controllers which can be host or gadget */
#if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \
(defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) && \
(!defined(CONFIG_DM_USB))
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
/* USB 2.0 PHY Control */
#define CM_PHY_PWRDN (1 << 0)
#define CM_PHY_OTG_PWRDN (1 << 1)
#define OTGVDET_EN (1 << 19)
#define OTGSESSENDEN (1 << 20)
static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr)
{
if (on) {
clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN,
OTGVDET_EN | OTGSESSENDEN);
} else {
clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
}
}
static struct musb_hdrc_config musb_config = {
.multipoint = 1,
.dyn_fifo = 1,
.num_eps = 16,
.ram_bits = 12,
};
#ifdef CONFIG_AM335X_USB0
static void am33xx_otg0_set_phy_power(struct udevice *dev, u8 on)
{
am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
}
struct omap_musb_board_data otg0_board_data = {
.set_phy_power = am33xx_otg0_set_phy_power,
};
static struct musb_hdrc_platform_data otg0_plat = {
.mode = CONFIG_AM335X_USB0_MODE,
.config = &musb_config,
.power = 50,
.platform_ops = &musb_dsps_ops,
.board_data = &otg0_board_data,
};
#endif
#ifdef CONFIG_AM335X_USB1
static void am33xx_otg1_set_phy_power(struct udevice *dev, u8 on)
{
am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
}
struct omap_musb_board_data otg1_board_data = {
.set_phy_power = am33xx_otg1_set_phy_power,
};
static struct musb_hdrc_platform_data otg1_plat = {
.mode = CONFIG_AM335X_USB1_MODE,
.config = &musb_config,
.power = 50,
.platform_ops = &musb_dsps_ops,
.board_data = &otg1_board_data,
};
#endif
int arch_misc_init(void)
{
#ifdef CONFIG_AM335X_USB0
musb_register(&otg0_plat, &otg0_board_data,
(void *)USB0_OTG_BASE);
#endif
#ifdef CONFIG_AM335X_USB1
musb_register(&otg1_plat, &otg1_board_data,
(void *)USB1_OTG_BASE);
#endif
return 0;
}
#else /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */
int arch_misc_init(void)
{
struct udevice *dev;
int ret;
ret = uclass_first_device(UCLASS_MISC, &dev);
if (ret || !dev)
return ret;
#if defined(CONFIG_DM_ETH) && defined(CONFIG_USB_ETHER)
ret = usb_ether_init();
if (ret) {
error("USB ether init failed\n");
return ret;
}
#endif
return 0;
}
#endif /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*
* In the case of non-SPL based booting we'll want to call these
* functions a tiny bit later as it will require gd to be set and cleared
* and that's not true in s_init in this case so we cannot do it there.
*/
int board_early_init_f(void) /*AS:AM335X board start from here*/
{
prcm_init();
set_mux_conf_regs();
return 0;
}
/*
* This function is the place to do per-board things such as ramp up the
* MPU clock frequency.
*/
__weak void am33xx_spl_board_init(void) /*AS:AM335X Board SPL Init*/
{
}
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
static void rtc32k_enable(void)
{
struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
/*
* Unlock the RTC's registers. For more details please see the
* RTC_SS section of the TRM. In order to unlock we need to
* write these specific values (keys) in this order.
*/
writel(RTC_KICK0R_WE, &rtc->kick0r);
writel(RTC_KICK1R_WE, &rtc->kick1r);
/* Enable the RTC 32K OSC by setting bits 3 and 6. */
writel((1 << 3) | (1 << 6), &rtc->osc);
}
#endif
static void uart_soft_reset(void)
{
struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
u32 regval;
regval = readl(&uart_base->uartsyscfg);
regval |= UART_RESET;
writel(regval, &uart_base->uartsyscfg);
while ((readl(&uart_base->uartsyssts) &
UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK)
;
/* Disable smart idle */
regval = readl(&uart_base->uartsyscfg);
regval |= UART_SMART_IDLE_EN;
writel(regval, &uart_base->uartsyscfg);
}
static void watchdog_disable(void)
{
struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
writel(0xAAAA, &wdtimer->wdtwspr);
while (readl(&wdtimer->wdtwwps) != 0x0)
;
writel(0x5555, &wdtimer->wdtwspr);
while (readl(&wdtimer->wdtwwps) != 0x0)
;
}
void s_init(void)
{
}
void early_system_init(void)
{
/*
* The ROM will only have set up sufficient pinmux to allow for the
* first 4KiB NOR to be read, we must finish doing what we know of
* the NOR mux in this space in order to continue.
*/
#ifdef CONFIG_NOR_BOOT
enable_norboot_pin_mux();
#endif
watchdog_disable();
set_uart_mux_conf();
setup_early_clocks();
uart_soft_reset();
#ifdef CONFIG_SPL_BUILD
/*
* Save the boot parameters passed from romcode.
* We cannot delay the saving further than this,
* to prevent overwrites.
*/
save_omap_boot_params();
#endif
#ifdef CONFIG_DEBUG_UART_OMAP
debug_uart_init();
#endif
#ifdef CONFIG_TI_I2C_BOARD_DETECT
do_board_detect();
#endif
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
/* Enable RTC32K clock */
rtc32k_enable();
#endif
}
#ifdef CONFIG_SPL_BUILD
void board_init_f(ulong dummy)
{
hw_data_init();
early_system_init();
board_early_init_f();
sdram_init();
/* dram_init must store complete ramsize in gd->ram_size */
gd->ram_size = get_ram_size(
(void *)CONFIG_SYS_SDRAM_BASE,
CONFIG_MAX_RAM_BANK_SIZE);
}
#endif
#endif
int arch_cpu_init_dm(void)
{
hw_data_init();
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
early_system_init();
#endif
return 0;
}
-
发表了主题帖:
《Linux内核深度解析》 U-Boot程序之入口_start
本帖最后由 beyond_笑谈 于 2024-12-19 22:02 编辑
多谢EE提供的这次《Linux内核深度解析》好书共读活动,希望借助本次活动可以深入了解Linux内核知识。
U-Boot下载:u-boot-2017.09.tar
将下载的代码利用FTP服务器传到ubuntu并且解压缩,如下图
利用vim打开uboot的入口文件 start.S,如下图
利用Source Insight 打开start.S文件进行阅读和备注
start.S的代码如下
[/*
* (C) Copyright 2013
* David Feng <fenghua@phytium.com.cn>
* Made notes by Allen Shen - 2024.12
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm-offsets.h>
#include <config.h>
#include <linux/linkage.h>
#include <asm/macro.h>
#include <asm/armv8/mmu.h>
/*************************************************************************
*
* Startup Code (reset vector)
*
*************************************************************************/
.globl _start /*uboot start from here*/
_start
#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
/*
* Various SoCs need something special and SoC-specific up front in
* order to boot, allow them to set that in their boot0.h file and then
* use it here.
*/
#include <asm/arch/boot0.h>
#else[
b reset /*To reset*/
#endif
.align 3
.globl _TEXT_BASE
_TEXT_BASE:
.quad CONFIG_SYS_TEXT_BASE
/*
* These are defined in the linker script.
*/
.globl _end_ofs
_end_ofs:
.quad _end - _start
.globl _bss_start_ofs
_bss_start_ofs:
.quad __bss_start - _start
.globl _bss_end_ofs
_bss_end_ofs:
.quad __bss_end - _start
reset:
/* Allow the board to save important registers */
b save_boot_params
.globl save_boot_params_ret
save_boot_params_ret:
#ifdef CONFIG_SYS_RESET_SCTRL
bl reset_sctrl
#endif
/*
* Could be EL3/EL2/EL1, Initial State:
* Little Endian, MMU Disabled, i/dCache Disabled
*/
adr x0, vectors
switch_el x1, 3f, 2f, 1f
3: msr vbar_el3, x0
mrs x0, scr_el3
orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */
msr scr_el3, x0
msr cptr_el3, xzr /* Enable FP/SIMD */
#ifdef COUNTER_FREQUENCY
ldr x0, =COUNTER_FREQUENCY
msr cntfrq_el0, x0 /* Initialize CNTFRQ */
#endif
b 0f
2: msr vbar_el2, x0
mov x0, #0x33ff
msr cptr_el2, x0 /* Enable FP/SIMD */
b 0f
1: msr vbar_el1, x0
mov x0, #3 << 20
msr cpacr_el1, x0 /* Enable FP/SIMD */
0:
/*
* Enable SMPEN bit for coherency.
* This register is not architectural but at the moment
* this bit should be set for A53/A57/A72.
*/
#ifdef CONFIG_ARMV8_SET_SMPEN
switch_el x1, 3f, 1f, 1f
3:
mrs x0, S3_1_c15_c2_1 /* cpuectlr_el1 */
orr x0, x0, #0x40
msr S3_1_c15_c2_1, x0
1:
#endif
/* Apply ARM core specific erratas */
bl apply_core_errata
/*
* Cache/BPB/TLB Invalidate
* i-cache is invalidated before enabled in icache_enable()
* tlb is invalidated before mmu is enabled in dcache_enable()
* d-cache is invalidated before enabled in dcache_enable()
*/
/* Processor specific initialization */
bl lowlevel_init
#if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
branch_if_master x0, x1, master_cpu
b spin_table_secondary_jump
/* never return */
#elif defined(CONFIG_ARMV8_MULTIENTRY)
branch_if_master x0, x1, master_cpu
/*
* Slave CPUs
*/
slave_cpu:
wfe
ldr x1, =CPU_RELEASE_ADDR
ldr x0, [x1]
cbz x0, slave_cpu
br x0 /* branch to the given address */
#endif /* CONFIG_ARMV8_MULTIENTRY */
master_cpu:
bl _main
#ifdef CONFIG_SYS_RESET_SCTRL
reset_sctrl:
switch_el x1, 3f, 2f, 1f
3:
mrs x0, sctlr_el3
b 0f
2:
mrs x0, sctlr_el2
b 0f
1:
mrs x0, sctlr_el1
0:
ldr x1, =0xfdfffffa
and x0, x0, x1
switch_el x1, 6f, 5f, 4f
6:
msr sctlr_el3, x0
b 7f
5:
msr sctlr_el2, x0
b 7f
4:
msr sctlr_el1, x0
7:
dsb sy
isb
b __asm_invalidate_tlb_all
ret
#endif
/*-----------------------------------------------------------------------*/
WEAK(apply_core_errata)
mov x29, lr /* Save LR */
/* For now, we support Cortex-A57 specific errata only */
/* Check if we are running on a Cortex-A57 core */
branch_if_a57_core x0, apply_a57_core_errata
0:
mov lr, x29 /* Restore LR */
ret
apply_a57_core_errata:
#ifdef CONFIG_ARM_ERRATA_828024
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* Disable non-allocate hint of w-b-n-a memory type */
orr x0, x0, #1 << 49
/* Disable write streaming no L1-allocate threshold */
orr x0, x0, #3 << 25
/* Disable write streaming no-allocate threshold */
orr x0, x0, #3 << 27
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
#ifdef CONFIG_ARM_ERRATA_826974
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* Disable speculative load execution ahead of a DMB */
orr x0, x0, #1 << 59
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
#ifdef CONFIG_ARM_ERRATA_833471
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* FPSCR write flush.
* Note that in some cases where a flush is unnecessary this
could impact performance. */
orr x0, x0, #1 << 38
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
#ifdef CONFIG_ARM_ERRATA_829520
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* Disable Indirect Predictor bit will prevent this erratum
from occurring
* Note that in some cases where a flush is unnecessary this
could impact performance. */
orr x0, x0, #1 << 4
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
#ifdef CONFIG_ARM_ERRATA_833069
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* Disable Enable Invalidates of BTB bit */
and x0, x0, #0xE
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
b 0b
ENDPROC(apply_core_errata)
/*-----------------------------------------------------------------------*/
WEAK(lowlevel_init)
mov x29, lr /* Save LR */
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
branch_if_slave x0, 1f
ldr x0, =GICD_BASE
bl gic_init_secure
1:
#if defined(CONFIG_GICV3)
ldr x0, =GICR_BASE
bl gic_init_secure_percpu
#elif defined(CONFIG_GICV2)
ldr x0, =GICD_BASE
ldr x1, =GICC_BASE
bl gic_init_secure_percpu
#endif
#endif
#ifdef CONFIG_ARMV8_MULTIENTRY
branch_if_master x0, x1, 2f
/*
* Slave should wait for master clearing spin table.
* This sync prevent salves observing incorrect
* value of spin table and jumping to wrong place.
*/
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
#ifdef CONFIG_GICV2
ldr x0, =GICC_BASE
#endif
bl gic_wait_for_interrupt
#endif
/*
* All slaves will enter EL2 and optionally EL1.
*/
adr x4, lowlevel_in_el2
ldr x5, =ES_TO_AARCH64
bl armv8_switch_to_el2
lowlevel_in_el2:
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
adr x4, lowlevel_in_el1
ldr x5, =ES_TO_AARCH64
bl armv8_switch_to_el1
lowlevel_in_el1:
#endif
#endif /* CONFIG_ARMV8_MULTIENTRY */
2:
mov lr, x29 /* Restore LR */
ret
ENDPROC(lowlevel_init)
WEAK(smp_kick_all_cpus)
/* Kick secondary cpus up by SGI 0 interrupt */
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
ldr x0, =GICD_BASE
b gic_kick_secondary_cpus
#endif
ret
ENDPROC(smp_kick_all_cpus)
/*-----------------------------------------------------------------------*/
ENTRY(c_runtime_cpu_setup)
/* Relocate vBAR */
adr x0, vectors
switch_el x1, 3f, 2f, 1f
3: msr vbar_el3, x0
b 0f
2: msr vbar_el2, x0
b 0f
1: msr vbar_el1, x0
0:
ret
ENDPROC(c_runtime_cpu_setup)
WEAK(save_boot_params)
b save_boot_params_ret /* back to my caller */
ENDPROC(save_boot_params)
-
回复了主题帖:
新手小白没学过任何基础,怎么学习stm32做出作品
如果电子技术、单片机编程、C语言等都是完全零基础,那就买个板子跟着视频从点灯开始学吧
-
回复了主题帖:
最能打国产芯榜:沁恒冒泡,推荐他家的带高速USB收发器、NFC的蓝牙soc CH585
支持无线数据透传是不错,不用留调试接口,产品可以直接上IP67了
-
回复了主题帖:
开发高性能伺服电机驱动控制器从未如此简单高集成硬件智能伺服电机驱动控制芯片TM...
用ADI这个芯片设计伺服驱动器还是不错的,很多参数可以通过ADI软件直接配置
-
回复了主题帖:
【一句】来一句话证明你用过单片机
又要换其他品牌单片机?那还得看规格书挨个配置寄存器
-
回复了主题帖:
STC更名为Ai?这事你怎么看?
在国内还是STC听起来更熟悉,多少攻城狮就是从STC单片机开始入门的。
-
回复了主题帖:
PCB Layout 求推荐教程
首先需要清楚电路中的信号(比如提到的走线宽度、线间距、绝缘间距等),然后再了解一下PCB裸板以及PCBA的加工工艺限制。
-
回复了主题帖:
嵌入式操作系统如何入门?
感觉就是AI出来的文章,嵌入式操作系统入门哪有这么简单和容易