So I am currently working on understanding how to Receive Side Scaling (RSS) Offloads work inside DPDK (Data Plane Development Kit). So basically from my understanding depending on which offload you have selected, it calculates a Hash value and uses that to place your packet for processing on a specific Queue, which is binded to a specific CPU Core.
So I have 2 Queries regarding this:
When I use RSS offload of **ETH_RSS_IPV6_EX** , I am unable to get
a Hash value other than Zero, meaning the packet is considered
invalid in accordance to the RSS Offload selected, even though my
Mellanox card supports this offload. I have sent the following Scapy packet but still hash is coming to be 0: sendp(Ether(dst="AA:AA:BB:BB:CC:DD")/IPv6(dst="a:a:a:a:a:a:a:b",src="a:a:a:a:a:a:a:c",nh=60)/IPv6ExtHdrDestOpt(nh=43,options=HAO(hoa="a:a:a:a:a:a:a:d"))/IPv6ExtHdrRouting(nh=59,type=2,addresses=["a:a:a:a:a:a:a:e"]),iface="enp4s0f0",count=1).
(On which packets to manipulate I got this resource from https://learn.microsoft.com/en-us/windows-hardware/drivers/network/rss-hashing-types#ndis_hash_ipv6_ex, but I believe there might be a difference between these RSS Offloads and the ones DPDK has.) What does this EX term mean in the RSS Offload.
Apart from that, can someone point me to a resource that explains the
RSS Offloads, one at a time, that are inside the DPDK, some of them being the
following (If you have an understanding of these, providing a jest of them can also be helpful):
#define ETH_RSS_IPV4 (1ULL << 2)
#define ETH_RSS_FRAG_IPV4 (1ULL << 3)
#define ETH_RSS_NONFRAG_IPV4_TCP (1ULL << 4)
#define ETH_RSS_NONFRAG_IPV4_UDP (1ULL << 5)
#define ETH_RSS_NONFRAG_IPV4_SCTP (1ULL << 6)
#define ETH_RSS_NONFRAG_IPV4_OTHER (1ULL << 7)
#define ETH_RSS_IPV6 (1ULL << 8)
#define ETH_RSS_FRAG_IPV6 (1ULL << 9)
#define ETH_RSS_NONFRAG_IPV6_TCP (1ULL << 10)
#define ETH_RSS_NONFRAG_IPV6_UDP (1ULL << 11)
#define ETH_RSS_NONFRAG_IPV6_SCTP (1ULL << 12)
#define ETH_RSS_NONFRAG_IPV6_OTHER (1ULL << 13)
#define ETH_RSS_L2_PAYLOAD (1ULL << 14)
#define ETH_RSS_IPV6_EX (1ULL << 15)
#define ETH_RSS_IPV6_TCP_EX (1ULL << 16)
#define ETH_RSS_IPV6_UDP_EX (1ULL << 17)
Please feel free for any clarifications or elaboration you require.
Thanks in Advance.
Edit_1 (In response to Vipin's comment):
I am enabling the RSS in this strucutre (ETH_RSS_IPV6_EX):
static struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
.split_hdr_size = 0,
.offloads = DEV_RX_OFFLOAD_CHECKSUM,
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,
.rss_hf = ETH_RSS_IPV6_EX, //ETH_RSS_IP //Orignal, //AU: Changing Hash Application
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
};
DPDK Version I am using is 20.08.
NIC being used is Mellanox ConnectX-5
I am using the DPDK l3fwd application as the base and testing on it.
Okay, so guys I contacted Mellanox support and they have replied that they have checked with their DPDK expert and reported that they do not support IPv6 Extension headers support in RSS offloads, thus the reason zero hash was being calculated when IPV6_EX RSS offload was used.
The question I asked Mellanox was in regards to ConnectX-5 and ConnectX-6.
Thank you #Vipin for your support.
As explained in the comments, ETH_RSS_IPV6_EX is a generic place holder. Not all drivers support the same. So depending upon PMD, driver and firmware extended features like RSS based on SRC-IP/DST-IP or some part of fields will be supported. example ETH_RSS_IPV6_TCP will be used if IPV6 has TCP in it and ETH_RSS_IPV6_TCP_EX will use if TCP is extended header.
note: igb and ixgbe supports _EX while i40e does not, you check intel NIC. DPDK mail thread discussion. Hence do not expect every NIC will has same features set for RSS
Related
I'm trying to add tinyUSB library but I get this define CFG_TUSB_RHPORT1_MODE as not defined.With this line I have problem. If i comment this line, my usb is not appear in device manager. I did this tutorial. Could you check what i'm doing wrong (link to repo below)?
At the end I want to make CDC communication without misc.
Okey I solved issue. Silly I did't think to change number from 1 to 0... so it looks now:
if (!(rhport == 1 && (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED))) usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN;
and in tusb_config.h I added:
#define CFG_TUSB_MCU OPT_MCU_STM32F4
#define CFG_TUSB_OS OPT_OS_NONE
#define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED
#define BOARD_DEVICE_RHPORT_NUM 0
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED)
Now its working :D Discussion can be closed
Had similar issue with RHPORT1 in my case - STM32F407:
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_NONE)
I will start a project which needs a QSPI protocol. The component I will use is a 16-bit ADC which supports QSPI with all combinations of clock phase and polarity. Unfortunately, I couldn't find a source on the internet that points to QSPI on STM32, which works with other components rather than Flash memories. Now, my question: Can I use STM32's QSPI protocol to communicate with other devices that support QSPI? Or is it just configured to be used for memories?
The ADC component I want to use is: ADS9224R (16-bit, 3MSPS)
Here is the image of the datasheet that illustrates this device supports the full QSPI protocol.
Many thanks
page 33 of the datasheet
The STM32 QSPI can work in several modes. The Memory Mapped mode is specifically designed for memories. The Indirect mode however can be used for any peripheral. In this mode you can specify the format of the commands that are exchanged: presence of an instruction, of an adress, of data, etc...
See register QUADSPI_CCR.
QUADSPI supports indirect mode, where for each data transaction you manually specify command, number of bytes in address part, number of data bytes, number of lines used for each part of the communication and so on. Don't know whether HAL supports all of that, it would probably be more efficient to work directly with QUADSPI registers - there are simply too many levers and controls you need to set up, and if the library is missing something, things may not work as you want, and QUADSPI is pretty unpleasant to debug. Luckily, after initial setup, you probably won't need to change very much in its settings.
In fact, some time ago, when I was learning QUADSPI, I wrote my own indirect read/write for QUADSPI flash. Purely a demo program for myself. With a bit of tweaking it shouldn't be hard to adapt it. From my personal experience, QUADSPI is a little hard at first, I spent a pair of weeks debugging it with logic analyzer until I got it to work. Or maybe it was due to my general inexperience.
Below you can find one of my functions, which can be used after initial setup of QUADSPI. Other communication functions are around the same length. You only need to set some settings in a few registers. Be careful with the order of your register manipulations - there is no "start communication" flag/bit/command. Communication starts automatically when you set some parameters in specific registers. This is explicitly stated in the reference manual, QUADSPI section, which was the only documentation I used to write my code. There is surprisingly limited information on QUADSPI available on the Internet, even less with registers.
Here is a piece from my basic example code on registers:
void QSPI_readMemoryBytesQuad(uint32_t address, uint32_t length, uint8_t destination[]) {
while (QUADSPI->SR & QUADSPI_SR_BUSY); //Make sure no operation is going on
QUADSPI->FCR = QUADSPI_FCR_CTOF | QUADSPI_FCR_CSMF | QUADSPI_FCR_CTCF | QUADSPI_FCR_CTEF; // clear all flags
QUADSPI->DLR = length - 1U; //Set number of bytes to read
QUADSPI->CR = (QUADSPI->CR & ~(QUADSPI_CR_FTHRES)) | (0x00 << QUADSPI_CR_FTHRES_Pos); //Set FIFO threshold to 1
/*
* Set communication configuration register
* Functional mode: Indirect read
* Data mode: 4 Lines
* Instruction mode: 4 Lines
* Address mode: 4 Lines
* Address size: 24 Bits
* Dummy cycles: 6 Cycles
* Instruction: Quad Output Fast Read
*
* Set 24-bit Address
*
*/
QUADSPI->CCR =
(QSPI_FMODE_INDIRECT_READ << QUADSPI_CCR_FMODE_Pos) |
(QIO_QUAD << QUADSPI_CCR_DMODE_Pos) |
(QIO_QUAD << QUADSPI_CCR_IMODE_Pos) |
(QIO_QUAD << QUADSPI_CCR_ADMODE_Pos) |
(QSPI_ADSIZE_24 << QUADSPI_CCR_ADSIZE_Pos) |
(0x06 << QUADSPI_CCR_DCYC_Pos) |
(MT25QL128ABA1EW9_COMMAND_QUAD_OUTPUT_FAST_READ << QUADSPI_CCR_INSTRUCTION_Pos);
QUADSPI->AR = (0xFFFFFF) & address;
/* ---------- Communication Starts Automatically ----------*/
while (QUADSPI->SR & QUADSPI_SR_BUSY) {
if (QUADSPI->SR & QUADSPI_SR_FTF) {
*destination = *((uint8_t*) &(QUADSPI->DR)); //Read a byte from data register, byte access
destination++;
}
}
QUADSPI->FCR = QUADSPI_FCR_CTOF | QUADSPI_FCR_CSMF | QUADSPI_FCR_CTCF | QUADSPI_FCR_CTEF; //Clear flags
}
It is a little crude, but it may be a good starting point for you, and it's well-tested and definitely works. You can find all my functions here (GitHub). Combine it with reading the QUADSPI section of the reference manual, and you should start to get a grasp of how to make it work.
Your job will be to determine what kind of commands and in what format you need to send to your QSPI slave device. That information is available in the device's datasheet. Make sure you send command and address and every other part on the correct number of QUADSPI lines. For example, sometimes you need to have command on 1 line and data on all 4, all in the same transaction. Make sure you set dummy cycles, if they are required for some operation. Pay special attention at how you read data that you receive via QUADSPI. You can read it in 32-bit words at once (if incoming data is a whole number of 32-bit words). In my case - in the function provided here - I read it by individual bytes, hence such a scary looking *destination = *((uint8_t*) &(QUADSPI->DR));, where I take an address of the data register, cast it to pointer to uint8_t and dereference it. Otherwise, if you read DR just as QUADSPI->DR, your MCU reads 32-bit word for every byte that arrives, and QUADSPI goes crazy and hangs and shows various errors and triggers FIFO threshold flags and stuff. Just be mindful of how you read that register.
I want to get the limiting address of the flash in the code itself, or at least the size of this flash.
I found only the start address of the flash in the stm32f302xc.h file, but did not find the end address.
/** #addtogroup Peripheral_memory_map
* #{
*/
#define FLASH_BASE 0x08000000UL /*!< FLASH base address in the alias region */
#define SRAM_BASE 0x20000000UL /*!< SRAM base address in the alias region */
#define PERIPH_BASE 0x40000000UL /*!< Peripheral base address in the alias region */
#define SRAM_BB_BASE 0x22000000UL /*!< SRAM base address in the bit-band region */
#define PERIPH_BB_BASE 0x42000000UL /*!< Peripheral base address in the bit-band region */
What defines are responsible for this, thanks.
What you want is described in the reference manual RM0366 in section 29.2 Memory size data register.
ST provide this functionaility but for some reason they don't always give an easy way to access it in the headers.
The address of this register is FLASHSIZE_BASE. You have to read it at run-time, eg:
uint16_t flash_size_kb = *(const uint16_t*)FLASHSIZE_BASE;
STM32 MCU families come in different flash sizes, that's why it's not defined in their header files. Although STM32CubeMX code generator could, in theory, add it when you select the exact model of your MCU. But this would mean code might not work if you flash it to variant with a different flash size.
However some STM32 MCUs come with a Flash size data register that contains information about the flash size. This address is often found in a header file and sometimes a macro is included. Note that it not a compile time constant, but a ROM constant that needs to be read at runtime.
stm32f3xx_hal_flash_ex.h contains the following register address:
#define FLASH_SIZE_DATA_REGISTER (0x1FFFF7CCU)
You can use it like this:
const size_t FLASH_SIZE = (*((uint16_t*)FLASH_SIZE_DATA_REGISTER)) << 10;
For the stm32g4xx there is a macro defined in stm32g4xx_hal_flash.h:
FLASH_SIZE
Be careful with writing your own macro for this as the flash size is not always linear with the value in the register. In the case of the stm32g4xx the value 0xFFFF means either 128kiB or 512kiB as seen below:
#define FLASH_SIZE_DATA_REGISTER FLASHSIZE_BASE
#if defined (FLASH_OPTR_DBANK)
#define FLASH_SIZE ((((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0xFFFFU)) ? (0x200UL << 10U) : \
(((*((uint32_t *)FLASH_SIZE_DATA_REGISTER)) & 0xFFFFUL) << 10U))
#define FLASH_BANK_SIZE (FLASH_SIZE >> 1)
#define FLASH_PAGE_NB 128U
#define FLASH_PAGE_SIZE_128_BITS 0x1000U /* 4 KB */
#else
#define FLASH_SIZE ((((*((uint16_t *)FLASH_SIZE_DATA_REGISTER)) == 0xFFFFU)) ? (0x80UL << 10U) : \
(((*((uint32_t *)FLASH_SIZE_DATA_REGISTER)) & 0xFFFFUL) << 10U))
#define FLASH_BANK_SIZE (FLASH_SIZE)
#define FLASH_PAGE_NB ((FLASH_SIZE == 0x00080000U) ? 256U : 64U)
#endif
The same applies to flash page size. Page size depends on the family and sometimes on the flash size. Sometimes ST provides a macro for this too.
Hi I am developing an application in BlackBerry 10 platform which will calculate data usage and voice usage of user device for particular duration.
There are some of the feasibility check need to be done for this which are as follows
Does BB10 API supports data usage calculation? If yes, Can I differentiate 3G/Cellular data from WiFi data?If yes, how can I achieve this?
How can I calculate Voice usage in BB 10 application? Voice usage is nothing but duration of all calls happened within particular timespan
Is there any API BB10 provides through which I can check if device is currently in Roaming or not?
Please let me know if this can be done in BB 10 application
Does BB10 API supports data usage calculation?
Yes, there are a few for API's for this
Can I differentiate 3G/Cellular data from WiFi data?
Yurp you can.
1) Add the following line to your .pro file:
LIBS += -lbbdevice
2) Make sure you include:
#include <bb/device/NetworkDataUsage>
3) Getting data useage for cellular network only
bb::device::NetworkDataUsage *nduCell = new bb::device::NetworkDataUsage("cellular0");
nduCell ->update();
quint64 bytesSent = nduCell ->bytesSent();
quint64 bytesReceived = nduCell ->bytesReceived();
4) Getting data useage for wifi only
bb::device::NetworkDataUsage *nduWifi = new bb::device::NetworkDataUsage("tiw_sta0");
nduWifi ->update();
quint64 bytesSent = nduWifi ->bytesSent();
quint64 bytesReceived = nduWifi ->bytesReceived();
That will give your the data useage since the device has started.
You will need to call ndu->update() regularly to get the most recent data usage statistics.
Extra Info:
Changing the parameter for the NetworkDataUsage changes the interface it minitors:
cellular0 == Cellular
tiw_sta0 == Wifi
ecm0 == USB
To find out which interfaces are available on your device:
1) Add the following line to your .pro file:
QT += network
2) Make sure you include:
#include <QNetworkInterface>
3) Displaying available interfaces
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
for (int i = 0; i < interfaces.size(); i++) {
qDebug() << QString::number(i) + ": " + interfaces.value(i).humanReadableName();
}
How can I calculate Voice usage in BB 10 application? Voice usage is nothing but duration of all calls happened within particular timespan
This can be done using Phone class.
There is signal call void callUpdated (const bb::system::phone::Call &call, ) using which we can get to know if incoming call is received or outgoing call is initiated.
With the combination of this and Timer class we can calculate Voice usage of device. (This code is not tested)
We've discovered our complex iPhone app (ObjC, C++, JavaScript/WebKit) is leaking file descriptors under unusual circumstances.
I need to know which files (by file path) we are leaving open.
I want something like the BSD command "lsof", which, of course, isn't available in iOS 4, at least not to me. Ideally a C or ObjC function. Or a tool, like shark or Instruments. Just need the files for our running app, not (as with lsof) for all apps/processes.
We do all sorts of things with files, and the code that is failing with "Too many open files" hasn't changed in ages, and since the circumstances are unusual, this could have crept in months ago. So there's no need to remind me to look at code that opens files and make sure I close them. I know that already. Would be nice to narrow it down with something lsof-esque. Thanks.
#import <sys/types.h>
#import <fcntl.h>
#import <errno.h>
#import <sys/param.h>
+(void) lsof
{
int flags;
int fd;
char buf[MAXPATHLEN+1] ;
int n = 1 ;
for (fd = 0; fd < (int) FD_SETSIZE; fd++) {
errno = 0;
flags = fcntl(fd, F_GETFD, 0);
if (flags == -1 && errno) {
if (errno != EBADF) {
return ;
}
else
continue;
}
fcntl(fd , F_GETPATH, buf ) ;
NSLog( #"File Descriptor %d number %d in use for: %s",fd,n , buf ) ;
++n ;
}
}
For future reference, I ran into a similar problem on an iPhone 11 with iOS 13; I was creating too many file descriptors (FDs) by creating too many files and sockets. My solution was to increase FDs at runtime with setrlimit().
First I got the FD limits on my iPhone 11, with the following code:
// This goes somewhere in your code
struct rlimit rlim;
if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
std::cout << "Soft limit: " << rlim.rlim_cur << std::endl;
std::cout << "Hard limit: " << rlim.rlim_max << std::endl;
} else {
std::cout << "Unable to get file descriptor limits" << std::endl;
}
After running getrlimit(), I could confirm that on iOS 13, the soft limit is 256 FDs, and the hard limit is infinite FDs. Since I was creating > 300 FDs between files and sockets, my app was crashing.
In my case I couldn't decrease the number of FDs, so I decided to increase the FD soft limit instead, with this code:
// This goes somewhere in your code
struct rlimit rlim;
rlim.rlim_cur = NEW_SOFT_LIMIT;
rlim.rlim_max = NEW_HARD_LIMIT;
if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
std::cout << "Unable to set file descriptor limits" << std::endl;
}
NOTE: You can find more information on gettrlimit() and setrlimit() here and here.
Can you reproduce the problem running in the simulator?
If so, then you could actually use "lsof"...
update:
Ok, if you can't use the simulator, then idea #2:
When you get the "too many open files" error, call a function that iterates through all open file descriptors and dumps some information about each (for example the length and the first few bytes).
Can't you just intercept all file opens with your own function, say my_fopen, and store the descriptors along with their names so that when you have too many files opened, you can go through your list to see what's taking all the descriptors?
If Instruments isn't working well for your purposes, my next recommendation would be to run your app in the simulator, and use fs_usage on the command line to track the file descriptors you're opening and closing. Something like this:
In Terminal, run "sudo fs_usage -f filesys MyAppName", replacing MyAppName with the name of your app.
Launch your app.
Look at the file descriptor open and close commands output by fs_usage to see which files you're leaving open.
Instruments.app might be able to help you (/Developer/Applications/Instruments.app). Run your app using the System Usage tool in Instruments, and it'll probably show you what you need to know. Best of all, it can be used while running the app on your device, without jailbreaking it.
I suggest you run your app on a jailbroken iPhone, and use Backgrounder and MobileTerminal to take a look at the files currently open.
You can get an iPhone binary of lsof here: http://modmyi.com/cydia/package.php?id=6945