*(int *)(void*) 0x80000000=0x2d70和*(volatile uint32_t *)0x80000000 =0x2d70有什么区别

这两行代码都是C语言中的强制类型转换和指针操作,但它们在语义和使用上有一些区别:

(int )(void)0x80000000 = 0x2d70;
这行代码首先将地址 0x80000000 转换为 void
类型的指针,然后再将 void* 类型的指针转换为 int* 类型的指针,最后通过解引用操作符 * 将地址 0x80000000 处的值设置为 0x2d70。

*(volatile uint32_t *)0x80000000 = 0x2d70;
这行代码直接将地址 0x80000000 转换为指向 volatile uint32_t 类型的指针,然后通过解引用操作符 * 将地址 0x80000000 处的值设置为 0x2d70。这里的 volatile 关键字表示该变量可能会由程序以外的因素(比如硬件)改变,因此编译器不会对该变量进行优化。

主要区别在于:

第一行代码中使用了两次类型转换,先转换为 void* 再转换为 int*。这种转换方式在某些情况下可能会引起编译器的警告,因为 void* 到其他类型的转换通常需要显式转换。
第二行代码中使用了 volatile 关键字,这告诉编译器不要对这个变量进行优化,因为其值可能会在程序不知情的情况下改变。这通常用于硬件寄存器的访问,以确保每次访问都从硬件中读取最新的值。
第二行代码中使用的是 uint32_t 类型,这明确指定了数据的宽度和符号性,而第一行代码中的 int 类型的大小和符号性可能依赖于编译器和平台。
在实际编程中,使用 volatile 关键字是访问硬件寄存器的常见做法,以确保程序的行为与硬件的实际状态保持一致。而 void* 类型的使用通常是为了实现更通用的指针操作,但在直接操作硬件寄存器时,通常不需要这种类型的转换。

/*********************************************************************************************************************** * Copyright (C) All rights reserved. ***********************************************************************************************************************/ /*********************************************************************************************************************** * @file gpio.c * @brief This file implements device driver for GPIO module. * @version 1.0.0 * @date 2019/6/26 ***********************************************************************************************************************/ /*********************************************************************************************************************** Includes ***********************************************************************************************************************/ #include "BAT32G133.h" #include "gpio.h" /*********************************************************************************************************************** Pragma directive ***********************************************************************************************************************/ /*********************************************************************************************************************** Global variables and functions ***********************************************************************************************************************/ /** * @brief Set specified GPIO as output function. * * @param port port address, such as &P0, &P1, &P2... * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_Output_Enable(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2A0) &= ~pinMsk; /*!< PMC=0: Digital Function */ *(port + 0x020) &= ~pinMsk; /*!< PM =0: Output Function */ } /** * @brief Set specified GPIO as input function. * * @param port port address, such as &P0, &P1, &P2... * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_Input_Enable(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2A0) &= ~pinMsk; /*!< PMC=0: Digital Function */ *(port + 0x020) |= pinMsk; /*!< PM =1: Input Function */ } /** * @brief Enable pull up resister of input GPIO . * * @param port port address, such as &P0, &P1, &P2... * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_PullUp_Enable(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2A0) &= ~pinMsk; /*!< PMC=0: Digital Function */ *(port - 0x2D0) |= pinMsk; /*!< PU =1: Pull Up enable */ } /** * @brief Disable pull up resister of input GPIO . * * @param port port address, such as &P0, &P1, &P2... * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_PullUp_Disable(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2D0) &= ~pinMsk; /*!< PU =0: Pull Up disable */ } /** * @brief Enable pull down resister of input GPIO . * * @param port port address, such as &P0, &P1, &P2... * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_PullDown_Enable(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2A0) &= ~pinMsk; /*!< PMC=0: Digital Function */ *(port - 0x2C0) |= pinMsk; /*!< PD =1: Pull Down enable */ } /** * @brief Disable pull down resister of input GPIO . * * @param port port address, such as &P0, &P1, &P2... * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_PullDown_Disable(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2C0) &= ~pinMsk; /*!< PD =0: Pull Down disable */ } /** * @brief Nch Open Drain Output mode * * @param port address, such as &P0, &P1, &P3, &P5, &P7 * @param pinMsk * e.g., bit0: 0x01, bit1: 0x02, bit0~3: 0x0F, bit0~7: 0xFF */ void GPIO_Nch_OpenDrain(__IO uint8_t *port, uint8_t pinMsk) { *(port - 0x2B0) |= pinMsk; /*!< POM =1: Nch OpenDrain Output */ } /** * @brief Set specified value to GPIO output * * @param port port address, such as &P0, &P1, &P2... * @param value */ void GPIO_Set_Value(__IO uint8_t *port, uint8_t value) { *port = value; /*!< PL = value */ } /** * @brief Get value from GPIO input * * @param port port address, such as &P0, &P1, &P2... * * @return */ uint8_t GPIO_Get_Value(__IO uint8_t *port) { //PORT->PMS = 0x01; /*!< Digital output level of the pin is read */ return (*port); /*!< PL = value */ } /** * @brief Initializes the PORTx * @param PORTx: where x can be 0~3 * @param PINx: where x can be 0~7 * @param MODEx: such as INPUT,PULLUP_INPUT,TTL_INPUT,ANALOG_INPUT,OUTPUT,OPENDRAIN_OUTPUT,PULLDOWN_INPUT * * @retval None */ #define CFG_BIT_DIR_INPUT 0x01 #define CFG_BIT_PU 0x02 #define CFG_BIT_PD 0x04 #define CFG_BIT_ANALOG 0x08 void PORT_Init(PORT_TypeDef PORTx,PIN_TypeDef PINx,PIN_ModeDef MODEx) { uint8_t mode = MODEx; uint8_t pos = 1<<PINx; #if 1 uint8_t cfg = CFG_BIT_DIR_INPUT; if(mode == PULLUP_INPUT) { cfg |= CFG_BIT_PU; }else if(mode == ANALOG_INPUT) { cfg |= CFG_BIT_ANALOG; }else if(mode == OUTPUT) { cfg &= ~CFG_BIT_DIR_INPUT; }else if(mode ==PULLDOWN_INPUT) { cfg |= CFG_BIT_PD; } if(cfg & CFG_BIT_DIR_INPUT) { if(cfg & CFG_BIT_ANALOG) *((volatile uint8_t*)(&PORT->PMC0+PORTx)) |= pos; else *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) |= pos; if(cfg & CFG_BIT_PU) *((volatile uint8_t*)(&PORT->PU0+PORTx)) |= pos; else *((volatile uint8_t*)(&PORT->PU0+PORTx)) &= ~pos; if(cfg & CFG_BIT_PD) *((volatile uint8_t*)(&PORT->PD0+PORTx)) |= pos; else *((volatile uint8_t*)(&PORT->PD0+PORTx)) &= ~pos; } else { *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->POM0+PORTx)) &= ~pos; } #else switch(mode) { case INPUT: *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) |= pos; //*((volatile uint8_t*)(&PORT->PIM0+PORTx)) &= ~pos; //*((volatile uint8_t*)(&PORT->POM0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PU0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PD0+PORTx)) &= ~pos; break; case PULLUP_INPUT: *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) |= pos; //*((volatile uint8_t*)(&PORT->PIM0+PORTx)) &= ~pos; //*((volatile uint8_t*)(&PORT->POM0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PU0+PORTx)) |= pos; *((volatile uint8_t*)(&PORT->PD0+PORTx)) &= ~pos; break; case TTL_INPUT: *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) |= pos; //*((volatile uint8_t*)(&PORT->PIM0+PORTx)) |= pos; //*((volatile uint8_t*)(&PORT->POM0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PU0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PD0+PORTx)) &= ~pos; break; case ANALOG_INPUT: *((volatile uint8_t*)(&PORT->PMC0+PORTx)) |= pos; break; case OUTPUT: *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) &= ~pos; //*((volatile uint8_t*)(&PORT->PIM0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->POM0+PORTx)) &= ~pos; break; // case OPENDRAIN_OUTPUT: // *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; // *((volatile uint8_t*)(&PORT->PM0+PORTx)) &= ~pos; // //*((volatile uint8_t*)(&PORT->PIM0+PORTx)) &= ~pos; // *((volatile uint8_t*)(&PORT->POM0+PORTx)) |= pos; // break; case PULLDOWN_INPUT: *((volatile uint8_t*)(&PORT->PMC0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PM0+PORTx)) |= pos; //*((volatile uint8_t*)(&PORT->PIM0+PORTx)) &= ~pos; //*((volatile uint8_t*)(&PORT->POM0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PU0+PORTx)) &= ~pos; *((volatile uint8_t*)(&PORT->PD0+PORTx)) |= pos; break; } #endif } /** * @brief Set the PORTx bit * @param PORTx: where x can be 0~3 * @param PINx: where x can be 0~7 * * @retval None */ void PORT_SetBit(PORT_TypeDef PORTx,PIN_TypeDef PINx) { uint8_t pos = 1<<PINx; *((volatile uint8_t*)(&PORT->P0+PORTx)) |= pos; } /** * @brief Clear the PORTx bit * @param PORTx: where x can be 0~3 * @param PINx: where x can be 0~7 * * @retval None */ void PORT_ClrBit(PORT_TypeDef PORTx,PIN_TypeDef PINx) { uint8_t pos = 1<<PINx; *((volatile uint8_t*)(&PORT->P0+PORTx)) &= ~pos; } /** * @brief Toggle the PORTx bit * @param PORTx: where x can be 0~3 * @param PINx: where x can be 0~7 * * @retval None */ void PORT_ToggleBit(PORT_TypeDef PORTx,PIN_TypeDef PINx) { uint8_t pos = 1<<PINx; *((volatile uint8_t*)(&PORT->P0+PORTx)) ^= pos; } /** * @brief Get the PORTx bit * @param PORTx: where x can be 0~3 * @param PINx: where x can be 0~7 * * @retval None */ uint8_t PORT_GetBit(PORT_TypeDef PORTx,PIN_TypeDef PINx) { uint8_t pos = 1<<PINx; //PORT->PMS = 0x01; /*!< Digital output level of the pin is read */ return *((volatile uint8_t*)(&PORT->P0+PORTx))&pos; } /** * @brief Config the PORTx bit * @param PORT_CFGx: such as P00_CFG ... * @param CFGx: such as IOCFG_INTP0 ... * * @retval None */ void PORT_Cfg(IO_CfgType PORT_CFGx, IO_CfgDef CFGx) { *((volatile uint8_t*)(&PORT->P00CFG+PORT_CFGx)) = CFGx; } 使用这里面的函数控制led闪亮
09-29
怎解决以下SPI从机与主机收发数据乱序的问题。 #define GYRO_DATA_LEN (12) #define GYRO_DATA_NUM (840) #define GYRO_DATA_NUM_ALL (GYRO_DATA_LEN*GYRO_DATA_NUM) // GYRO命令定义 #define GYRO_READ_CMD 0x8C // 接收发送缓冲区 uint8_t spi_tx_buffer[14] = {0}; // 用于接收来自主机的数据 uint8_t spi_rx_buffer[14] = {0}; // 模拟数据参数 uint8_t gyro_data[GYRO_DATA_NUM_ALL] = { 0xD5,0xF4,0x5E,0x0B,0x6A,0x00,0xEB,0xFF,0x60,0xFF,0x5E,0x00, ...... 0xCB,0xF4,0x86,0x0B,0xB7,0xFF,0xB2,0xFF,0x2C,0x00,0x2D,0x00 }; int16_t icount_gyro = 0; volatile uint8_t spi_slave_transfer_complete = 0; volatile uint8_t spi_slave_error = 0; void SystemClock_Config(void); int fputc(int ch,FILE *f) { uint8_t temp[1] = {ch}; HAL_UART_Transmit(&huart2,temp,1,2); return ch; } // SPI传输完成回调函数 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1) { spi_slave_transfer_complete = 1; } } /* 错误回调 */ void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1) { spi_slave_error = 1; } } /* 从机命令处理函数 */ void SPI_Slave_Process_Command(void) { // 检查接收到的命令 if ((spi_rx_buffer[0] == GYRO_READ_CMD)&&(spi_rx_buffer[1] == 0x00)) { // 更新GYRO数据(模拟数据变化) icount_gyro = icount_gyro % GYRO_DATA_NUM; spi_tx_buffer[2] = gyro_data[icount_gyro*GYRO_DATA_LEN]; spi_tx_buffer[3] = gyro_data[icount_gyro*GYRO_DATA_LEN+1]; spi_tx_buffer[4] = gyro_data[icount_gyro*GYRO_DATA_LEN+2]; spi_tx_buffer[5] = gyro_data[icount_gyro*GYRO_DATA_LEN+3]; spi_tx_buffer[6] = gyro_data[icount_gyro*GYRO_DATA_LEN+4]; spi_tx_buffer[7] = gyro_data[icount_gyro*GYRO_DATA_LEN+5]; spi_tx_buffer[8] = gyro_data[icount_gyro*GYRO_DATA_LEN+6]; spi_tx_buffer[9] = gyro_data[icount_gyro*GYRO_DATA_LEN+7]; spi_tx_buffer[10] = gyro_data[icount_gyro*GYRO_DATA_LEN+8]; spi_tx_buffer[11] = gyro_data[icount_gyro*GYRO_DATA_LEN+9]; spi_tx_buffer[12] = gyro_data[icount_gyro*GYRO_DATA_LEN+10]; spi_tx_buffer[13] = gyro_data[icount_gyro*GYRO_DATA_LEN+11]; icount_gyro++; } else { printf("Invalid command: 0x%02X\r\n", spi_rx_buffer[0]); } return; } /* 从机通信启动函数 */ void SPI_Slave_Start_Transfer(void) { spi_slave_transfer_complete = 0; spi_slave_error = 0; /* 启动全双工DMA传输 */ if (HAL_SPI_TransmitReceive_DMA(&hspi1, spi_tx_buffer, spi_rx_buffer, 14) != HAL_OK) { /* 启动失败处理 */ // 可以尝试重新初始化SPI } } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_SPI1_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ icount_gyro = 0; printf("===============================Slave System Start===============================\n"); // 启动SPI传输 SPI_Slave_Start_Transfer(); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ if (spi_slave_transfer_complete) { SPI_Slave_Process_Command(); /* 重新启动传输,准备下一次通信 */ SPI_Slave_Start_Transfer(); } /* 错误处理 */ if (spi_slave_error) { /* SPI错误恢复 */ HAL_SPI_DeInit(&hspi1); HAL_Delay(10); MX_SPI1_Init(); spi_slave_error = 0; SPI_Slave_Start_Transfer(); } } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } HAL_PWR_EnableBkUpAccess(); __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_8; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 3; RCC_OscInitStruct.PLL.PLLN = 20; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) { Error_Handler(); } /** Enable MSI Auto calibration */ HAL_RCCEx_EnableMSIPLLMode(); } void Error_Handler(void) { __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */
10-31
void dma2d_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t color) { uint32_t addr; uint32_t offline = 0; uint32_t psx, psy, pex, pey; /* 以LCD面板为基准的坐标系,不随横竖屏变化而变化 */ // /* 坐标系转换 */ // if (lcdltdc.dir) /* 横屏 */ // { psx = sx; psy = sy; pex = ex; pey = ey; // } // else /* 竖屏 */ // { // psx = sy; // psy = lcdltdc.pheight - ex - 1; // pex = ey; // pey = lcdltdc.pheight - sx - 1; // } /* 横屏 */ addr = FB_ADDR + 2 * (800 * psy + psx); offline = 800 - (pex - psx + 1); /* 使能DMA2D时钟并停止DMA2D */ __HAL_RCC_DMA2D_CLK_ENABLE(); DMA2D->CR &= ~DMA2D_CR_START; /* 设置DMA2D工作模式 */ DMA2D->CR = DMA2D_R2M; /* 寄存器到存储器 */ /* 设置DMA2D的相关参数 */ /* 颜色格式设置(OPFCCR) */ DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_RGB565; /* 输出存储器地址(OMAR) */ DMA2D->OMAR = addr; /* 输出窗口(OOR NLR) */ DMA2D->OOR = offline; DMA2D->NLR = ((pex - psx + 1) << 16) | (pey - psy + 1); /* 像素数 */ /* 颜色寄存器(仅R2M时设置) OCOLR */ DMA2D->OCOLR = color; /* 启动DMA2D传输 */ DMA2D->CR |= DMA2D_CR_START; /* 启动DMA2D */ /* 等待DMA2D传输完成,清除相关标志 */ while((DMA2D->ISR & DMA2D_FLAG_TC) == 0); DMA2D->IFCR |= DMA2D_FLAG_TC; } 使用寄存器配置颜色显示正常void FillScreenWithColor(uint32_t color) { DMA2D_HandleTypeDef hdma2d; hdma2d.Instance = DMA2D; hdma2d.Init.Mode = DMA2D_R2M; // 寄存器到内存 hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; hdma2d.Init.OutputOffset = 0; HAL_DMA2D_Init(&hdma2d); printf("WPixel0: 0x%04X\n", (uint16_t)(color)); // 低16位 HAL_DMA2D_Start(&hdma2d, (uint16_t)(color & 0xFFFF), // 确保只使用低16位 0xC0000000, // 显存地址 800, // 行宽 480); // 行数 HAL_DMA2D_PollForTransfer(&hdma2d, 100); // 等待完成 // 立即读取前4个像素(8字节) volatile uint32_t* p = (volatile uint32_t*)0xC0000000; printf("RPixel0: 0x%04X\n", (uint16_t)(*p)); // 低16位 }使用hal库设置颜色不正常
11-26
// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2021 Netfactory */ #include <common.h> #include <cpu_func.h> #include <debug_uart.h> #include <hang.h> #include <init.h> #include <asm/global_data.h> #include <spl.h> #include <cli.h> #include <linux/delay.h> #include <spi_flash.h> #include <asm/io.h> #include "nand.h" //#include "ddr_init.h" //#if BOOT_OS_LITEOS /*LITEOS 单NOR,双NOR,片外双BOOT 启动场景1*/ #define CONFIG_NORDOUBOOT_LITEOS_MAIN 0xC0000 #define CONFIG_NORDOUBOOT_LITEOS_BACKUP 0x4C0000 /*LITEOS 单NOR,双NOR,片内,片外*/ #define CONFIG_NORBOOT_LITEOS_MAIN 0x140000 #define CONFIG_NORBOOT_LITEOS_BACKUP 0x540000 //#define CONFIG_NORBOOT_UBOOT_MAIN 0x140000 //#define CONFIG_NORBOOT_UBOOT_BACKUP 0x2C0000 //#else /*Linux 2M nand 分区大小 片内片外*/ #define CONFIG_2M_NANDBOOT_UBOOT_MAIN 0x600000 #define CONFIG_2M_NANDBOOT_UBOOT_BACKUP 0xE00000 /*Linux 4M nand 分区大小 片内片外*/ #define CONFIG_4M_NANDBOOT_UBOOT_MAIN 0xC00000 #define CONFIG_4M_NANDBOOT_UBOOT_BACKUP 0x1400000 /*Linux FMC1 NOR 双boot*/ #define CONFIG_NORDOUBOOT_UBOOT_MAIN (0x800000 + 0x10000000) #define CONFIG_NORDOUBOOT_UBOOT_BACKUP (0xC00000 + 0x10000000) /*Linux FMC1 NOR 片内安全*/ #define CONFIG_NORBOOT_UBOOT_MAIN (0x140000 + 0x10000000) #define CONFIG_NORBOOT_UBOOT_BACKUP (0x540000 + 0x10000000) /*片外片内norflash启动 */ //#define CONFIG_NORBOOT_UBOOT_MAIN 0x300000 //#define CONFIG_NORBOOT_UBOOT_BACKUP 0x700000 //#endif #if 0 /* 片外nor硬件双boot */ #define CONFIG_STARTCODE_NORBOOT_UBOOT_MAIN 0x140000 //to be fix #define CONFIG_STARTCODE_NORBOOT_UBOOT_BACKUP 0xc00000 //to be fix /* nand启动 */ #define CONFIG_NANDBOOT_UBOOT_MAIN 0xC00000 #define CONFIG_NANDBOOT_UBOOT_BACKUP 0x1400000 #endif DECLARE_GLOBAL_DATA_PTR; unsigned int spl_get_mru_reg(uint64_t addr) { return (*(volatile unsigned int*)(addr)); } unsigned int spl_get_bootsel(void) { unsigned int bootsel = spl_get_mru_reg(MRU_CFG1); return ((bootsel & MRU_CFG1_BOOTSEL_MASK) >> MRU_CFG1_BOOTSEL_SHIFT); } #ifdef EXEC_ENV_2125_EVB unsigned long spl_nor_get_uboot_base(void) { unsigned int bootmod = ((spl_get_mru_reg(MRU_CFG1) & MRU_CFG1_BOOTMOD_MASK ) >> MRU_CFG1_BOOTMOD_SHIFT); unsigned int bootsel1 = (spl_get_bootsel() >> 0x1); unsigned int mru_remap = spl_get_mru_reg(MRU_REMAP); unsigned int mru_reg7 = (spl_get_mru_reg(MRU_REG7) & 0x1); unsigned int ns_forbid = spl_get_mru_reg(SEC_NS_FORBIT); if (ns_forbid != NONE_SECURE_BOOT_FLAG) { printf("SPL: secure boot, nsforbid(%u)\n", ns_forbid); printf("SPL: boot area %s, mrureg7(%u)\n", (mru_reg7 ? "back" : "main"), mru_reg7); #if BOOT_OS_LITEOS return (mru_reg7 ? CONFIG_NORBOOT_LITEOS_BACKUP : CONFIG_NORBOOT_LITEOS_MAIN); #else return (mru_reg7 ? (CONFIG_NORBOOT_UBOOT_BACKUP - 0x10000000) : (CONFIG_NORBOOT_UBOOT_MAIN - 0x10000000)); #endif } /* 片内rom启动 */ if (bootmod == 0x1) { printf("SPL: boot from %s, bootmod(%u)\n", (bootmod ? "rom" : "norflash"), bootmod); printf("SPL: boot area %s, mru_reg7(%u)\n", (mru_reg7 ? "backup" : "main"), mru_reg7); #if BOOT_OS_LITEOS return (mru_reg7 ? CONFIG_NORBOOT_LITEOS_BACKUP : CONFIG_NORBOOT_LITEOS_MAIN); #else return (mru_reg7 ? (CONFIG_NORBOOT_UBOOT_BACKUP - 0x10000000) : (CONFIG_NORBOOT_UBOOT_MAIN - 0x10000000)); #endif } printf("SPL: boot from %s, bootsel1(%u)\n", (bootsel1 ? "norflash remap is disabled" : "norflash remap is enabled"), bootsel1); /* 片外nor双boot启动 */ if (bootsel1 == 0x0) { printf("SPL: boot %s, mru_remap(%u)\n", (mru_remap ? "backup" : "main"), mru_remap); #if BOOT_OS_LITEOS return (mru_reg7 ? CONFIG_NORDOUBOOT_LITEOS_BACKUP : CONFIG_NORDOUBOOT_LITEOS_MAIN); #else return (mru_reg7 ? (CONFIG_NORDOUBOOT_UBOOT_BACKUP - 0x10000000) : (CONFIG_NORDOUBOOT_UBOOT_MAIN - 0x10000000)); #endif } /* 片外nof启动,带safetycode */ printf("SPL: boot from %s, mru_reg7(%u)\n", (mru_reg7 ? "backup" : "main"), mru_reg7); #if BOOT_OS_LITEOS return (mru_reg7 ? CONFIG_NORBOOT_LITEOS_BACKUP : CONFIG_NORBOOT_LITEOS_MAIN); #else return (mru_reg7 ? (CONFIG_NORBOOT_UBOOT_BACKUP - 0x10000000) : (CONFIG_NORBOOT_UBOOT_MAIN - 0x10000000)); #endif } #else unsigned int spl_get_spinor_doubleboot(void) { unsigned int bootmod = ((spl_get_mru_reg(MRU_CFG1) & MRU_CFG1_BOOTMOD_MASK ) >> MRU_CFG1_BOOTMOD_SHIFT); unsigned int bootsel = spl_get_bootsel(); unsigned int bootsel0 = (bootsel >> 0 ) & 0x1; unsigned int bootsel1 = (bootsel >> 1 ) & 0x1; unsigned int bootsel2 = (bootsel >> 2 ) & 0x1; unsigned int bootsel3 = (bootsel >> 3 ) & 0x1; /*仅当片外Nor启动:BOOT_SEL1 表示 SPI Nor双boot使能*/ if (bootmod == 0x0) //片外启动 { if(bootsel0 == 0 && bootsel2 == 0) //从FMC0 启动 NOR 启动 { printf_spl("SPL: boot from fmc0 %s, bootsel1(%u)\n", (bootsel1 ? "norflash remap is disabled" : "norflash remap is enabled"), bootsel1); return 0; } if(bootsel0 == 1 && bootsel3 == 1) {//从FMC1 启动 NOR 启动 printf_spl("SPL: boot from fmc1 %s, bootsel1(%u)\n", (bootsel1 ? "norflash remap is disabled" : "norflash remap is enabled"), bootsel1); return 0; } return -1; } else { return -1; } } unsigned long spl_nor_get_uboot_base(void) { unsigned int bootmod = ((spl_get_mru_reg(MRU_CFG1) & MRU_CFG1_BOOTMOD_MASK ) >> MRU_CFG1_BOOTMOD_SHIFT); unsigned int bootsel = spl_get_bootsel(); unsigned int bootsel0 = (bootsel >> 0 ) & 0x1; unsigned int bootsel1 = (bootsel >> 1 ) & 0x1; unsigned int bootsel2 = (bootsel >> 2 ) & 0x1; unsigned int mru_remap = spl_get_mru_reg(MRU_REMAP); unsigned int mru_reg7 = (spl_get_mru_reg(MRU_REG7) & 0x1); unsigned int ns_forbid = spl_get_mru_reg(SEC_NS_FORBIT); printf_spl("SPL: %s secure boot, nsforbid(%u)\n", (ns_forbid == NONE_SECURE_BOOT_FLAG ? "non" : ""), ns_forbid); printf_spl("SPL: boot from %s, bootmod(%u)\n", (bootmod ? "rom" : "norflash"), bootmod); spl_get_spinor_doubleboot(); #if BOOT_OS_LITEOS /*启动方式1 无管理双boot*/ if (ns_forbid == NONE_SECURE_BOOT_FLAG && bootmod == 0 && bootsel0 == 0 && bootsel1 == 0 && bootsel2 == 0) { printf_spl("SPL: boot %s, mru_remap(%u)\n", (mru_remap ? "back" : "main"), mru_remap); return (mru_reg7 ? CONFIG_NORDOUBOOT_LITEOS_BACKUP : CONFIG_NORDOUBOOT_LITEOS_MAIN); } /*启动方式2, 9, 14*/ if ((ns_forbid == NONE_SECURE_BOOT_FLAG && bootmod == 0 && bootsel0 == 0 && bootsel2 == 0 && bootsel1 == 1) || \ (ns_forbid == NONE_SECURE_BOOT_FLAG && bootsel0 == 0 && bootsel2 == 0 && bootmod == 1) || \ (ns_forbid != NONE_SECURE_BOOT_FLAG && bootsel0 == 0 && bootsel2 == 0 )) { printf_spl("SPL: boot area %s, mrureg7(%u)\n", (mru_reg7 ? "back" : "main"), mru_reg7); return (mru_reg7 ? CONFIG_NORBOOT_LITEOS_BACKUP : CONFIG_NORBOOT_LITEOS_MAIN); } #else /*启动方式7 有管理双boot*/ if (ns_forbid == NONE_SECURE_BOOT_FLAG && bootmod == 0 && bootsel0 == 1 && bootsel1 == 0 && bootsel2 == 1) { printf_spl("SPL: boot %s, mru_remap(%u)\n", (mru_remap ? "back" : "main"), mru_remap); return (mru_reg7 ? CONFIG_NORDOUBOOT_UBOOT_BACKUP : CONFIG_NORDOUBOOT_UBOOT_MAIN); } /*启动方式13,18*/ if ((ns_forbid == NONE_SECURE_BOOT_FLAG && bootmod == 1 && bootsel0 == 1 && bootsel2 == 1) || \ (ns_forbid != NONE_SECURE_BOOT_FLAG && bootsel0 == 1 && bootsel2 == 1 )) { printf_spl("SPL: boot area %s, mrureg7(%u)\n", (mru_reg7 ? "back" : "main"), mru_reg7); return (mru_reg7 ? CONFIG_NORBOOT_UBOOT_BACKUP : CONFIG_NORBOOT_UBOOT_MAIN); } #endif printf("SPL: not support boot type\n"); return -1; } #endif #define FMC_NAND_BL_INDEX2 2 #define FMC_NOR_WL_INDEX2 2 #define FMC_NOR_WL_INDEX3 3 #define FMC0_SPI_NAND_UBOOT_SIZE 0x800000 #define FMC0_SPI_NOR_LITEOS_SIZE 0x400000 #define FMC1_DOUBLE_NOR_DOUBLE_BOOT_LITEOS_MAIN_BASE 0x0 #define FMC0_SINGLE_NOR_DOUBLE_BOOT_LITEOS_BASE 0x800000 #define FMC0_SINGLE_NOR_SINGLE_BOOT_LITEOS_BASE 0x940000 #define FMC1_SPI_NOR_UBOOT_SIZE 0x400000 uint32_t spl_nand_get_uboot_raw_page(void); void spl_set_flash_protect(void) { unsigned int bootsel = spl_get_bootsel(); unsigned int bootsel0 = (bootsel >> 0 ) & 0x1; unsigned int bootsel2 = (bootsel >> 2 ) & 0x1; unsigned int nor_next_boot_base; #if !BOOT_OS_LITEOS unsigned int nand_next_boot_base; #endif if ((bootsel0 == 0) && (bootsel2 == 1)) { // nand启动 #if !BOOT_OS_LITEOS nand_next_boot_base = spl_nand_get_uboot_raw_page(); (void)fmc_nand_bl_with_addr_config_addr(0, FMC_NAND_BL_INDEX2, nand_next_boot_base, nand_next_boot_base + FMC0_SPI_NAND_UBOOT_SIZE); (void)fmc_nand_lock_config(0, 1); #endif } else { // nor启动 nor_next_boot_base = spl_nor_get_uboot_base(); #if BOOT_OS_LITEOS /* code区 */ (void)spi_flash_lock_config(0, 1); (void)spi_flash_wl_addr_config_addr(0, FMC_NOR_WL_INDEX2, nor_next_boot_base, nor_next_boot_base + FMC0_SPI_NOR_LITEOS_SIZE); #else if (nor_next_boot_base > 0x10000000) { nor_next_boot_base = nor_next_boot_base - 0x10000000; } (void)spi_flash_wl_addr_config_addr(1, FMC_NOR_WL_INDEX2, nor_next_boot_base, nor_next_boot_base + FMC1_SPI_NOR_UBOOT_SIZE); (void)spi_flash_lock_config(1, 1); #endif } } #if BOOT_OS_LITEOS void spl_set_flash_liteos_run_protect(void) { unsigned int bootsel = spl_get_bootsel(); unsigned int bootsel1 = (bootsel >> 1 ) & 0x1; unsigned int bootsel3 = (bootsel >> 3 ) & 0x1; unsigned int bootmod = ((spl_get_mru_reg(MRU_CFG1) & MRU_CFG1_BOOTMOD_MASK ) >> MRU_CFG1_BOOTMOD_SHIFT); unsigned int ns_forbid = spl_get_mru_reg(SEC_NS_FORBIT); /* run区 */ if (bootsel3 == 1) { // 双nor (void)spi_flash_lock_config(1, 1); (void)spi_flash_wl_addr_config_addr(1, FMC_NOR_WL_INDEX3, FMC1_DOUBLE_NOR_DOUBLE_BOOT_LITEOS_MAIN_BASE, FMC1_DOUBLE_NOR_DOUBLE_BOOT_LITEOS_MAIN_BASE + FMC0_SPI_NOR_LITEOS_SIZE - 1); (void)spi_flash_xip_addr_protect(1, 0, FMC1_DOUBLE_NOR_DOUBLE_BOOT_LITEOS_MAIN_BASE, FMC1_DOUBLE_NOR_DOUBLE_BOOT_LITEOS_MAIN_BASE + FMC0_SPI_NOR_LITEOS_SIZE - 1); } else if ((bootsel3 == 0) && (bootsel1 == 0) && (bootmod == 0) && (ns_forbid == NONE_SECURE_BOOT_FLAG)) { //单nor 双boot (void)spi_flash_wl_addr_config_addr(0, FMC_NOR_WL_INDEX3, FMC0_SINGLE_NOR_DOUBLE_BOOT_LITEOS_BASE, FMC0_SINGLE_NOR_DOUBLE_BOOT_LITEOS_BASE + FMC0_SPI_NOR_LITEOS_SIZE - 1); (void)spi_flash_xip_addr_protect(0, 0, FMC0_SINGLE_NOR_DOUBLE_BOOT_LITEOS_BASE, FMC0_SINGLE_NOR_DOUBLE_BOOT_LITEOS_BASE + FMC0_SPI_NOR_LITEOS_SIZE - 1); } else { //单nor 单boot (void)spi_flash_wl_addr_config_addr(0, FMC_NOR_WL_INDEX3, FMC0_SINGLE_NOR_SINGLE_BOOT_LITEOS_BASE, FMC0_SINGLE_NOR_SINGLE_BOOT_LITEOS_BASE + FMC0_SPI_NOR_LITEOS_SIZE - 1); (void)spi_flash_xip_addr_protect(0, 0, FMC0_SINGLE_NOR_SINGLE_BOOT_LITEOS_BASE, FMC0_SINGLE_NOR_SINGLE_BOOT_LITEOS_BASE + FMC0_SPI_NOR_LITEOS_SIZE - 1); } } #endif #ifdef EXEC_ENV_2125_EVB uint32_t spl_nand_get_uboot_raw_page(void) { unsigned int mru_reg7 = (spl_get_mru_reg(MRU_REG7) & 0x1); printf("SPL: boot from %s, mru_reg7(%u)\n", (mru_reg7 ? "backup" : "main"), mru_reg7); return (mru_reg7 ? CONFIG_4M_NANDBOOT_UBOOT_BACKUP : CONFIG_4M_NANDBOOT_UBOOT_MAIN); } #else #if !BOOT_OS_LITEOS uint32_t spl_nand_get_uboot_raw_page(void) { unsigned int mru_reg7 = (spl_get_mru_reg(MRU_REG7) & 0x1); unsigned int bootsel = spl_get_bootsel(); unsigned int bootsel0 = (bootsel >> 0 ) & 0x1; unsigned int bootsel1 = (bootsel >> 1 ) & 0x1; unsigned int bootsel2 = (bootsel >> 2 ) & 0x1; if (bootsel0 == 0 && bootsel2 == 1 && bootsel1 == 0) { printf_spl("SPL: boot area %s, mrureg7(%u)\n", (mru_reg7 ? "back" : "main"), mru_reg7); return (mru_reg7 ? CONFIG_2M_NANDBOOT_UBOOT_BACKUP : CONFIG_2M_NANDBOOT_UBOOT_MAIN); } if (bootsel0 == 0 && bootsel2 == 1 && bootsel1 == 1) { printf_spl("SPL: boot area %s, mrureg7(%u)\n", (mru_reg7 ? "back" : "main"), mru_reg7); return (mru_reg7 ? CONFIG_4M_NANDBOOT_UBOOT_BACKUP : CONFIG_4M_NANDBOOT_UBOOT_MAIN); } printf("SPL: not support boot type\n"); return -1; } #endif #endif #ifdef EXEC_ENV_2125_EVB u32 spl_boot_device(void) { unsigned int bootsel0 = (spl_get_bootsel() & 0x1); printf("SPL: boot from %s, bootsel0(%u)\n", (bootsel0 ? "nandflash" : "norflash"), bootsel0); return (bootsel0 ? BOOT_DEVICE_NAND : BOOT_DEVICE_SPI); } #else u32 spl_boot_device(void) { unsigned int bootsel = spl_get_bootsel(); unsigned int bootsel0 = (bootsel >> 0 ) & 0x1; unsigned int bootsel2 = (bootsel >> 2 ) & 0x1; unsigned int bootsel3 = (bootsel >> 3 ) & 0x1; printf_spl("SPL: bootsel0(%u),bootsel2(%u), bootsel3(%u)\n", bootsel0 , bootsel2, bootsel3); if (bootsel0 == 0) { printf_spl("SPL: boot from FMC0 %s, bootsel2(%u)\n", (bootsel2 ? "nand" : "spinor") ,bootsel2); /*当bootsel2 =1 时必为有管理场景;当bootsel2 =0 时必为无管理场景,此时需要通过FMC NOR驱动读写LITEOS到运行地址*/ return (bootsel2 ? BOOT_DEVICE_NAND : BOOT_DEVICE_SPI); } else { if(bootsel3 == 1) { // printf_spl("SPL: boot from FMC1 nor\n"); /*必为有管理场景,SPI通过boot方式拷贝uboot到DDR*/ return (BOOT_DEVICE_NOR); } else { printf_spl("SPL: boot from FMC1 but no flash in FMC1\n"); return -1; } } } #endif unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash) { return spl_nor_get_uboot_base(); } #if 1 //#ifdef MBIST_EN #define SECTION_RAM_CODE __attribute__((section(".ram_code"))) #if 0 void SECTION_RAM_CODE mbist_l2_test(void) { int cnt = 0x80000; char *pdest = 0x30080000; //清空L2数据,检测是否有异常情况发生 while ((cnt)-- > 0) { *pdest++ = 0; } //启动Mbist //等待硬件mbist完成?软件如何感知 //置位老化结束标志 *(volatile uint64_t *)(MBIST_FINISH_FLAG_ADDR) = MBIST_FINISH_FLAG_VALUE; //开内狗等待狗超时 *(volatile uint64_t *)(0x3022A000 + 0x0) = 1; //切换为软件喂外狗 *(volatile uint64_t *)(0x3022D000 + 0x4) = 1; asm volatile("b ."); } #endif static void raw_write_daif(unsigned int daif) { __asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory"); } static void hardware_feed_wdg_switch(int num) { //切换回硬件喂狗时,需要先鉴权 writel(0xAA5555AA, (HFD_BASE + HFD_AUTH_OFFSET)); writel(0xAABBCCDD, (HFD_BASE + HFD_AUTH_OFFSET)); //需要设置喂外狗次数为无限次,否则喂6次就会停 writel(num, (HFD_BASE + HFD_NUM_OFFSET)); //此时才能切换回硬件喂狗 writel(0, (HFD_BASE + HFD_SFDEN_OFFSET)); } static void designware_wdt_disable(uint64_t base) { /*由于WDG CR的bit0 无法直接写0,需要特殊流程进行解锁寄存器 (DW_WDT_AUTH为额外设计的寄存器)*/ writel(0x5555aaaa, (base + 0X1C)); writel(0xaaaa5555, (base + 0X1C)); writel(0, (base + 0X00)); } static unsigned int designware_wdt_is_enabled(uint64_t base) { return readl(base + 0x00) & BIT(0); } static void hw_watchdog_reset(uint64_t base) { if (designware_wdt_is_enabled(base)) /* restart the watchdog counter */ writel(0x76, (0x3022A000 + 0x0C)); } static void designware_wdt_stop(uint64_t base) { hw_watchdog_reset(base); designware_wdt_disable(base); } void mbist_start(void) { /*读 RAM 空间是否有老化标志,且老化标志未结束*/ int mbist_enable = readl(MBIST_ENBALE_FLAG_ADDR); int mbist_finish = readl(MBIST_FINISH_FLAG_ADDR); if(mbist_enable == MBIST_ENBALE_FLAG_VALUE && mbist_finish != MBIST_FINISH_FLAG_VALUE) { printf_spl("SPL: prepare Mbist test\n"); //关闭内狗 designware_wdt_stop(0x3022A000); //外狗切换为硬件喂狗 hardware_feed_wdg_switch(0); //关闭中断 raw_write_daif((1<<6 | 1<<7 | 1<<8 | 1<<9)); #if 0 mbist_l2_test(); #else #if BOOT_OS_LITEOS memcpy((void *)(uintptr_t)(0x30060000),(void *)(uintptr_t)(0x300A3300+0x3bd00) ,32*1024); #else memcpy((void *)(uintptr_t)(0x30060000),(void *)(uintptr_t)(0x300A3300+0x54d00) ,32*1024); #endif void ( *entry ) ( void ); /* Jump to the target entry */ entry = ( void ( * ) ( void ) ) 0x30060000; printf_spl("SPL :Jump to Mbist.\n" ); udelay(10); entry(); #endif } //拷贝MBIST 到FLASH if(mbist_finish == MBIST_FINISH_FLAG_VALUE) { printf_spl("MBIST: test finish, result OK\n"); //清除32K SRAM数据 memset((void *)CONFIG_SYS_INIT_RAM_ADDR, 0, CONFIG_SYS_INIT_RAM_SIZE); } } #endif void board_init_f(ulong dummy) { int ret; unsigned int bootsel0 = (spl_get_bootsel() & 0x1); bootsel0 = bootsel0 ? BOOT_DEVICE_NAND : BOOT_DEVICE_NOR; #ifdef CONFIG_DEBUG_UART /* * Debug UART can be used from here if required: * * debug_uart_init(); * printch('a'); * printhex8(0x1234); * printascii("string"); */ //Repeat Call in crt0_64.S,printf //debug_uart_init(); #endif mbist_start(); board_early_init_f(); ret = spl_early_init(); if (ret) { debug("spl_early_init() failed: %d\n", ret); hang(); } timer_init(); preloader_console_init(); arch_cpu_init(); pll_init(); #ifndef EXEC_ENV_2125_EVB spl_set_flash_protect(); #endif } /* Override weak function defined in SPL framework to enable validation * of main u-boot image before jumping to u-boot image. */ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { typedef void __noreturn (*image_entry_noargs_t)(void); image_entry_noargs_t image_entry = (image_entry_noargs_t)(spl_image->entry_point); /* Validation codes */ printf("Jumping to U-Boot at address 0x%lx\n", spl_image->entry_point); image_entry(); } static int spl_abortboot(int abort_times, int bootdelay) { int abort = 0; int abort_ascl = 0; unsigned long ts; if (abort_times == 0) { printf("Press 'ctrl+C/c' to stop autoboot: %2d ", bootdelay); abort_ascl = 0x3; } else { printf("Press 'ctrl+D/d' to stop autoboot: %2d ", bootdelay); abort_ascl = 0x4; } /* * Check if key already pressed */ if (tstc()) { /* we got a key press */ if(abort_ascl == getchar()) /* consume input */ { puts("\b\b\b 0"); abort = 1; /* don't auto boot */ } } while ((bootdelay > 0) && (!abort)) { --bootdelay; /* delay 1000 ms */ ts = get_timer(0); do { if (tstc()) { /* we got a key press */ if(abort_ascl == getchar()) { abort = 1; /* don't auto boot */ bootdelay = 0; /* no more delay */ break; } } #ifdef PLD_EMU /*PLD环境下延时需要减少*/ udelay(10); #else udelay(10000); #endif } while (!abort && get_timer(ts) < 1000); printf("\b\b\b%2d ", bootdelay); } putc('\n'); return abort; } /* for SPL command line */ void spl_shell_poll(int abort_times) { //Generic_Timer_init(); if(spl_abortboot(abort_times, 1)) { printf("spl enter cli_loop \n"); cli_simple_loop(); } } void spl_shell_enter(void) { printf("spl enter cli_loop \n"); cli_simple_loop(); } void spl_board_prepare_for_boot(void) { } 这是spl的代码,是厂家提供的代码,没有修改过,原来是nor+nand启动,就能正常初始化ddr的,为什么穷改成单nand启动了,就不行了?
09-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值