mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
fx3: Upgrade B2xx build
This is an upgrade to the latest FX3 SDK (1.3.5) and to the ARM gcc in version 15.3.rel1 for the build of the B2xx firmware and bootloader. All required steps are explained in the updated readme file. Additionally, some bounds checks were added both in the firmware and the bootloader, as well as some more validations and checks to prevent over- and underflows. Newly introduced checks were documented in the code.
This commit is contained in:
parent
416988b3b6
commit
155dfbf352
@ -16,10 +16,13 @@ managing the transport from the host to the FPGA by configuring IO and DMA.
|
||||
|
||||
In order to compile the USRP B200 and B210 bootloader and firmware, you will
|
||||
need the FX3 SDK distributed by Cypress Semiconductor. You can download the
|
||||
[FX3 SDK from here](https://www.cypress.com/documentation/software-and-drivers/ez-usb-fx3-software-development-kit)
|
||||
[FX3 SDK from here](https://www.cypress.com/documentation/software-and-drivers/ez-usb-fx3-software-development-kit).
|
||||
Version 1.3.5 is known to be working.
|
||||
|
||||
From the SDK, extract the ARM cross-compile toolchain tarball `ARM-GCC.tar.gz`
|
||||
and the FX3 firmware tarball `fx3_firmware_linux.tar.gz`.
|
||||
Get the latest version of the [GNU Toolchains for ARM from arm.com](https://gitlab.arm.com/tooling/gnu-toolchains-for-arm)
|
||||
and extract it. Version 15.3.rel1 is known to be working.
|
||||
|
||||
Set up the appropriate environment variables for the build:
|
||||
|
||||
@ -32,15 +35,39 @@ Set up the appropriate environment variables for the build:
|
||||
These should look something like this:
|
||||
|
||||
```
|
||||
$ export ARMGCC_INSTALL_PATH=/path/to/my/files/arm-2013.11
|
||||
$ export ARMGCC_VERSION=4.8.1
|
||||
$ export ARMGCC_INSTALL_PATH=/path/to/my/files/arm-gnu-toolchain-15.3.rel1-x86_64-arm-none-eabi
|
||||
$ export ARMGCC_VERSION=15.3.1
|
||||
$ export FX3FWROOT=/path/to/my/files/cyfx3sdk
|
||||
```
|
||||
|
||||
The SDK makefiles invoke `arm-none-eabi-gcc` unqualified and only use
|
||||
`ARMGCC_INSTALL_PATH` to locate the libraries, so the toolchain must also be on
|
||||
your `PATH`:
|
||||
|
||||
```
|
||||
$ export PATH=$ARMGCC_INSTALL_PATH/bin:$PATH
|
||||
```
|
||||
|
||||
Without this, the build either fails with `arm-none-eabi-gcc: No such file or
|
||||
directory` or, if a different ARM toolchain happens to be installed, silently
|
||||
compiles with that compiler while linking against the libraries of the toolchain
|
||||
above. Verify the expected compiler is picked up:
|
||||
|
||||
```
|
||||
$ arm-none-eabi-gcc --version
|
||||
```
|
||||
|
||||
## Applying the Patch to the Toolchain
|
||||
|
||||
Now, you'll need to apply a patch to some files in the Cypress SDK. Apply the
|
||||
patch `b200/fx3_mem_map.patch` as follows:
|
||||
Now, you'll need to apply a patch to some files in the Cypress SDK. Before doing
|
||||
so, ensure all files in the SDK have Unix line endings and are writable for the user:
|
||||
|
||||
```
|
||||
$ cd $FX3FWROOT
|
||||
$ find . -type f -exec dos2unix {} \; -exec chmod u+w {} \;
|
||||
```
|
||||
|
||||
Apply the patch `b200/fx3_mem_map.patch` as follows:
|
||||
|
||||
```
|
||||
$ cd uhd.git/firmware/fx3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -6,43 +6,45 @@
|
||||
|
||||
#include "cyu3i2c.h"
|
||||
|
||||
static uint16_t glI2cPageSize = 0x40; /* I2C Page size to be used for transfers. */
|
||||
|
||||
/* I2c initialization for EEPROM programming. */
|
||||
void CyFxI2cInit (uint16_t pageLen) {
|
||||
void CyFxI2cInit(uint16_t pageLen)
|
||||
{
|
||||
CyU3PI2cConfig_t i2cConfig;
|
||||
|
||||
/* Initialize and configure the I2C master module. */
|
||||
CyU3PI2cInit ();
|
||||
CyU3PI2cInit();
|
||||
|
||||
/* Start the I2C master block. The bit rate is set at 100KHz.
|
||||
* The data transfer is done via DMA. */
|
||||
CyU3PMemSet ((uint8_t *)&i2cConfig, 0, sizeof(i2cConfig));
|
||||
CyU3PMemSet((uint8_t*)&i2cConfig, 0, sizeof(i2cConfig));
|
||||
i2cConfig.bitRate = CY_FX_USBI2C_I2C_BITRATE;
|
||||
i2cConfig.busTimeout = 0xFFFFFFFF;
|
||||
i2cConfig.dmaTimeout = 0xFFFF;
|
||||
i2cConfig.isDma = CyFalse;
|
||||
|
||||
CyU3PI2cSetConfig (&i2cConfig, NULL);
|
||||
CyU3PI2cSetConfig(&i2cConfig, NULL);
|
||||
glI2cPageSize = pageLen;
|
||||
}
|
||||
|
||||
/* I2C read / write for programmer application. */
|
||||
void CyFxUsbI2cTransfer (
|
||||
uint16_t byteAddress,
|
||||
uint8_t devAddr,
|
||||
uint16_t byteCount,
|
||||
uint8_t *buffer,
|
||||
CyBool_t isRead)
|
||||
void CyFxUsbI2cTransfer(uint16_t byteAddress,
|
||||
uint8_t devAddr,
|
||||
uint16_t byteCount,
|
||||
uint8_t* buffer,
|
||||
CyBool_t isRead)
|
||||
{
|
||||
CyU3PI2cPreamble_t preamble;
|
||||
uint16_t pageCount = (byteCount / glI2cPageSize);
|
||||
uint16_t resCount = glI2cPageSize;
|
||||
uint16_t resCount = glI2cPageSize;
|
||||
|
||||
if (byteCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((byteCount % glI2cPageSize) != 0) {
|
||||
pageCount ++;
|
||||
pageCount++;
|
||||
resCount = byteCount % glI2cPageSize;
|
||||
}
|
||||
|
||||
@ -56,7 +58,8 @@ void CyFxUsbI2cTransfer (
|
||||
preamble.buffer[3] = (devAddr | 0x01);
|
||||
preamble.ctrlMask = 0x0004;
|
||||
|
||||
CyU3PI2cReceiveBytes (&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);
|
||||
CyU3PI2cReceiveBytes(
|
||||
&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);
|
||||
} else {
|
||||
/* Write. Update the preamble information. */
|
||||
preamble.length = 3;
|
||||
@ -65,18 +68,19 @@ void CyFxUsbI2cTransfer (
|
||||
preamble.buffer[2] = (uint8_t)(byteAddress & 0xFF);
|
||||
preamble.ctrlMask = 0x0000;
|
||||
|
||||
CyU3PI2cTransmitBytes (&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);
|
||||
CyU3PI2cTransmitBytes(
|
||||
&preamble, buffer, (pageCount == 1) ? resCount : glI2cPageSize, 0);
|
||||
/* Wait for the write to complete. */
|
||||
preamble.length = 1;
|
||||
CyU3PI2cWaitForAck(&preamble, 200);
|
||||
}
|
||||
|
||||
/* An additional delay seems to be required after receiving an ACK. */
|
||||
CyU3PThreadSleep (1);
|
||||
CyU3PThreadSleep(1);
|
||||
|
||||
/* Update the parameters */
|
||||
byteAddress += glI2cPageSize;
|
||||
byteAddress += glI2cPageSize;
|
||||
buffer += glI2cPageSize;
|
||||
pageCount --;
|
||||
pageCount--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,33 +7,34 @@
|
||||
|
||||
#include "cyu3externcstart.h"
|
||||
|
||||
#include "cyu3usbconst.h"
|
||||
#include "cyu3types.h"
|
||||
#include "cyu3usbconst.h"
|
||||
|
||||
/* Following two definitions made in b200_main.h for consistency. */
|
||||
/* define B200_VREQ_EEPROM_WRITE (uint8_t)(0xBA) */
|
||||
/* define B200_VREQ_EEPROM_READ (uint8_t)(0xBB) */
|
||||
|
||||
static uint16_t glI2cPageSize = 0x40; /* I2C Page size to be used for transfers. */
|
||||
|
||||
/* This application uses EEPROM as the slave I2C device. The I2C EEPROM
|
||||
* part number used is 24LC256. The capacity of the EEPROM is 256K bits */
|
||||
#define CY_FX_USBI2C_I2C_MAX_CAPACITY (32 * 1024) /* Capacity in bytes */
|
||||
#define CY_FX_USBI2C_I2C_MAX_CAPACITY (32 * 1024) /* Capacity in bytes */
|
||||
|
||||
/* The following constant is defined based on the page size that the I2C
|
||||
* device support. 24LC256 support 64 byte page write access. */
|
||||
#define CY_FX_USBI2C_I2C_PAGE_SIZE (64)
|
||||
#define CY_FX_USBI2C_I2C_PAGE_SIZE (64)
|
||||
|
||||
/* I2C Data rate */
|
||||
#define CY_FX_USBI2C_I2C_BITRATE (100000)
|
||||
#define CY_FX_USBI2C_I2C_BITRATE (100000)
|
||||
|
||||
/* Give a timeout value of 5s for any programming. */
|
||||
#define CY_FX_USB_I2C_TIMEOUT (5000)
|
||||
#define CY_FX_USB_I2C_TIMEOUT (5000)
|
||||
|
||||
/* Function forward-declerations. */
|
||||
void CyFxI2cInit (uint16_t pageLen);
|
||||
void CyFxUsbI2cTransfer (uint16_t byteAddress, uint8_t devAddr,
|
||||
uint16_t byteCount, uint8_t *buffer, CyBool_t isRead);
|
||||
void CyFxI2cInit(uint16_t pageLen);
|
||||
void CyFxUsbI2cTransfer(uint16_t byteAddress,
|
||||
uint8_t devAddr,
|
||||
uint16_t byteCount,
|
||||
uint8_t* buffer,
|
||||
CyBool_t isRead);
|
||||
|
||||
#include "cyu3externcend.h"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ endif
|
||||
|
||||
MODULE = b200_main
|
||||
|
||||
SOURCE += $(MODULE).c b200_i2c.c b200_usb_descriptors.c ../common/common_helpers.c ../common/common_descriptors.c cyfxtx.c
|
||||
SOURCE += $(MODULE).c b200_i2c.c b200_usb_descriptors.c syscalls.c ../common/common_helpers.c ../common/common_descriptors.c cyfxtx.c
|
||||
|
||||
INCFLAGS = -I../common
|
||||
|
||||
|
||||
68
firmware/fx3/b200/firmware/syscalls.c
Normal file
68
firmware/fx3/b200/firmware/syscalls.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
(void)file;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fstat(int file, struct stat* st)
|
||||
{
|
||||
(void)file;
|
||||
if (st != 0) {
|
||||
st->st_mode = S_IFCHR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void)file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _read(int file, char* ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
{
|
||||
(void)status;
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
int _write(int file, const char* ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
return len;
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
diff -r -u cyfx3sdk/fw_build/boot_fw/cyfx3.ld cyfx3sdk-modified/fw_build/boot_fw/cyfx3.ld
|
||||
--- cyfx3sdk/fw_build/boot_fw/cyfx3.ld 2018-05-23 02:25:01.000000000 -0700
|
||||
+++ cyfx3sdk-modified/fw_build/boot_fw/cyfx3.ld 2020-08-22 14:54:46.407481500 -0700
|
||||
@@ -39,12 +39,18 @@
|
||||
|
||||
--- cyfx3sdk/fw_build/boot_fw/cyfx3.ld 2026-08-11 15:34:04.645797167 +0200
|
||||
+++ cyfx3sdk-modified/fw_build/boot_fw/cyfx3.ld 2026-08-11 15:51:14.427111162 +0200
|
||||
@@ -41,12 +41,18 @@
|
||||
MEMORY
|
||||
{
|
||||
I-TCM : ORIGIN = 0x100 LENGTH = 0x100
|
||||
+ BLANK : ORIGIN = 0x40070000 LENGTH = 0x0100
|
||||
SYS_MEM : ORIGIN = 0x40078000 LENGTH = 0x7000
|
||||
DATA : ORIGIN = 0x4007F000 LENGTH = 0x1000
|
||||
@ -17,12 +17,12 @@ diff -r -u cyfx3sdk/fw_build/boot_fw/cyfx3.ld cyfx3sdk-modified/fw_build/boot_fw
|
||||
+ . += 0x100;
|
||||
+ } > BLANK
|
||||
+
|
||||
.text :
|
||||
.vectors :
|
||||
{
|
||||
*(RESET)
|
||||
*(CYU3P_ITCM_SECTION)
|
||||
diff -r -u cyfx3sdk/fw_build/fx3_fw/cyfxtx.c cyfx3sdk-modified/fw_build/fx3_fw/cyfxtx.c
|
||||
--- cyfx3sdk/fw_build/fx3_fw/cyfxtx.c 2018-05-23 02:25:01.000000000 -0700
|
||||
+++ cyfx3sdk-modified/fw_build/fx3_fw/cyfxtx.c 2020-08-21 12:34:14.344699800 -0700
|
||||
--- cyfx3sdk/fw_build/fx3_fw/cyfxtx.c 2026-08-11 15:34:04.685797262 +0200
|
||||
+++ cyfx3sdk-modified/fw_build/fx3_fw/cyfxtx.c 2026-08-11 15:34:17.397827996 +0200
|
||||
@@ -98,7 +98,7 @@
|
||||
area which is used by the application code as well as the drivers to allocate thread
|
||||
stacks and other internal data structures.
|
||||
@ -33,8 +33,8 @@ diff -r -u cyfx3sdk/fw_build/fx3_fw/cyfxtx.c cyfx3sdk-modified/fw_build/fx3_fw/c
|
||||
|
||||
/*
|
||||
diff -r -u cyfx3sdk/fw_build/fx3_fw/fx3_512k.ld cyfx3sdk-modified/fw_build/fx3_fw/fx3_512k.ld
|
||||
--- cyfx3sdk/fw_build/fx3_fw/fx3_512k.ld 2018-05-23 02:25:01.000000000 -0700
|
||||
+++ cyfx3sdk-modified/fw_build/fx3_fw/fx3_512k.ld 2020-08-21 12:34:14.345050200 -0700
|
||||
--- cyfx3sdk/fw_build/fx3_fw/fx3_512k.ld 2026-08-11 15:34:04.665797215 +0200
|
||||
+++ cyfx3sdk-modified/fw_build/fx3_fw/fx3_512k.ld 2026-08-11 15:34:17.381827956 +0200
|
||||
@@ -32,11 +32,11 @@
|
||||
The default memory map used for FX3 applications is as follows:
|
||||
|
||||
@ -52,10 +52,10 @@ diff -r -u cyfx3sdk/fw_build/fx3_fw/fx3_512k.ld cyfx3sdk-modified/fw_build/fx3_f
|
||||
|
||||
Interrupt handlers are placed in I-TCM (16KB). The first 256 bytes of ITCM are
|
||||
reserved for Exception Vectors and will be loaded during firmware initialization.
|
||||
@@ -58,8 +58,8 @@
|
||||
@@ -59,8 +59,8 @@
|
||||
MEMORY
|
||||
{
|
||||
I-TCM : ORIGIN = 0x100 LENGTH = 0x3F00
|
||||
I-TCM : ORIGIN = 0x200 LENGTH = 0x3E00
|
||||
- SYS_MEM : ORIGIN = 0x40003000 LENGTH = 0x2D000
|
||||
- DATA : ORIGIN = 0x40030000 LENGTH = 0x8000
|
||||
+ SYS_MEM : ORIGIN = 0x40003000 LENGTH = 0x35000
|
||||
@ -63,7 +63,7 @@ diff -r -u cyfx3sdk/fw_build/fx3_fw/fx3_512k.ld cyfx3sdk-modified/fw_build/fx3_f
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
@@ -114,5 +114,17 @@
|
||||
@@ -115,5 +115,17 @@
|
||||
. = ALIGN(4);
|
||||
} > DATA
|
||||
__exidx_end = .;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user