Why my program gets wrong address-cell/size-cell values from Device tree? - linux-kernel

I use libfdt and I have trouble to get right address-cell/size-cells values from reserved memory region node (leaf) into my device tree.
fdt_address_cells returns 0x2 and fdt_size_cells returns 0x1 for "some-block" even though "address-cells"/"size-cells" are not specified into some-block node. fdt_address_cells/fdt_size_cells suppose to return "-FDT_BAD_NCELLS" based on their description into libfdt.h
`
reserved-memory {
#address-cells = <0x02>;
#size-cells = <0x02>;
some-block {
reg = <0x00 0xaa000000 0x00 0xbb00000>;
no-map;
compatible = "somevendor,something";
};
}
`
I expect that these function return "-FDT_BAD_NCELLS" if address-cells/size-cells are not specified into node.

From section 2.3.5. of The Devicetree specification v0.3:
If missing, a client program should assume a default value of 2 for #address-cells, and a value of 1 for #size-cells.
The documentation for the return values of fdt_address_cells() and fdt_size_cells() in libfdt agrees with this:
/**
* fdt_address_cells - retrieve address size for a bus represented in the tree
* #fdt: pointer to the device tree blob
* #nodeoffset: offset of the node to find the address size for
*
* When the node has a valid #address-cells property, returns its value.
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
* 2, if the node has no #address-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #address-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
int fdt_address_cells(const void *fdt, int nodeoffset);
/**
* fdt_size_cells - retrieve address range size for a bus represented in the
* tree
* #fdt: pointer to the device tree blob
* #nodeoffset: offset of the node to find the address range size for
*
* When the node has a valid #size-cells property, returns its value.
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
* 1, if the node has no #size-cells property
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* -FDT_ERR_TRUNCATED, standard meanings
*/
int fdt_size_cells(const void *fdt, int nodeoffset);

Related

Red Black Tree - return all the values greater than X in sorted order

I really need this feature in my project. Namely, I have a Red Black Tree and I need to write a function to return all the values higher than X in the sorted order.
Example:
Given the following RBT
https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Red-black_tree_example.svg/500px-Red-black_tree_example.svg.png
function greater(6) should return [ 6, 8, 11, 13, 15, 17, 22, 25, 27]
function greater(11) should return [13, 15, 17, 22, 25, 27]
Any suggestion ? What is the recursion to do it given the fact that I already have found the node X ?
Do an inorder traversal on the tree, when you find a value greater than the given value push it to the result array and return it back.
Updated for optimisation:
We don't have to check the left subtree of the current node if the value of the current node is < than the target boundary value. Only check the left subtree if its value is >= target boundary value.
Here is the working example with the Javascript code.
/**
* Function to create a tree node with null left and right child
* #param {Number} val
* #return {Node} tree node
* */
function Node(val) {
this.value = val;
this.left = null;
this.right = null;
}
// Constructing the tree
const root = new Node(13);
root.left = new Node(8);
root.left.left = new Node(1);
root.left.left.right = new Node(6);
root.left.right = new Node(11);
root.right = new Node(17);
root.right.left = new Node(15);
root.right.right = new Node(25);
root.right.right.left = new Node(22);
root.right.right.right = new Node(27);
/**
* In-order traversal of a binary tree.
* While processing the current node, we will check and push the value to result array
* #param {Node} node
* #param {Number} contraint value
* #param {Number[]} result array
* #return {Void}
* */
function inorder(node, val, result) {
if (node == null) return;
/**
* We don't have to check the left subtree of the current node if the value
* of the current node is < than target boundary value. Only check left
* subtree if its value is >= target boundary value.
* */
if(node.value >= val) {
inorder(node.left, val, result);
}
if (node.value > val) {
result.push(node.value);
}
inorder(node.right, val, result);
}
/**
* #param {Node} root
* #param {Number} value
* #return {Number[]} result
* */
function getValuesAfter(root, value) {
const result = new Array();
inorder(root, value, result);
return result;
}
console.log("Sorted values after 6:");
const result6 = getValuesAfter(root, 6);
console.log(result6.join(', '));
console.log("Sorted values after 11:");
const result11 = getValuesAfter(root, 11);
console.log(result11.join(', '));
console.log("Sorted values after 22:");
const result22 = getValuesAfter(root, 22);
console.log(result22.join(', '));

PLL turning on when debugging on STM32F767 Nucleo

I have been scratching my head for the past 2 days trying to figure out what is wrong with my very simple UART program on System Workbench for STM32 from STMicroelectronics. For some reason when I set:
USART3->BRR = (16000000/9600); //Sets the baud rate to 9600 with a clock of 16MHz
The output on the serial line is rubbish, however when I press the reset button on the board and let it run, I see
Hello World
As expected. Doing some digging I found out that the source for the system clock is the PLL output (RCC_CFGR register), red arrow on the imagem bellow:
RCC_CFGR
The bits correspondent to the red arrows tells me that the PLL is ON. Analyzing the RCC_PLLCFGR register and inputing the PLLM, PLLN and PLLP parameters togheter with the correspondents prescallers (AHB and APB1) into the CubeMX I arrived at a APB1 bus clock of 48MHz. So I did:
USART3->BRR = (48000000/9600); //Sets the baud rate to 9600 with a clock of 48MHz
And voilà doing step by step on the debugger I can see "HELLO WORLD" so the bus clock is 48MHz.
BUT, and I press the reset button and leave it running now the output is non-sense. Something on the debugging process is turning on the PLL and using it as the SYSCLK source.
I copied and pasted the code into Keil uVision and there was no problem, debugging and running, so the problem isn't the code itself. I took a look at the startup_stm32.s, core_cm7.h and debug files from SW4STM32 and couldn't find any hint as to why this is happening. Looking in the reference manual Reference Manual on page 170 the reset value of RCC_CFGR is 0x0000.0000 so the PLL is TURNED OFF after reset, so something in the debugging is actively setting the PLL ON.
I am using Tera Term to look at the ST-LINK serial port and Digital Discovery from Digilent to confirm what is going on the bus, and both give me even data.
Any ideas?
Full code:
#include "stm32f767xx.h"
#include "time.h"
/*
* Function declarations
*/
void uS_Delay(int Time);
void mS_Delay(int Time);
void S_Delay(int Time);
void GPIOAa_Init(void);
void Config_TIM5(void);
void TIM5_IRQHandler(void);
void Enable_TIM5Interrupt(void);
void UART_Config(void);
void UART_Send(int character);
int Delay_End = 0;
int main(void)
{
GPIOD_Init();
Config_TIM5();
Enable_TIM5Interrupt();
UART_Config();
int butao = 0;
while(1)
{
UART_Send('H');
mS_Delay(10);
UART_Send('E');
mS_Delay(10);
UART_Send('L');
mS_Delay(10);
UART_Send('L');
mS_Delay(10);
UART_Send('O');
mS_Delay(10);
UART_Send(' ');
mS_Delay(10);
UART_Send('W');
mS_Delay(10);
UART_Send('O');
mS_Delay(10);
UART_Send('R');
mS_Delay(10);
UART_Send('L');
mS_Delay(10);
UART_Send('D');
mS_Delay(10);
}
}
/*
* Functions
*/
void uS_Delay(int Time){
uint32_t Delay = (uint32_t) (unsigned long) (Time*16);
/* The APB bus cycle period is by default 62.5 nS, defined by the
* default bus frequency of 16 MHz. The number of steps to produce
* a 1 uS clock is:
*
* Nº Steps = 1uS/62.5nS
* Nº Steps = 16
*
* So for a delay of "Time" microseconds the number of steps is:
*
* Delay = Time*16
*/
TIM5->ARR = Delay;
/* TIM-ARR value will be the counter boundary to roll over.
* The default bus frequency is 16MHz.
*/
TIM5->CR1 |= 0x09;
/* TIM5->CR1 is the main basic timer controller, in this situation
* the bits 0 and 3 are been set. Those bits enables the counting
* itself and the one-shot-mode, respectively. One-shot-mode makes
* it so when an update event occurs (overflow, underflow, etc) the
* counter stops counting, in other words the bit 0 of TIM%->CR1
* is cleared.
*/
Delay_End = 0;
while(Delay_End == 0);
Delay_End = 0;
/* Delay_End is a flag telling the uS_Delay() function that the
* specified delay hasn't finished (Delay_End = 0), so keeps the
* PC register stuck on (while(Delay_End == 0)). When the counter
* rolls over it generates an interrupt. The handler (TIM5_IRQHandler)
* sets this flag and now the program can get out of the while loop
* the flag is once again cleared (Delay_End = 0) and the program
* resumes.
*/
}
void mS_Delay(int Time){
uint32_t Delay = (uint32_t) (unsigned long) (Time*16000);
/* The APB bus cycle period is by default 62.5 nS, defined by the
* default bus frequency of 16 MHz. The number of steps to produce
* a 1 mS clock is:
*
* Nº Steps = 1uS/62.5nS
* Nº Steps = 16.000
*
* So for a delay of "Time" microseconds the number of steps is:
*
* Delay = Time*16.000
*/
TIM5->ARR = Delay;
/* TIM-ARR value will be the counter boundary to roll over.
* The default bus frequency is 16MHz.
*/
TIM5->CR1 |= 0x09;
/* TIM5->CR1 is the main basic timer controller, is this situation
* the bits 0 and 3 are been set. Those bits enables the counting
* itself and the one-shot-mode, respectively. One-shot-mode makes
* it so when an update event occurs (overflow, underflow, etc) the
* counter stops counting, in other words the bit 0 of TIM%->CR1
* is cleared.
*/
Delay_End = 0;
while(Delay_End == 0);
Delay_End = 0;
/* Delay_End is a flag telling the uS_Delay() function that the
* specified delay hasn't finished (Delay_End = 0), so keeps the
* PC register stuck on (while(Delay_End == 0)). When the counter
* rolls over it generates an interrupt. The handler (TIM5_IRQHandler)
* sets this flag and now the program can get out of the while loop
* the flag is once again cleared (Delay_End = 0) and the program
* resumes.
*/
}
void S_Delay(int Time){
uint32_t Delay = (uint32_t) (unsigned long) (Time*16000000);
/* The APB bus cycle period is by default 62.5 nS, defined by the
* default bus frequency of 16 MHz. The number of steps to produce
* a 1 S clock is:
*
* Nº Steps = 1S/62.5nS
* Nº Steps = 16.000.000
*
* So for a delay of "Time" seconds the number of steps is:
*
* Delay = Time*16.000.000
*/
TIM5->ARR = Delay;
/* TIM-ARR value will be the counter boundary to roll over.
* The default bus frequency is 16MHz.
*/
TIM5->CR1 |= 0x09;
/* TIM5->CR1 is the main basic timer controller, is this situation
* the bits 0 and 3 are been set. Those bits enables the counting
* itself and the one-shot-mode, respectively. One-shot-mode makes
* it so when an update event occurs (overflow, underflow, etc) the
* counter stops counting, in other words the bit 0 of TIM%->CR1
* is cleared.
*/
Delay_End = 0;
while(Delay_End == 0);
Delay_End = 0;
/* Delay_End is a flag telling the uS_Delay() function that the
* specified delay hasn't finished (Delay_End = 0), so keeps the
* PC register stuck on (while(Delay_End == 0)). When the counter
* rolls over it generates an interrupt. The handler (TIM5_IRQHandler)
* sets this flag and now the program can get out of the while loop
* the flag is once again cleared (Delay_End = 0) and the program
* resumes.
*/
}
void GPIOD_Init(void){
int a;
RCC->AHB1ENR |= 0x08; //Enables clock for port D
a = RCC->AHB1ENR; //Small delay
GPIOD->MODER |= 0x00020000;
/*
* Sets output mode for alternate mode for pin PD8
*/
GPIOD->AFR[1] |= 0x00000007;
/*
* Alternate function 7 selected for pin PD8
*/
}
void Config_TIM5(void){
int a;
RCC->APB1ENR |= 0x08; //Enables clock for TIM5
a = RCC->APB1ENR; //Small delay
TIM5->DIER |= 0X01; //Enables update interrupt
}
void TIM5_IRQHandler(void){
Delay_End = 1; //The specified delay time has ended
TIM5->SR &= ~(0x01); //Clears the update event flag
}
void Enable_TIM5Interrupt(void){
NVIC->ISER[1] = 0x40000; //Enables interrupt event from TIM5 peripheral
NVIC->IP[50] = 0x00; //Sets the priority for the TIM5 interrupt
}
void UART_Config(void){
int a;
RCC->APB1ENR |= 0x00040000; //Enable clock for UART4
a = RCC->APB1ENR; //Small delay
USART3->CR1 |= 0x08; //Enable the transmitter
USART3->BRR = (48000000/9600); //Sets the baud rate to 9600
USART3->CR1 |= 0x01; //Enable the USART4
}
void UART_Send(int character){
USART3->TDR = (character);
}
Edit1: I got confused with RCC_CR and RCC_CFGR but the problem is the same.
Edit2: I noticed that the prescalers for APB1 and APB2 buses were also changed.
Edit3: Workaround when you start the debugging session press the icon(Reset the chip and restart debug session), this button will restart the debug session with a reset. This way the contents of the registers are as expected. I am still on the look for a mre permanent solution.

will x86 cpu perform an early end of multiplication when detects a zero-operand? [duplicate]

This question already has answers here:
Do modern cpus skip multiplications by zero?
(2 answers)
Closed 5 years ago.
================Update=======================
Seems duplicate of Do modern cpus skip multiplications by zero?
But please allow me to reserve this post, because I didn't search out that post before my publish. And allow me to post my test result in the answer area.
==================Original Post=================
Take this function as example:
int mul(int a, int b, int c, int d){
return a*b*c*d;
}
When cpu enters this function call:
int result = mul(0, 1, 2, 3);
(assume we don't allow the compiler do any optimization and the machine code appears exactly as the program order.)
I know nowadays x86 CPU has out-of-order execution, will it perform an early end of multiplication when he found he got a zero-operand?
Thanks!
No, a modern x86-64 CPU will not stop multiplying numbers just because one of them is zero. Out of order execution isn't going to prevent any of the instructions from running, it just might allow some to be executed well, out of order.
This is easy to verify using the code you wrote. Let's call it multiply.c:
int mul(int a, int b, int c, int d){
return a * b * c * d;
}
int main() {
for (int i = 0; i < 1e8; i++) {
int result = mul(0, 1, 2, 3);
}
}
Firstly verify that the code doesn't run any slower when the '0' is replaced with a '1':
gcc multiply.c -O0
time ./a.out
real 0m0.387s
user 0m0.378s
sys 0m0.002s
Re-running after changing the 0 to a 1 resulting in a real time of 0.384s, no statistical difference.
Next take a look at what assembly is being generated by gcc:
gcc -g -c -O0 multiply.c
otool -tvVX multiply.o
...
_mul:
pushq %rbp
movq %rsp, %rbp
movl %edi, -0x4(%rbp)
movl %esi, -0x8(%rbp)
movl %edx, -0xc(%rbp)
movl %ecx, -0x10(%rbp)
movl -0x4(%rbp), %ecx
imull -0x8(%rbp), %ecx
imull -0xc(%rbp), %ecx
imull -0x10(%rbp), %ecx
movl %ecx, %eax
popq %rbp
retq
nopw %cs:_mul(%rax,%rax)
You can see the three separate multiplies, so they aren't being compiled away or anything of that nature.
#Douglas B. Staple
Thanks for you benchmark. I also did a similar test.
#include<stdio.h>
#include"../base/benchmark.h"
#define MAX (100 * 10000)
int product0;
int product1;
int zero = 0;
int one = 1;
int main(void){
TSTAMP_INIT();
long time0, time2;
TSTAMP();
for(int i = 0; i < MAX; i++){
product0 *= zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero * zero ;
}
TSTAMP(&time0);
for(int i = 0; i < MAX; i++){
product1 = one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one * one ;
}
TSTAMP(&time2);
printf("%ld %ld\n", time0, time2);
return 0;
}
Compile and Run:
$ gcc -o t t.c ../base/benchmark.c -O0
$ ./t
84828 74827
The time unit is us.
I have checked the assemble code, it's not optimized.
The reason I use a long multiplication expression inside the loop is that, I want to reduce the time cost proportion occupied by loop instruction.
It seems that the first loop body cost a little more time(84838us), i think it's because of the warm-up phase of CPU cache. I have reverse location of two loop bodies and get a similar result: still the former cost a little more time.
So I can get a same conclusion as you, and as other friends stated, multiplication on x86 is time-fixed.

Generate random number bounded between two numbers in Java Card

How to generate random number bounded between two number in Java Card? For example number should be generated between 0 and 50.
Note that I have only tested the distribution of the random numbers using SecureRandom within Java SE. I'm reasonably sure that this code is correct though. The code uses the "simple reject" method defined by NIST.
So without further ado, the code.
package nl.owlstead.jcsecurerandom;
import javacard.framework.JCSystem;
import javacard.framework.Util;
import javacard.security.RandomData;
/**
* Generates numbers within a range. This class uses modulo arithmetic to
* minimize the number of calls to the random number generator without expensive
* calculations. The class is similar in operation to the
* {#code SecureRandom.nextInt(int)} method defined in Java SE.
*
* #author owlstead
*/
public final class JCSecureRandom {
private static final short SHORT_SIZE_BYTES = 2;
private static final short START = 0;
private final RandomData rnd;
private final byte[] buf;
/**
* Constructor which uses the given source of random bytes. A two byte
* buffer transient buffer is generated that is cleared on deselect.
*
* #param rnd
* the source of random bytes
*/
public JCSecureRandom(final RandomData rnd) {
this.rnd = rnd;
this.buf = JCSystem.makeTransientByteArray(SHORT_SIZE_BYTES,
JCSystem.CLEAR_ON_DESELECT);
}
/**
* Generates a single short with a random value in the range of 0
* (inclusive) to the given parameter n (exclusive).
*
* #param n
* the upper bound of the random value, must be positive
* (exclusive)
* #return the random value in the range [0..n-1]
*/
public short nextShort(final short n) {
final short sn = (short) (n - 1);
short bits, val;
do {
bits = next15();
val = (short) (bits % n);
} while ((short) (bits - val + sn) < 0);
return val;
}
/**
* Generates a single byte with a random value in the range of 0 (inclusive)
* to the given parameter n (exclusive).
*
* #param n
* the upper bound of the random value, must be positive
* (exclusive)
* #return the random value in the range [0..n-1]
*/
public byte nextByte(final byte n) {
if ((n & -n) == n) {
return (byte) ((n * next7()) >> 7);
}
final byte sn = (byte) (n - 1);
byte bits, val;
do {
bits = next7();
val = (byte) (bits % n);
} while ((byte) (bits - val + sn) < 0);
return val;
}
/**
* Generates 15 bits from two bytes by setting the highest bit to zero.
*
* #return the positive valued short containing 15 bits of random
*/
private short next15() {
this.rnd.generateData(this.buf, START, SHORT_SIZE_BYTES);
return (short) (Util.getShort(this.buf, START) & 0x7FFF);
}
/**
* Generates 7 bits from one byte by setting the highest bit to zero.
*
* #return the positive valued byte containing 7 bits of random
*/
private byte next7() {
this.rnd.generateData(this.buf, START, SHORT_SIZE_BYTES);
return (byte) (this.buf[START] & 0x7F);
}
}
In Java Card, you only have access to the javacard.security.RandomData, which is only able to generate random bytes.
You first need a variable of the right type:
private RandomData rng;
private byte[] rndBuffer;
Then, you need the following code in your constructor/install (to avoid allocating a random generator and buffer every time):
rng = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
rndBuffer = JCSystem.getTransientByteArray(JCSystem.CLEAR_ON_DESELECT, 1);
And then, you can define your method to get a random byte in a range:
byte getRandomByteInRange(byte min, byte max) {
do {
rng.generateData(rndBuffer,0,1);
while ((rndBuffer[0]<min) || (rndBuffer[0]>max))
return rndBuffer[0];
}
There is most likely a less stupid way to write this method (especially for small ranges), but it should work.
There are examples here. Taking the example 2 from that link:
import java.util.Random;
/** Generate random integers in a certain range. */
public final class RandomRange {
public static final void main(String... aArgs){
log("Generating random integers in the range 1..10.");
int START = 1;
int END = 10;
Random random = new Random();
for (int idx = 1; idx <= 10; ++idx){
showRandomInteger(START, END, random);
}
log("Done.");
}
private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
if ( aStart > aEnd ) {
throw new IllegalArgumentException("Start cannot exceed End.");
}
//get the range, casting to long to avoid overflow problems
long range = (long)aEnd - (long)aStart + 1;
// compute a fraction of the range, 0 <= frac < range
long fraction = (long)(range * aRandom.nextDouble());
int randomNumber = (int)(fraction + aStart);
log("Generated : " + randomNumber);
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
use RandomData abstract class:
http://www.win.tue.nl/pinpasjc/docs/apis/jc222/javacard/security/RandomData.html
Edit:
here is an exaple of this class in use,
byte[] keyBytes = JCSystem.getTransientByteArray(COD,16);
RandomData rng = RandomData.getInstance(ALG_SECURE_RANDOM);
rng.generateData(keyBytes,0,16);
If you are simply looking for random number instead of randomData you can use this:
/*
* generate a random number between 0 and 50
*/
Random random1 = new Random();
int card = (random1.nextInt(51));

Why "offset+length<0" in jdk to make sure if the arguments if illegal?

In jdk,there are many places to check the arguments abut array.eg.
/*..........
*
* #throws IllegalArgumentException
* If <tt>offset</tt> is negative or greater than
* <tt>buf.length</tt>, or if <tt>length</tt> is negative, or if
* the sum of these two values is negative.
*
* #param buf Input buffer (not copied)
* #param offset Offset of the first char to read
* #param length Number of chars to read
*/
public CharArrayReader(char buf[], int offset, int length) {
if ((offset < 0) || (offset > buf.length) || (length < 0) ||
//$ offset+length
(**(offset + length) < 0)**) {
throw new IllegalArgumentException();
}
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.markedPos = offset;
}
why " (offset + length) <0 "is necessary?
In Java int is signed so it can happen that two positive ints when added together result in a negative value. It's called wrap-around or Integer Overflow
I believe it is checking for overflow.
Range of int is -2,147,483,648 to 2,147,483,647.
From the code you can see, there are places we need offset + length. If offset + length is larger than 2,147,483,647 it is going to give problem, and (offset + length) < 0) is checking for such case.

Resources