![]() |
Forum Index : Microcontroller and PC projects : Pushing the limits of MMBasic
![]() ![]() |
|||||
Author | Message | ||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
The device has an MPU, memory protection unit, which allows FW to set up memory regions with different attributes (instructions access, cacheability, .etc.) For instance, if OPTION RAM is set, instruction access for that RAM region is enabled: if(Option.RunInRam==0xD0300000){ /* Configure the MPU attributes for SDRAM */ MPU_InitStruct7.Enable = MPU_REGION_ENABLE; MPU_InitStruct7.BaseAddress = 0xD0300000; MPU_InitStruct7.Size = MPU_REGION_SIZE_512KB; MPU_InitStruct7.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct7.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct7.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct7.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct7.Number = MPU_REGION_NUMBER7; MPU_InitStruct7.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct7.SubRegionDisable = 0x00; MPU_InitStruct7.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct7); } The other regions have instruction access disabled. E.g.: /* Configure the MPU attributes for Variable memory*/ MPU_InitStruct10.Enable = MPU_REGION_ENABLE; MPU_InitStruct10.BaseAddress = 0x38000000; MPU_InitStruct10.Size = MPU_REGION_SIZE_64KB; MPU_InitStruct10.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct10.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct10.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct10.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct10.Number = MPU_REGION_NUMBER10; MPU_InitStruct10.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct10.SubRegionDisable = 0x00; MPU_InitStruct10.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct10); Epsilon CMM2 projects |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
Sorry. My post crossed Peter's. Epsilon CMM2 projects |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
I think the above means: 1. the situation is that MMBasic on the CMM2 blocks SDRAM from having data execute as code but that it could be allowed if desired (or if MMBasic isn't there) 2. probably the other RAM can/could be used Which maybe lets those who contemplate this stuff know how things are and what they might have to do plus the consequences (e.g. copyright preventing distribution of the changed code in any case). I suppose one workaround for the copyright situation would be to make a CSUB which boots an OS from SD card and does whatever is desired (perhaps one option being to go back to MMBasic). "Just" a bit of work... John |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
I briefly considered options such as this one, or applying a live FW patch or somesuch, but (im)practicalities aside, that just feels like an aggressive hijacking of the platform. I don't want to go there. If it doesn't have Peter's/Geoff's blessing, it's not going to happen. Essentially, this is a feature request to extend ARMCFunctions.h, but that involves quite a bit of work. On the off chance that Peter would be OK with the feature, but couldn't be bothered to implement it, I'm volunteering to do the implementation. Epsilon CMM2 projects |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
"Pushing the limits of MMBasic" - spit-balling blue-sky ideas What would the ramifications be of allowing operators/commands/functions to work on entire arrays? I noted on the F4 firmware thread that MATH ADD isn't available. After pondering more, I observed that my use case is the same as the INC command, if it applied to arrays. For example, INC a() would be equivalent to MATH ADD a(),1,a(). This could then be extended to almost everything. For example, a() = cos(t()) would set each element of array a to the cosine of the corresponding element of array t. (Base assumption that array sizes match.) This would apply to all operations. This could get hairy with, for example, something like slen%() = LEN(name$()) but you get the idea. Even multi-dimensional arrays could be possible. Use cases? Consider a (large) set of particles animated on screen. Each particle has x and y coordinates, stored in x() and y(). Each particle has velocities, stored in vx() and vy(). For each movement step, x(i) = x(i) + vx(i), etc. Currently, we must loop i through each element. Now it gets wild, maybe too wild: IF x() < 0 OR x() > MM.HRES THEN That looks like a nightmare to parse. Conditional per element operations? Yikes!x() = MIN(MAX(x(),0),MM.HRES) vx() = -vx() ENDIF INC x(),vx() We can already throw the arrays of x and y coordinates at the PIXEL command. How about at everything else too? Visit Vegipete's *Mite Library for cool programs. |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
This is called list comprehension and it's a key aspect of functional programming, think Lisp. I first came across this in the legendary SICP book: https://mitpress.mit.edu/sites/default/files/sicp/index.html If you haven't read it, you should. It will blow your mind. This is the book that spiked my interest in programming languages. It has been said that if you evolve any programming language far enough, it turns into lisp. You can do list comprehension to some degree already using CALL: OPTION EXPLICIT OPTION DEFAULT NONE OPTION BASE 0 SUB doubleIt(x%) x% = x%*2 END SUB SUB printIt(x%) PRINT x% END SUB SUB mapf(fun$, arr%(), numElems%) LOCAL ii% FOR ii%=0 TO numElems%-1 CALL fun$, arr%(ii%) NEXT ii% END SUB DIM myArr%(3) = (11,22,33,44) PRINT "Before:" mapf("printIt", myArr%(), 4) mapf("doubleIt", myArr%(), 4) PRINT "After:" mapf("printIt", myArr%(), 4) END This program produces: Before: 11 22 33 44 After: 22 44 66 88 Anyway, I'm in favor of more of this :-) Epsilon CMM2 projects |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7937 |
(Lisp(isn't,great)+(when+counting)(parantheses)) or something.... :) I once wrote a couple of little routines in AUTOlisp in my CAD days. lol I don't know what the limits are on the CMM2 now, but Peter has often said that there is hardly any room left in the command table, and from what he's said about parsing I wouldn't count on a favourable comment about putting arrays in silly places. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
jirsoft![]() Guru ![]() Joined: 18/09/2020 Location: Czech RepublicPosts: 533 |
I think you are forced to use Thumb-2 (or Thumb-1), because Cortex M7 has't ARM instruction set implemented ![]() Jiri Napoleon Commander and SimplEd for CMM2 (GitHub), CMM2.fun |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
Oh, OK. It looks more than adequate, though actually wanting to use assembler is vanishingly rare. John |
||||
capsikin Guru ![]() Joined: 30/06/2020 Location: AustraliaPosts: 341 |
Looks like a byte order / word order issue. With the disassembler in big endian mode, and taking the 4-hex-digit words from the first listing instead of the 8-hex-digit numbers from the second listing, I disassembled the instructions. here Edited to add: After considering this, it seems the online disassembler is taking two hex digits at a time for the machine code, and treating this as the next byte, rather than properly handling 4-digit and bigger numbers in the machine code. My workaround happened to work, but only when giving the disassembler 4-digit numbers - that's why I couldn't use the 8-digit numbers from the CSUB block. A more reliable solution to this would be to convert the numbers (both 8-digit from the CSUB block, or 4-digit from the other listing) into bytes in little endian order (low byte first), then run the disassembler on the bytes in little endian mode. I've done this here Similarly, the output of the assembler here is best converted into a CSUB block by taking the little-endian output then converting it into 32 bit (8 hex digit) words (knowing the bytes are in little-endian order, so the digits from the last of the four bytes are written as the left two digits of the word, etc). It might be handy to have a program for the CMM2 to convert sequences of hex numbers (which could be a mix of 2-digit (bytes), 4-digit, or 8-digit) to either 8-digit numbers for embedding in programs, or bytes for giving to an online disassembler, all assuming little endian byte order which I believe is correct for thee system. It's right, that from my point of view is Thumb/2 crippled ARM, I have programmed on ARM250 and it was very nice... And superscalar pipeline are good exactly for this thing: you are writing normally and CPU is much faster... Edited 2021-06-27 11:31 by capsikin |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |