RomixNL 0 Posted June 3, 2012 Share Posted June 3, 2012 How do I create random numbers in Energia? A call to random(5) produces: Arnold.cpp.o: In function `setup': Arnold.cpp:190: undefined reference to `random(long)' collect2: ld returned 1 exit status The random functions are disabled in WMath.cpp #if 0 #if 0 void randomSeed(unsigned int seed) { if (seed != 0) { srandom(seed); } } long random(long howbig) { if (howbig == 0) { return 0; } return random() % howbig; } long random(long howsmall, long howbig) { if (howsmall >= howbig) { return howsmall; } long diff = howbig - howsmall; return random(diff) + howsmall; } #endif uncommenting/enabling does not solve the problem. Any help greatly appreciated. I desperately need random numbers in a sketch. Quote Link to post Share on other sites
Sir Ferdek 8 Posted June 3, 2012 Share Posted June 3, 2012 http://www.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=slaa338&docCategoryId=1&familyId=914 [tipdf]slaa338[/tipdf] I have it rewritten in plain C, so let me know if you want it. This method of generating random numbers satisfy requirements for noncritical systems. I have done some accurate tests on 1M samples of bits and compared it to other methods as my project for course assesment and results are quite satisfactory: - 50.19% of zeroes, 49.81% of ones - FFT is smooth and even without serious frequency peaks - runstest() in MATLAB returns 0.3 (1 means that series of data is random with 95% probability, for comparison MATLAB's pseudorandom generator scores less than 0.03) - passes birth paradox test PS: Where do I have to look for Energia's source code if I'd like to contribute some lines of mine? RomixNL 1 Quote Link to post Share on other sites
energia 485 Posted June 3, 2012 Share Posted June 3, 2012 randomSeed() and random() not are not yet implemented (see issue 63 on github https://github.com/energia/Energia/issues/63). Sir Ferdek, I would love to have a look at your random number code. Would you consider contributing it to Energia? Quote Link to post Share on other sites
bluehash 1,581 Posted June 3, 2012 Share Posted June 3, 2012 Where do I have to look for Energia's source code if I'd like to contribute some lines of mine? http://energia.github.com/Energia/ Quote Link to post Share on other sites
energia 485 Posted June 3, 2012 Share Posted June 3, 2012 PS: Where do I have to look for Energia's source code if I'd like to contribute some lines of mine? Energia project is here: https://github.com/energia/Energia The contribution procedure needs to be formalized but in a nut shell. If you just want to submit a patch or 2 then send us the patch and we will take care of it. Users that want to actively participate in Energia are added as members and you get full access. New code/bug fix follow this process https://github.com/energia/Energia/wiki ... ew-process. Quote Link to post Share on other sites
Sir Ferdek 8 Posted June 3, 2012 Share Posted June 3, 2012 Sir Ferdek, I would love to have a look at your random number code. Would you consider contributing it to Energia? Yes, of course. I just need to find some time to refactor and comment it (you know, exam session is coming ). What's more, there are some drawbacks which should be mentioned before implementing. First of all, it modifies DCO (modulation, RSELx) to add some randomness. Secondly, generating one number, then returning to original frequency, then generating number again makes runstest() think they are less random (no idea why, but it made HUGE difference).The solution to that problem was to batch generate whole table of random numbers and read them one after another when needed. Unfortunately, this creates huge security flaw as they are held in memory, so one can peek and "guess" what the next number is going to be. Thirtly, this method was tested by me only at 1MHz DCO speed. No idea what will happen at higher frequencies (notice how dramatically it changes DCO/VLO ratio on which this generator is based). Anyway, there is still some hope. According to the [tipdf]slaa338[/tipdf] we can use this method only to generate random seed for stream cipher mentioned there (http://eprint.iacr.org/2006/019.pdf). It could be done directly after PUC/POR, changing clocks wouldn't make difference. Or invoke hardware generator just from time to time in order to reinitialize cipher with new seed. Endless posibilities. Oh, and for your curiosity - generating 1M of random bits @1MHz and transfering them via UART @9600N1 took ~45 minutes . So IMHO it's not the way to go bluehash 1 Quote Link to post Share on other sites
Sir Ferdek 8 Posted June 8, 2012 Share Posted June 8, 2012 OK, no matter what, tommorow you'll have your piece of code Quote Link to post Share on other sites
energia 485 Posted June 9, 2012 Share Posted June 9, 2012 Hi Sir Fredrik. No rush. I did a quick fix and used the random from libc. This is not msp430-libc but the random.c imported from the original libc. This is the same random and srandom that AVR uses. I would still love to have a more sophisticated random number generator. Your implementation could be a good complementary random number generator in the form of a library.. Quote Link to post Share on other sites
Sir Ferdek 8 Posted June 9, 2012 Share Posted June 9, 2012 //****************************************** //Description: Random number generation using MSP's internal clocks //based on TI's slaa338 //****************************************** //ACLK - set to LFXT1 = VLO BCSCTL3 |= LFXT1S_2; //clear OSCFault flag //wait for clock fault system to react do{ IFG1 &= ~OFIFG; // Clear OSCFault flag } while(BCSCTL3 & LFXT1OF); //DCO default @1MHz, //MCLK - default DCO/1 //SMCLK - default DCO/1 //prepare timer TACCTL0 |= CM_1 + CCIS_1 + CAP; TACTL |= TASSEL_2 + MC_2; //workaround for DCO freeze problem void setRSELx(unsigned char target){ unsigned char current = BCSCTL1 & 0x0F; if((target > 0x0D && current < 0x0C) || (current > 0x0D && target < 0x0C)){ BCSCTL1 = (BCSCTL1 & 0xF0) | 0x0D; } BCSCTL1 = (BCSCTL1 & 0xF0) | (target & 0x0F); } unsigned getRandomCLK(void){ register unsigned i,j; register unsigned maj=0; //majority vote holder register char ACLK_div=0; //ACLK divider randomness register unsigned rnd=0; //return value unsigned bcs_tmp=0; for(i=0;i<16;++i){ maj = 0; for(j=0;j<5;++j){ //wait for capture while(!(TACCTL0 & CCIFG)); //capture occured, clear flag TACCTL0 &= ~CCIFG; if(TACCR0 & 0x01){ maj++; } } rnd <<= 1; //make space for new bit if(maj > 0x02){ //see if there are two or more 1's rnd |= 0x0001; //if so, set new bit } else { rnd &= ~(0x0001); //if not, clear new bit } ACLK_div = rnd<<4; ACLK_div &= 0x30; BCSCTL1 ^= ACLK_div; //now xor DCO modulation bits (see 'slau144i', 5.3.1) DCOCTL ^= 0x1F; //add to RSEL bits to change DCO speed //NOTE: see errata page 3 for DCO freeze problem description bcs_tmp = ((BCSCTL1 + 0x05) & 0x0F); setRSELx(bcs_tmp); } return rnd; //capture timer is left running } Optimizations are welcome. bluehash 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.