| @ -1,29 +1,29 @@ | |||||
| #include <stdbool.h> | #include <stdbool.h> | ||||
| #include "hal.h" | #include "hal.h" | ||||
| typedef struct { | |||||
| volatile uint32_t state; | |||||
| } My_Mem; | |||||
| // typedef struct { | |||||
| // volatile uint32_t state; | |||||
| // } My_Mem; | |||||
| #define MY_MEM ((My_Mem*)(0xF0030000)) | |||||
| // #define MY_MEM ((My_Mem*)(0xF0030000)) | |||||
| int main(void) | int main(void) | ||||
| { | { | ||||
| printf("HELLO WORLD\n"); | printf("HELLO WORLD\n"); | ||||
| uint32_t state = 10000; | uint32_t state = 10000; | ||||
| uint32_t state_return; | |||||
| // uint32_t state_return; | |||||
| while (1) | while (1) | ||||
| { | { | ||||
| printf("State in : %i\n", state); | printf("State in : %i\n", state); | ||||
| MY_MEM->state = state; | |||||
| state_return = MY_MEM->state; | |||||
| // MY_MEM->state = state; | |||||
| // state_return = MY_MEM->state; | |||||
| state = state + 1; | state = state + 1; | ||||
| printf("State out: %i\n", state_return); | |||||
| printf("State out: %i\n", state); | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @ -1,446 +0,0 @@ | |||||
| :0200000480007A | |||||
| :10000000130000001300000013000000971104000B | |||||
| :100010009381C1C1170106001301C1FE171500002D | |||||
| :1000200013054574970504009385C5FD1706040064 | |||||
| :100030001306C63F63FCC5008322050023A05500BC | |||||
| :100040001305450093854500E3E8C5FE1705040048 | |||||
| :100050001305C53D970504009385453D6378B500BC | |||||
| :100060002320050013054500E36CB5FE9700000052 | |||||
| :10007000130101FF23241100371500001305058823 | |||||
| :100080007310453037250000130585807310053047 | |||||
| :100090001305000093050000EF00C0126F104035FB | |||||
| :1000A0006F000000130000001300000013000000A8 | |||||
| :1000B000130101F8232211002324210023263100FB | |||||
| :1000C00023284100232A5100232C6100232E710094 | |||||
| :1000D00023208102232291022324A1022326B1029C | |||||
| :1000E0002328C102232AD102232CE102232EF1026C | |||||
| :1000F0002320010523221105232421052326310570 | |||||
| :1001000023284105232A5105232C6105232E71053F | |||||
| :1001100023208107232291072324A1072326B10747 | |||||
| :100120002328C107232AD107232CE107232EF10717 | |||||
| :10013000EF00800883204100032181008321C1005A | |||||
| :100140000322010183224101032381018323C10191 | |||||
| :100150000324010283244102032581028325C10275 | |||||
| :100160000326010383264103032781038327C10359 | |||||
| :100170000328010483284104032981048329C1043D | |||||
| :10018000032A0105832A4105032B8105832BC10521 | |||||
| :10019000032C0106832C4106032D8106832DC10605 | |||||
| :1001A000032E0107832E4107032F8107832FC107E9 | |||||
| :1001B00013010108730020306F00000000000000F0 | |||||
| :0401C000000000003B | |||||
| :1001C400130101FE232C8100171500001305C555EA | |||||
| :1001D40037240000232A91002328210123263101FA | |||||
| :1001E400232E110013040471EF00107D97190000F1 | |||||
| :1001F40093898954B70403F0171900001309C954EB | |||||
| :100204009305040013850900EF00107B23A08400EC | |||||
| :1002140083A504001305090013041400EF00D0792A | |||||
| :100224006FF01FFE97070080938787DD99C7171526 | |||||
| :1002340000001305052A6F10202D82806376D600F6 | |||||
| :10024400B385C5002380A500678000006780000097 | |||||
| :10025400130101FD0323810323202103232E3101F4 | |||||
| :10026400232C4101232A51012328610123267101F2 | |||||
| :1002740023248101232611022324810223229102B3 | |||||
| :10028400232291012320A101137C2300138B060058 | |||||
| :10029400130A0500938A0500930906001309070051 | |||||
| :1002A40083260103832B410363140C061375130087 | |||||
| :1002B400639A0B1C63F6D7021307F0016364F732E9 | |||||
| :1002C40013060003930500026F008000638AB700E1 | |||||
| :1002D400938717003307F900A30FC7FEE3E8D7FE9F | |||||
| :1002E4006308050263F6770313070002638EE71AB7 | |||||
| :1002F40013060003930500026F0080006386B71A9B | |||||
| :10030400938717003307F900A30FC7FEE39877FF1D | |||||
| :100314001377030163020708137703406314071A72 | |||||
| :10032400639E0718130700016382E82A93072000DD | |||||
| :10033400638EF826930700032300F9009307100047 | |||||
| :100344006304081A3307F900138417009307D002D3 | |||||
| :100354002300F7001373330063140300636A740FFC | |||||
| :10036400938C09006F00C00413070002638AE7023C | |||||
| :10037400B306F90093871700130780072380E6006C | |||||
| :1003840013070002638EE7003307F90093060003A6 | |||||
| :100394002300D7009387170013070002E392E7FABC | |||||
| :1003A400137333006302030A938C090013040002DD | |||||
| :1003B400B38C8C00330D9901330489000345F4FF99 | |||||
| :1003C40033068D4093060B001304F4FF93850A0053 | |||||
| :1003D40093840C00E7000A00E31289FE63080C0210 | |||||
| :1003E400B389344163F479031386040093060B0044 | |||||
| :1003F40093850A001305000293841400E7000A00A1 | |||||
| :100404009389190013860400E3E279FF8320C10273 | |||||
| :100414000324810213850400032901028324410279 | |||||
| :100424008329C101032A8101832A4101032B01018C | |||||
| :10043400832BC100032C8100832C4100032D010078 | |||||
| :10044400130101036780000013040002637C740B32 | |||||
| :10045400B38C7901B38C8C401386090093060B008E | |||||
| :1004640093850A001305000293041600E7000A00AE | |||||
| :1004740013860400E39494FF93840C00E31A04F2BB | |||||
| :100484006FF0DFF5630E05086316080A1377C300DF | |||||
| :100494006312070AE3F8D7E41307F001E372F7E203 | |||||
| :1004A40093070002E3F677E793770301E38A07EE05 | |||||
| :1004B400937703406390070E930700026380F60866 | |||||
| :1004C400638E770713070001638AE8081307200087 | |||||
| :1004D400E398E8EA13070002E384E7EC3307F90042 | |||||
| :1004E400938717006F00C00D137743006310070252 | |||||
| :1004F400137783006316070813733300138407000C | |||||
| :10050400E30603F4938C09006FF01FF73307F90037 | |||||
| :10051400138417009307B0022300F7006FF09FE3E2 | |||||
| :10052400E3F8D7DE1307F001E37CF7D89307000262 | |||||
| :100534006FF01FDE938BFBFF6FF0DFF51387F7FF80 | |||||
| :10054400630E0704930600016380D80C9306200011 | |||||
| :100554006386D806930707006FF01FE3137703023F | |||||
| :10056400E30407E013070002E38CE7E23307F90032 | |||||
| :10057400930680052300D700938717006FF05FE090 | |||||
| :100584003307F90013841700930700022300F700D0 | |||||
| :100594006FF05FDC930700026FF0DFF29307000156 | |||||
| :1005A4006388F80493072000E396F8FA930720067B | |||||
| :1005B4002300F900930710006FF01FDD3307E900F3 | |||||
| :1005C400930620062300D7006FF09FDB1377030206 | |||||
| :1005D400E31E07F8930780072300F9009307100030 | |||||
| :1005E4006FF09FDA93070002E31E05CE6FF05FD22F | |||||
| :1005F40093770302E38007FE930780052300F90045 | |||||
| :10060400930710006FF05FD8937603029387E7FF98 | |||||
| :10061400E39E06F4B306F900930707006FF0DFD5F5 | |||||
| :10062400130101FB232E3103232611042324810407 | |||||
| :10063400232291042320210583294105631A0704F9 | |||||
| :1006440013F309409300010193F9F9FE63020304D3 | |||||
| :1006540003230105232431012320110123226100F6 | |||||
| :100664009308080013880700930707001387000006 | |||||
| :10067400EFF01FBE8320C1040324810483244104BA | |||||
| :10068400032901048329C1031301010567800000C4 | |||||
| :1006940013FE090213031006631C0E081379F30FEB | |||||
| :1006A400930F07001353F701930001011307000090 | |||||
| :1006B400930310009302F0FF13049000130969FFE1 | |||||
| :1006C40093040002130F0000130EE001B3DECF41C8 | |||||
| :1006D40093FE1E001313130033E36E00B39EC30195 | |||||
| :1006E400130EFEFF6346030133030341336FDF013F | |||||
| :1006F400E31E5EFC1373F30F6366640213030303C8 | |||||
| :100704001373F30F13071700338EE000A30F6EFE6D | |||||
| :10071400E3000FF4E30E97F213030000930F0F00AE | |||||
| :100724006FF05FFA330323011373F30F6FF09FFD30 | |||||
| :10073400130310046FF09FF6130101F7232C8106B5 | |||||
| :1007440023206107232E71052328A1052326B10543 | |||||
| :10075400232E1106232A9106232821072326310755 | |||||
| :100764002324410723225107232C8105232A9105A1 | |||||
| :10077400232611093363F700232CA100232EB10093 | |||||
| :10078400130B0600938B0600130D08001384080056 | |||||
| :10079400832E0109832DC1096316030893F60D40C6 | |||||
| :1007A40093FDFDFE6380060893090000130A01020D | |||||
| :1007B400832781098325C101032581012322F100B7 | |||||
| :1007C400832741092324B101930804002320F10065 | |||||
| :1007D40013080D009387090013070A0093860B0082 | |||||
| :1007E40013060B00EFF0DFA68320C1070324810763 | |||||
| :1007F40083244107032901078329C106032A8106AB | |||||
| :10080400832A4106032B0106832BC105032C810592 | |||||
| :10081400832C4105032D0105832DC1041301010916 | |||||
| :100824006780000013F60D0293061006631E060E81 | |||||
| :100834009384070093D5F40193070700130E000077 | |||||
| :1008440093090000130A01029300F0011309100038 | |||||
| :100854009308F0FF930A9000938C66FF130C000238 | |||||
| :100864001307E003130F000013030000939F140009 | |||||
| :100874003386E04093D2F50193161E0033D5E7008A | |||||
| :100884003396CF00130807FEB3E6D2009395150004 | |||||
| :100894003365A6006344080033D50441137515007D | |||||
| :1008A400B365B500138E060063C8D6033316E9009A | |||||
| :1008B40033858540B3B2A500B383D6411358F641BE | |||||
| :1008C4006394DE0063EA850093050500338E53408C | |||||
| :1008D400336FCF00336303011307F7FFE31A17F9EC | |||||
| :1008E40093F5F50F63ECBA029385050393F7F50FBF | |||||
| :1008F4009389190033073A01A30FF7FEB3676F001A | |||||
| :10090400E38807EAE38689EB9355F301130E0000AD | |||||
| :1009140093070F00930403006FF09FF4B3859501D0 | |||||
| :1009240093F7F50F6FF0DFFC930610046FF05FF0A0 | |||||
| :10093400130101FA23282105232631052324410527 | |||||
| :10094400232C81032326B103232E1104232C810499 | |||||
| :10095400232A91042322510523206105232E7103A8 | |||||
| :10096400232A91032328A103938905001309060070 | |||||
| :10097400138C0600930D0700170A0000130A4A8D12 | |||||
| :1009840063840500130A050003450C00130D0000E1 | |||||
| :1009940063040516B70701009387F7FF930400016A | |||||
| :1009A400971C0000938C0CBF130B9000232AF100BA | |||||
| :1009B4006F00000213060D009306090093850900D9 | |||||
| :1009C400130D1D00E7000A0003450C006306051221 | |||||
| :1009D40093075002130C1C00E31EF5FC03450C00A6 | |||||
| :1009E40013071C0093060000930705FE93F7F70F07 | |||||
| :1009F4001306070063ECF40293972700B38797016B | |||||
| :100A040083A70700B38797016780070093E6160062 | |||||
| :100A1400130C070003450C0013071C001306070002 | |||||
| :100A2400930705FE93F7F70FE3F8F4FC930705FD2E | |||||
| :100A340093F7F70F6370FB129307A0026308F51C8A | |||||
| :100A44009307E00213060C00930B0000130C07003D | |||||
| :100A5400930F00006304F5149307A0066306F516CC | |||||
| :100A640063FEA7069307C006630AF53C9307A00735 | |||||
| :100A74006318F5000345160093E60610130C1C00DA | |||||
| :100A84009307B5FD93F7F70F13073005E364F7F207 | |||||
| :100A940017170000130747B493972700B387E7009D | |||||
| :100AA40083A70700B387E7006780070093E6260063 | |||||
| :100AB400130C07006FF01FF693E64600130C0700B3 | |||||
| :100AC4006FF05FF593E60601130C07006FF09FF4D7 | |||||
| :100AD40093E68600130C07006FF0DFF3930780069C | |||||
| :100AE400E310F5FA03451600630EF53893E606089D | |||||
| :100AF400130C1C006FF0DFF813060D0063642D0166 | |||||
| :100B04001306F9FF930609009385090013050000F5 | |||||
| :100B1400E7000A008320C1050324810513050D00A5 | |||||
| :100B240083244105032901058329C104032A81047F | |||||
| :100B3400832A4104032B0104832BC103032C810367 | |||||
| :100B4400832C4103032D0103832DC10213010106EC | |||||
| :100B540067800000930B00006F00C000130C0700B7 | |||||
| :100B64001307170013942B00330474011314140097 | |||||
| :100B74003304A4000345070013060700930B04FD88 | |||||
| :100B8400930705FD93F7F70FE37AFBFC130C2C0096 | |||||
| :100B94009307E002930F0000E310F5EC0345160001 | |||||
| :100BA40093E60640930705FD93F7F70F6378FB027E | |||||
| :100BB4009307A0026300F52A9307A00613060C000E | |||||
| :100BC400130C1C00E31EF5E893E60620034516000B | |||||
| :100BD400130C1C006FF0DFEA130C0600939A2F002D | |||||
| :100BE400B38AFA01939A1A00B38AAA0003451C0037 | |||||
| :100BF40013061C00938F0AFD930705FD93F7F70F67 | |||||
| :100C0400E37CFBFC130C2C006FF01FE583AB0D00A1 | |||||
| :100C1400938D4D0063CC0B2003451C00130C2C005A | |||||
| :100C24006FF01FF703A40D0093874D00232CF100F0 | |||||
| :100C34000345040063920F24930DE0FF630A0552F9 | |||||
| :100C440093871D002328F1003306F4009307040062 | |||||
| :100C54006F008000638CC7009387170003C70700E9 | |||||
| :100C6400E31A07FEB38787402328F10093FA06406E | |||||
| :100C740063880A008327010163F4FF002328F1013C | |||||
| :100C840093F72600232EF100638407366308052CAE | |||||
| :100C9400638C0A28B38AAF0113060D006386CA0267 | |||||
| :100CA4009306090093850900930D1600E7000A00D6 | |||||
| :100CB400B387AD41B307F40003C50700630C052CEB | |||||
| :100CC40013860D00E39ECAFC8327C101138D0A001D | |||||
| :100CD40063960728832D81016FF01FCF03A70D00B2 | |||||
| :100CE40013E41602930780002320F10013060D007D | |||||
| :100CF4002322810093880F0013080001930700004A | |||||
| :100D0400930609009385090013050A00EFF05F912B | |||||
| :100D1400938D4D00130D05006FF01FCB93874D008D | |||||
| :100D2400930A1D0093F626002328F10013840A0079 | |||||
| :100D34006386062603C50D0013060D0093060900FD | |||||
| :100D440093850900E7000A0013071000338DAB01F7 | |||||
| :100D54006378773B93071400130604009306090095 | |||||
| :100D6400138407009385090013050002E7000A00B5 | |||||
| :100D7400E3128DFE832D01016FF01FC593078007D9 | |||||
| :100D84006304F53C930780056306F5109307F006AA | |||||
| :100D94006302F53293072006630AF51013079006E1 | |||||
| :100DA40013F6F6FE93F706401308A0006314E5104B | |||||
| :100DB40013F40620638A07101376E6FF9307900660 | |||||
| :100DC400137406206302F51093074006630EF50EB4 | |||||
| :100DD4006318042E9377061013844D00639A073426 | |||||
| :100DE40093770604639A07309377060803A70D00E8 | |||||
| :100DF40063860700832741013377F7002322C1006C | |||||
| :100E04002320710193880F00930700006F00C00F27 | |||||
| :100E140013060D009306090093850900130550027B | |||||
| :100E2400130D1D00E7000A006FF01FBA93E62600B9 | |||||
| :100E3400B30B704103451C006FF05FDE03451600E1 | |||||
| :100E4400E31CF5C293E6063003452600130C360076 | |||||
| :100E54006FF01FC383AF0D0003452600130C36004B | |||||
| :100E640093C7FFFF93D7F741B3FFFF00938D4D0066 | |||||
| :100E7400130626006FF05FBE630C052E938DFFFFF3 | |||||
| :100E84006FF01FDC93E6060C03452600130C3600B6 | |||||
| :100E94006FF01FBF13F636FF93F706401366060282 | |||||
| :100EA40063840720130800016FF01FF1130820006A | |||||
| :100EB400138606001307400693770640631AE52C51 | |||||
| :100EC40013740620E39A07EE631E04169377061044 | |||||
| :100ED40013844D00639C07229377060463980720CC | |||||
| :100EE40093770608638C072683970D0093D6F74102 | |||||
| :100EF40033C7F6003307D7402322C10023207101F2 | |||||
| :100F040093880F0093D7F70113060D009306090089 | |||||
| :100F14009385090013050A00EFF08FF0130D050007 | |||||
| :100F2400930D04006FF05FAA13060D0093060900E9 | |||||
| :100F340093850900930A1600E7000A00B387AA41C3 | |||||
| :100F4400B307F40003C5070013860A00E31005FE87 | |||||
| :100F5400138D0A008327C101E38E07D6832701017D | |||||
| :100F640013060D00E3F877D73384AB01330DF44057 | |||||
| :100F74009306090093850900130500021304160063 | |||||
| :100F8400E7000A0013060400E314A4FF832D810183 | |||||
| :100F94006FF09FA3138D0D006FF0DFFB130710009C | |||||
| :100FA4006372771F1304FDFF330474016F00800024 | |||||
| :100FB400938A1A0013060D0093060900938509000D | |||||
| :100FC40013050002138D0A00E7000A00E3928AFE6B | |||||
| :100FD400138D1A0003C50D009306090013060400BF | |||||
| :100FE40093850900E7000A00832D01016FF0DF9D5E | |||||
| :100FF400032701019307170063707719B387AB01C7 | |||||
| :10100400B38DE7402328F10193071D0013060D005B | |||||
| :10101400930609009385090013050002138D070048 | |||||
| :10102400E7000A00832F0101E31EBDFD0345040010 | |||||
| :1010340093871B002328F100E31C05C4832D810141 | |||||
| :101044006FF09F98938D7D0093FD8DFF03A54D0058 | |||||
| :1010540083A70D00930808009356F541B3C7F60023 | |||||
| :101064003387D740B3C5A600B3B7E700B386D540EE | |||||
| :101074002326C100232471012322F101232001002E | |||||
| :101084001358F501B387F64013060D0093060900C3 | |||||
| :101094009385090013050A00EFF00FEA938D8D0084 | |||||
| :1010A400130D05006FF05F9213F40620130800017E | |||||
| :1010B4006FF01FD213088000138606006FF09FDFC5 | |||||
| :1010C400938D7D0093FD8DFF03A70D0083A74D0035 | |||||
| :1010D400930808002326C100232471012322F1016F | |||||
| :1010E40023200100130800006FF01FFA83C70D00CE | |||||
| :1010F400138707006FF05FE003C70D006FF01FD088 | |||||
| :10110400138D0A00832D01016FF01F8C83A70D003E | |||||
| :1011140093880F002322C10013D7F741B346F70089 | |||||
| :101124002320710193D7F7013387E6406FF0DFDDA9 | |||||
| :1011340003A70D0093880F002322C100232071010F | |||||
| :10114400930700006FF05FDC93F70640130800017B | |||||
| :1011540013F636FFE38407C66FF01FC683A70D009E | |||||
| :1011640093D6F74133C7F6003307D7406FF0DFD883 | |||||
| :10117400232801006FF09FAF2328F100E31A05B084 | |||||
| :101184006FF0DFEB13040D00138D0A006FF09FE482 | |||||
| :10119400930606006FF0DFFB631405006780000010 | |||||
| :1011A4006F00801A6308050003A3050083A54500AA | |||||
| :1011B4006700030067800000130101FC1303410270 | |||||
| :1011C4002322B1022324C1022326D1022328E102CF | |||||
| :1011D4009306050093058100130703001306F0FF2F | |||||
| :1011E40017050000130585FB232E1100232AF102A5 | |||||
| :1011F400232C0103232E110323266100EFF04FF368 | |||||
| :101204008320C1011301010467800000130101FC64 | |||||
| :10121400130381022324C1022326D1022328E102DD | |||||
| :101224009386050013070300930505001306F0FFDA | |||||
| :1012340017F5FFFF1305C500232E1100232AF10221 | |||||
| :10124400232C0103232E110323266100EFF04FEE1C | |||||
| :101254008320C1011301010467800000130101FC14 | |||||
| :101264001303C1022326D1022328E10293060600B8 | |||||
| :1012740013070300138605009305050017F5FFFF08 | |||||
| :10128400130505FC232E1100232AF102232C01034C | |||||
| :10129400232E110323266100EFF08FE98320C1017F | |||||
| :1012A4001301010467800000130101FE1387050088 | |||||
| :1012B400930605009305C1001306F0FF170500000F | |||||
| :1012C4001305C5ED232E1100EFF08FE68320C10135 | |||||
| :1012D40013010102678000001387060093060600CD | |||||
| :1012E400138605009305050017F5FFFF130545F563 | |||||
| :1012F4006FF00FE4130101FC1303C1022326D10292 | |||||
| :101304002328E1022324A1002326B100930606002A | |||||
| :1013140093058100130703001306F0FF170500006F | |||||
| :10132400130585E8232E1100232AF102232C01033F | |||||
| :10133400232E110323226100EFF08FDF8320C101EC | |||||
| :101344001301010467800000130101FEA307A1003B | |||||
| :10135400930510001305F100232E1100EF00C001C6 | |||||
| :101364008320C10113010102678000001385050079 | |||||
| :10137400930506006F004000638605023306B5003E | |||||
| :10138400370701F0834605008327470093D70701F9 | |||||
| :1013940093F7F70FE38A07FE2320D7001305150000 | |||||
| :1013A400E312A6FE678000008346050063840602FC | |||||
| :1013B400370701F08327470093D7070193F7F70F07 | |||||
| :1013C400E38A07FE2320D700130515008346050092 | |||||
| :1013D400E39206FE67800000F32500B8732500B091 | |||||
| :1013E400732600B8E39AC5FE678000004111814569 | |||||
| :1013F40022C406C62A841928970700009387C73594 | |||||
| :1014040088435C5D91C3829722854922797197074D | |||||
| :1014140000009387673462C403AC07004ECE52CCFD | |||||
| :1014240056CA5AC806D622D426D24AD05EC6AA8A3A | |||||
| :101434002E8B054AFD5903298C1463040902832465 | |||||
| :1014440049001384F4FF634E04008A04CA946306BB | |||||
| :101454000B0283A74410638267037D14F114E3181D | |||||
| :1014640034FFB250225492540259F249624AD24A89 | |||||
| :10147400424BB24B224C4561828083274900D440C1 | |||||
| :10148400FD176380870423A20400E1DA8327891807 | |||||
| :1014940033178A00832B4900F98F99EB82968327AF | |||||
| :1014A4004900E39A77F983278C14E38827FB61B713 | |||||
| :1014B4008327C91883A544087D8F19E7568582962A | |||||
| :1014C400F9BF23228900D1B72E858296C9BF411165 | |||||
| :1014D40022C4970700009387A72817040000130469 | |||||
| :1014E40024281D8C06C626C2098411C8931424001E | |||||
| :1014F400F114BE949C407D14F114829765FCB240B3 | |||||
| :101504002244924441018280AA85814601460145D4 | |||||
| :1015140009A09707000093872724984383278714FB | |||||
| :10152400A1C3D8437D48634DE804131827001DC1A7 | |||||
| :10153400338307012324C30883A887180546331679 | |||||
| :10154400E600B3E8C80023A417192324D31089465E | |||||
| :10155400630DD5000507D8C3C2978CC701458280A7 | |||||
| :101564009307C7142324F7146DBF83A6C718050770 | |||||
| :10157400D8C3558E23A6C718C2978CC7014582804D | |||||
| :101584007D55828067800000678000006F00000046 | |||||
| :1015940040F5FFFF9CF4FFFF9CF4FFFF34F5FFFFD1 | |||||
| :1015A4009CF4FFFF9CF4FFFF9CF4FFFF9CF4FFFFFF | |||||
| :1015B4009CF4FFFF9CF4FFFF9CF4FFFF28F5FFFF62 | |||||
| :1015C4009CF4FFFF1CF5FFFF9CF4FFFF9CF4FFFF5E | |||||
| :1015D4007CF4FFFF3CF8FFFFE0F3FFFFE0F3FFFFC5 | |||||
| :1015E400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFFB3 | |||||
| :1015F400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFFA3 | |||||
| :10160400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF92 | |||||
| :10161400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF82 | |||||
| :10162400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF72 | |||||
| :10163400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF62 | |||||
| :10164400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF52 | |||||
| :10165400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF42 | |||||
| :10166400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF32 | |||||
| :10167400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF22 | |||||
| :10168400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF12 | |||||
| :10169400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFF02 | |||||
| :1016A400A8F7FFFFE0F3FFFFE0F3FFFFE0F3FFFF26 | |||||
| :1016B400E0F3FFFFE0F3FFFFE0F3FFFFE0F3FFFFE2 | |||||
| :1016C400E0F3FFFFE0F3FFFFA8F7FFFF48F7FFFF9A | |||||
| :1016D400A8F7FFFFE0F3FFFFE0F3FFFFE0F3FFFFF6 | |||||
| :1016E400E0F3FFFFA8F7FFFFE0F3FFFFE0F3FFFFE6 | |||||
| :1016F400E0F3FFFFE0F3FFFFE0F3FFFFA8F7FFFFD6 | |||||
| :1017040008F7FFFFE0F3FFFFE0F3FFFF50F6FFFFF2 | |||||
| :10171400E0F3FFFFA8F7FFFFE0F3FFFFE0F3FFFFB5 | |||||
| :10172400A8F7FFFF48454C4C4F20574F524C440AF2 | |||||
| :1017340000000000537461746520696E203A20250E | |||||
| :10174400690A00005374617465206F75743A20252A | |||||
| :08175400690A00000000048096 | |||||
| :04175C0028020080DF | |||||
| :1017600000000000EC02048054030480BC030480E9 | |||||
| :101770000000000000000000000000000000000069 | |||||
| :101780000000000000000000000000000000000059 | |||||
| :101790000000000000000000000000000000000049 | |||||
| :1017A0000000000000000000000000000000000039 | |||||
| :1017B0000000000000000000000000000000000029 | |||||
| :1017C0000000000000000000000000000000000019 | |||||
| :1017D0000000000000000000000000000000000009 | |||||
| :1017E00000000000000000000000000000000000F9 | |||||
| :1017F00000000000000000000000000000000000E9 | |||||
| :1018000000000000000000000100000000000000D7 | |||||
| :101810000E33CDAB34126DE6ECDE05000B0000009C | |||||
| :1018200000000000000000000000000000000000B8 | |||||
| :1018300000000000000000000000000000000000A8 | |||||
| :101840000000000000000000000000000000000098 | |||||
| :101850000000000000000000000000000000000088 | |||||
| :101860000000000000000000000000000000000078 | |||||
| :101870000000000000000000000000000000000068 | |||||
| :101880000000000000000000000000000000000058 | |||||
| :101890000000000000000000000000000000000048 | |||||
| :1018A0000000000000000000000000000000000038 | |||||
| :1018B0000000000000000000000000000000000028 | |||||
| :1018C0000000000000000000000000000000000018 | |||||
| :1018D0000000000000000000000000000000000008 | |||||
| :1018E00000000000000000000000000000000000F8 | |||||
| :1018F00000000000000000000000000000000000E8 | |||||
| :1019000000000000000000000000000000000000D7 | |||||
| :1019100000000000000000000000000000000000C7 | |||||
| :1019200000000000000000000000000000000000B7 | |||||
| :1019300000000000000000000000000000000000A7 | |||||
| :101940000000000000000000000000000000000097 | |||||
| :101950000000000000000000000000000000000087 | |||||
| :101960000000000000000000000000000000000077 | |||||
| :101970000000000000000000000000000000000067 | |||||
| :101980000000000000000000000000000000000057 | |||||
| :101990000000000000000000000000000000000047 | |||||
| :1019A0000000000000000000000000000000000037 | |||||
| :1019B0000000000000000000000000000000000027 | |||||
| :1019C0000000000000000000000000000000000017 | |||||
| :1019D0000000000000000000000000000000000007 | |||||
| :1019E00000000000000000000000000000000000F7 | |||||
| :1019F00000000000000000000000000000000000E7 | |||||
| :101A000000000000000000000000000000000000D6 | |||||
| :101A100000000000000000000000000000000000C6 | |||||
| :101A200000000000000000000000000000000000B6 | |||||
| :101A300000000000000000000000000000000000A6 | |||||
| :101A40000000000000000000000000000000000096 | |||||
| :101A50000000000000000000000000000000000086 | |||||
| :101A60000000000000000000000000000000000076 | |||||
| :101A70000000000000000000000000000000000066 | |||||
| :101A80000000000000000000000000000000000056 | |||||
| :101A90000000000000000000000000000000000046 | |||||
| :101AA0000000000000000000000000000000000036 | |||||
| :101AB0000000000000000000000000000000000026 | |||||
| :101AC0000000000000000000000000000000000016 | |||||
| :101AD0000000000000000000000000000000000006 | |||||
| :101AE00000000000000000000000000000000000F6 | |||||
| :101AF00000000000000000000000000000000000E6 | |||||
| :101B000000000000000000000000000000000000D5 | |||||
| :101B100000000000000000000000000000000000C5 | |||||
| :101B200000000000000000000000000000000000B5 | |||||
| :101B300000000000000000000000000000000000A5 | |||||
| :101B40000000000000000000000000000000000095 | |||||
| :101B50000000000000000000000000000000000085 | |||||
| :101B60000000000000000000000000000000000075 | |||||
| :101B70000000000000000000000000000000000065 | |||||
| :081B800000000000000000005D | |||||
| :040000058000000077 | |||||
| :00000001FF | |||||
| @ -0,0 +1,137 @@ | |||||
| /* SECTIONS for volatile chip configuration, i.e. chips without flash */ | |||||
| SECTIONS | |||||
| { | |||||
| .init : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.init))) | |||||
| } >rom | |||||
| .text : | |||||
| { | |||||
| *(.text.unlikely .text.unlikely.*) | |||||
| *(.text.startup .text.startup.*) | |||||
| *(.text .text.*) | |||||
| *(.gnu.linkonce.t.*) | |||||
| } >rom | |||||
| .fini : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.fini))) | |||||
| } >rom | |||||
| PROVIDE (__etext = .); | |||||
| PROVIDE (_etext = .); | |||||
| PROVIDE (etext = .); | |||||
| . = ALIGN(4); | |||||
| .preinit_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__preinit_array_start = .); | |||||
| KEEP (*(.preinit_array)) | |||||
| PROVIDE_HIDDEN (__preinit_array_end = .); | |||||
| } >rom | |||||
| .init_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__init_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | |||||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | |||||
| PROVIDE_HIDDEN (__init_array_end = .); | |||||
| } >rom | |||||
| .fini_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__fini_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | |||||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | |||||
| PROVIDE_HIDDEN (__fini_array_end = .); | |||||
| } >rom | |||||
| .ctors : | |||||
| { | |||||
| /* gcc uses crtbegin.o to find the start of | |||||
| the constructors, so we make sure it is | |||||
| first. Because this is a wildcard, it | |||||
| doesn't matter if the user does not | |||||
| actually link against crtbegin.o; the | |||||
| linker won't look for a file to match a | |||||
| wildcard. The wildcard also means that it | |||||
| doesn't matter which directory crtbegin.o | |||||
| is in. */ | |||||
| KEEP (*crtbegin.o(.ctors)) | |||||
| KEEP (*crtbegin?.o(.ctors)) | |||||
| /* We don't want to include the .ctor section from | |||||
| the crtend.o file until after the sorted ctors. | |||||
| The .ctor section from the crtend file contains the | |||||
| end of ctors marker and it must be last */ | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |||||
| KEEP (*(SORT(.ctors.*))) | |||||
| KEEP (*(.ctors)) | |||||
| } >rom | |||||
| .dtors : | |||||
| { | |||||
| KEEP (*crtbegin.o(.dtors)) | |||||
| KEEP (*crtbegin?.o(.dtors)) | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |||||
| KEEP (*(SORT(.dtors.*))) | |||||
| KEEP (*(.dtors)) | |||||
| } >rom | |||||
| .dalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _data = . ); | |||||
| } >rom | |||||
| /* RODATA is usally in ROM, however in volatile configurations this doesn't | |||||
| make a lot of sense. */ | |||||
| .rodata : | |||||
| { | |||||
| *(.rdata) | |||||
| *(.rodata .rodata.*) | |||||
| *(.gnu.linkonce.r.*) | |||||
| } >ram | |||||
| .data : | |||||
| { | |||||
| *(.data .data.*) | |||||
| *(.gnu.linkonce.d.*) | |||||
| . = ALIGN(8); | |||||
| PROVIDE( __global_pointer$ = . + 0x800 ); | |||||
| *(.sdata .sdata.*) | |||||
| *(.gnu.linkonce.s.*) | |||||
| . = ALIGN(8); | |||||
| *(.srodata.cst16) | |||||
| *(.srodata.cst8) | |||||
| *(.srodata.cst4) | |||||
| *(.srodata.cst2) | |||||
| *(.srodata .srodata.*) | |||||
| } >ram | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _edata = . ); | |||||
| PROVIDE( edata = . ); | |||||
| PROVIDE( _fbss = . ); | |||||
| PROVIDE( __bss_start = . ); | |||||
| .bss : | |||||
| { | |||||
| *(.sbss*) | |||||
| *(.gnu.linkonce.sb.*) | |||||
| *(.bss .bss.*) | |||||
| *(.gnu.linkonce.b.*) | |||||
| *(COMMON) | |||||
| . = ALIGN(4); | |||||
| } >ram | |||||
| . = ALIGN(8); | |||||
| PROVIDE( _end = . ); | |||||
| PROVIDE( end = . ); | |||||
| } | |||||
| PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); | |||||
| PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); | |||||
| @ -0,0 +1,137 @@ | |||||
| /* SECTIONS for volatile chip configuration, i.e. chips without flash */ | |||||
| SECTIONS | |||||
| { | |||||
| .init : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.init))) | |||||
| } >rom | |||||
| .text : | |||||
| { | |||||
| *(.text.unlikely .text.unlikely.*) | |||||
| *(.text.startup .text.startup.*) | |||||
| *(.text .text.*) | |||||
| *(.gnu.linkonce.t.*) | |||||
| } >rom | |||||
| .fini : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.fini))) | |||||
| } >rom | |||||
| PROVIDE (__etext = .); | |||||
| PROVIDE (_etext = .); | |||||
| PROVIDE (etext = .); | |||||
| . = ALIGN(4); | |||||
| .preinit_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__preinit_array_start = .); | |||||
| KEEP (*(.preinit_array)) | |||||
| PROVIDE_HIDDEN (__preinit_array_end = .); | |||||
| } >rom | |||||
| .init_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__init_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | |||||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | |||||
| PROVIDE_HIDDEN (__init_array_end = .); | |||||
| } >rom | |||||
| .fini_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__fini_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | |||||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | |||||
| PROVIDE_HIDDEN (__fini_array_end = .); | |||||
| } >rom | |||||
| .ctors : | |||||
| { | |||||
| /* gcc uses crtbegin.o to find the start of | |||||
| the constructors, so we make sure it is | |||||
| first. Because this is a wildcard, it | |||||
| doesn't matter if the user does not | |||||
| actually link against crtbegin.o; the | |||||
| linker won't look for a file to match a | |||||
| wildcard. The wildcard also means that it | |||||
| doesn't matter which directory crtbegin.o | |||||
| is in. */ | |||||
| KEEP (*crtbegin.o(.ctors)) | |||||
| KEEP (*crtbegin?.o(.ctors)) | |||||
| /* We don't want to include the .ctor section from | |||||
| the crtend.o file until after the sorted ctors. | |||||
| The .ctor section from the crtend file contains the | |||||
| end of ctors marker and it must be last */ | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |||||
| KEEP (*(SORT(.ctors.*))) | |||||
| KEEP (*(.ctors)) | |||||
| } >rom | |||||
| .dtors : | |||||
| { | |||||
| KEEP (*crtbegin.o(.dtors)) | |||||
| KEEP (*crtbegin?.o(.dtors)) | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |||||
| KEEP (*(SORT(.dtors.*))) | |||||
| KEEP (*(.dtors)) | |||||
| } >rom | |||||
| .dalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _data = . ); | |||||
| } >rom | |||||
| /* RODATA is usally in ROM, however in volatile configurations this doesn't | |||||
| make a lot of sense. */ | |||||
| .rodata : | |||||
| { | |||||
| *(.rdata) | |||||
| *(.rodata .rodata.*) | |||||
| *(.gnu.linkonce.r.*) | |||||
| } >ram | |||||
| .data : | |||||
| { | |||||
| *(.data .data.*) | |||||
| *(.gnu.linkonce.d.*) | |||||
| . = ALIGN(8); | |||||
| PROVIDE( __global_pointer$ = . + 0x800 ); | |||||
| *(.sdata .sdata.*) | |||||
| *(.gnu.linkonce.s.*) | |||||
| . = ALIGN(8); | |||||
| *(.srodata.cst16) | |||||
| *(.srodata.cst8) | |||||
| *(.srodata.cst4) | |||||
| *(.srodata.cst2) | |||||
| *(.srodata .srodata.*) | |||||
| } >ram | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _edata = . ); | |||||
| PROVIDE( edata = . ); | |||||
| PROVIDE( _fbss = . ); | |||||
| PROVIDE( __bss_start = . ); | |||||
| .bss : | |||||
| { | |||||
| *(.sbss*) | |||||
| *(.gnu.linkonce.sb.*) | |||||
| *(.bss .bss.*) | |||||
| *(.gnu.linkonce.b.*) | |||||
| *(COMMON) | |||||
| . = ALIGN(4); | |||||
| } >ram | |||||
| . = ALIGN(8); | |||||
| PROVIDE( _end = . ); | |||||
| PROVIDE( end = . ); | |||||
| } | |||||
| PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); | |||||
| PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); | |||||
| @ -0,0 +1,54 @@ | |||||
| PLATFORM ?= murax | |||||
| RISCV_ARCH ?= rv32im | |||||
| RISCV_ABI ?= ilp32 | |||||
| RISCV_CMODEL ?= medany | |||||
| RISCV_ARCHFLAGS += -march=$(RISCV_ARCH) | |||||
| RISCV_ARCHFLAGS += -mabi=$(RISCV_ABI) | |||||
| RISCV_ARCHFLAGS += -mcmodel=$(RISCV_CMODEL) | |||||
| CFLAGS += -Os -Wall -Wextra | |||||
| CFLAGS += $(RISCV_ARCHFLAGS) | |||||
| CFLAGS += -fstrict-volatile-bitfields | |||||
| CFLAGS += --specs=nosys.specs | |||||
| ifeq ($(PLATFORM),murax) | |||||
| CFLAGS += -DVEXRISCV_VOLATILE | |||||
| endif | |||||
| ifeq ($(PLATFORM),pqvexriscvup5k) | |||||
| CFLAGS += -DVEXRISCV_VOLATILE -DVEXRISCV_RWMTVEC | |||||
| endif | |||||
| ifeq ($(PLATFORM),pqvexriscvicoboard) | |||||
| CFLAGS += -DVEXRISCV_VOLATILE -DVEXRISCV_RWMTVEC | |||||
| endif | |||||
| ifeq ($(PLATFORM),pqvexriscvsim) | |||||
| CFLAGS += -DVEXRISCV_RWMTVEC | |||||
| endif | |||||
| ifeq ($(PLATFORM),pqvexriscvsimhuge) | |||||
| CFLAGS += -DVEXRISCV_RWMTVEC | |||||
| endif | |||||
| CROSS_PREFIX ?= riscv64-unknown-elf | |||||
| CC = $(CROSS_PREFIX)-gcc | |||||
| AR = $(CROSS_PREFIX)-ar | |||||
| SRCS = init.c start.s | |||||
| OBJS = $(PLATFORM)_init.o $(PLATFORM)_start.o | |||||
| TARGET = lib$(PLATFORM)bsp.a | |||||
| all: $(TARGET) | |||||
| $(TARGET): $(OBJS) | |||||
| $(AR) rcs $@ $^ | |||||
| $(PLATFORM)_%.o: %.c | |||||
| $(CC) $(CFLAGS) -c -o $@ $< | |||||
| $(PLATFORM)_%.o: %.S | |||||
| $(CC) $(CFLAGS) -c -o $@ $< | |||||
| clean: | |||||
| rm -rf $(OBJS) $(TARGET) | |||||
| @ -0,0 +1,8 @@ | |||||
| #include "weak_under_alias.h" | |||||
| void __weak__init() {} | |||||
| void __weak__fini() {} | |||||
| weak_under_alias(_init); | |||||
| weak_under_alias(_fini); | |||||
| @ -0,0 +1,29 @@ | |||||
| #include <stdbool.h> | |||||
| #include "hal.h" | |||||
| // typedef struct { | |||||
| // volatile uint32_t state; | |||||
| // } My_Mem; | |||||
| // #define MY_MEM ((My_Mem*)(0xF0030000)) | |||||
| int main(void) | |||||
| { | |||||
| printf("HELLO WORLD\n"); | |||||
| uint32_t state = 10000; | |||||
| // uint32_t state_return; | |||||
| while (1) | |||||
| { | |||||
| printf("State in : %i\n", state); | |||||
| // MY_MEM->state = state; | |||||
| // state_return = MY_MEM->state; | |||||
| state = state + 1; | |||||
| printf("State out: %i\n", state); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| @ -0,0 +1,11 @@ | |||||
| OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") | |||||
| OUTPUT_ARCH(riscv) | |||||
| ENTRY( _start ) | |||||
| MEMORY | |||||
| { | |||||
| ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 8k | |||||
| } | |||||
| INCLUDE volatile.ld | |||||
| @ -0,0 +1,141 @@ | |||||
| /* SECTIONS for non-volatile chip configuration, i.e. chips with flash */ | |||||
| SECTIONS | |||||
| { | |||||
| .init : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.init))) | |||||
| } >rom | |||||
| .text : | |||||
| { | |||||
| *(.text.unlikely .text.unlikely.*) | |||||
| *(.text.startup .text.startup.*) | |||||
| *(.text .text.*) | |||||
| *(.gnu.linkonce.t.*) | |||||
| } >rom | |||||
| .fini : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.fini))) | |||||
| } >rom | |||||
| PROVIDE (__etext = .); | |||||
| PROVIDE (_etext = .); | |||||
| PROVIDE (etext = .); | |||||
| .rodata : | |||||
| { | |||||
| *(.rdata) | |||||
| *(.rodata .rodata.*) | |||||
| *(.gnu.linkonce.r.*) | |||||
| . = ALIGN(8); | |||||
| *(.srodata.cst16) | |||||
| *(.srodata.cst8) | |||||
| *(.srodata.cst4) | |||||
| *(.srodata.cst2) | |||||
| *(.srodata .srodata.*) | |||||
| } >rom | |||||
| . = ALIGN(4); | |||||
| .preinit_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__preinit_array_start = .); | |||||
| KEEP (*(.preinit_array)) | |||||
| PROVIDE_HIDDEN (__preinit_array_end = .); | |||||
| } >rom | |||||
| .init_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__init_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | |||||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | |||||
| PROVIDE_HIDDEN (__init_array_end = .); | |||||
| } >rom | |||||
| .fini_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__fini_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | |||||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | |||||
| PROVIDE_HIDDEN (__fini_array_end = .); | |||||
| } >rom | |||||
| .ctors : | |||||
| { | |||||
| /* gcc uses crtbegin.o to find the start of | |||||
| the constructors, so we make sure it is | |||||
| first. Because this is a wildcard, it | |||||
| doesn't matter if the user does not | |||||
| actually link against crtbegin.o; the | |||||
| linker won't look for a file to match a | |||||
| wildcard. The wildcard also means that it | |||||
| doesn't matter which directory crtbegin.o | |||||
| is in. */ | |||||
| KEEP (*crtbegin.o(.ctors)) | |||||
| KEEP (*crtbegin?.o(.ctors)) | |||||
| /* We don't want to include the .ctor section from | |||||
| the crtend.o file until after the sorted ctors. | |||||
| The .ctor section from the crtend file contains the | |||||
| end of ctors marker and it must be last */ | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |||||
| KEEP (*(SORT(.ctors.*))) | |||||
| KEEP (*(.ctors)) | |||||
| } >rom | |||||
| .dtors : | |||||
| { | |||||
| KEEP (*crtbegin.o(.dtors)) | |||||
| KEEP (*crtbegin?.o(.dtors)) | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |||||
| KEEP (*(SORT(.dtors.*))) | |||||
| KEEP (*(.dtors)) | |||||
| } >rom | |||||
| .lalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| } >rom | |||||
| .dalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| } >ram AT>rom | |||||
| .data : | |||||
| { | |||||
| PROVIDE( _data = . ); | |||||
| *(.data .data.*) | |||||
| *(.gnu.linkonce.d.*) | |||||
| . = ALIGN(8); | |||||
| PROVIDE( __global_pointer$ = . + 0x800 ); | |||||
| *(.sdata .sdata.*) | |||||
| *(.gnu.linkonce.s.*) | |||||
| } >ram AT>rom | |||||
| PROVIDE( _data_lma = LOADADDR(.data) ); | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _edata = . ); | |||||
| PROVIDE( edata = . ); | |||||
| PROVIDE( _fbss = . ); | |||||
| PROVIDE( __bss_start = . ); | |||||
| .bss : | |||||
| { | |||||
| *(.sbss*) | |||||
| *(.gnu.linkonce.sb.*) | |||||
| *(.bss .bss.*) | |||||
| *(.gnu.linkonce.b.*) | |||||
| *(COMMON) | |||||
| . = ALIGN(4); | |||||
| } >ram | |||||
| . = ALIGN(8); | |||||
| PROVIDE( _end = . ); | |||||
| PROVIDE( end = . ); | |||||
| } | |||||
| PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); | |||||
| PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); | |||||
| @ -0,0 +1,11 @@ | |||||
| OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") | |||||
| OUTPUT_ARCH(riscv) | |||||
| ENTRY( _start ) | |||||
| MEMORY | |||||
| { | |||||
| ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 1024K | |||||
| } | |||||
| INCLUDE volatile.ld | |||||
| @ -0,0 +1,14 @@ | |||||
| OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") | |||||
| OUTPUT_ARCH(riscv) | |||||
| ENTRY( _start ) | |||||
| __ram_size = 384K; | |||||
| MEMORY | |||||
| { | |||||
| rom (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 256K | |||||
| ram (wxa!ri) : ORIGIN = 0x80040000, LENGTH = 128K | |||||
| } | |||||
| INCLUDE nonvolatile.ld | |||||
| @ -0,0 +1,14 @@ | |||||
| OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") | |||||
| OUTPUT_ARCH(riscv) | |||||
| ENTRY( _start ) | |||||
| __ram_size = 16M; | |||||
| MEMORY | |||||
| { | |||||
| rom (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 8M | |||||
| ram (wxa!ri) : ORIGIN = 0x80800000, LENGTH = 8M | |||||
| } | |||||
| INCLUDE nonvolatile.ld | |||||
| @ -0,0 +1,14 @@ | |||||
| OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") | |||||
| OUTPUT_ARCH(riscv) | |||||
| ENTRY( _start ) | |||||
| __ram_size = 128K; | |||||
| MEMORY | |||||
| { | |||||
| rom (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 64K | |||||
| ram (wxa!ri) : ORIGIN = 0x80010000, LENGTH = 64K | |||||
| } | |||||
| INCLUDE volatile-split.ld | |||||
| @ -0,0 +1,156 @@ | |||||
| .section .init | |||||
| .global _start | |||||
| .type _start,@function | |||||
| _start: | |||||
| #ifndef VEXRISCV_RWMTVEC | |||||
| j _crtInit | |||||
| nop | |||||
| nop | |||||
| nop | |||||
| nop | |||||
| nop | |||||
| nop | |||||
| nop | |||||
| j trap_entry | |||||
| _crtInit: | |||||
| #endif | |||||
| .cfi_startproc | |||||
| .cfi_undefined ra | |||||
| .option push | |||||
| .option norelax | |||||
| la gp, __global_pointer$ | |||||
| .option pop | |||||
| la sp, _sp | |||||
| #ifndef VEXRISCV_VOLATILE | |||||
| /* Load data section */ | |||||
| la a0, _data_lma | |||||
| la a1, _data | |||||
| la a2, _edata | |||||
| bgeu a1, a2, 2f | |||||
| 1: | |||||
| lw t0, (a0) | |||||
| sw t0, (a1) | |||||
| addi a0, a0, 4 | |||||
| addi a1, a1, 4 | |||||
| bltu a1, a2, 1b | |||||
| 2: | |||||
| #endif | |||||
| /* Clear bss section */ | |||||
| la a0, __bss_start | |||||
| la a1, _end | |||||
| bgeu a0, a1, 2f | |||||
| 1: | |||||
| sw zero, (a0) | |||||
| addi a0, a0, 4 | |||||
| bltu a0, a1, 1b | |||||
| 2: | |||||
| /* Call global constructors */ | |||||
| la a0, __libc_fini_array | |||||
| call atexit | |||||
| call __libc_init_array | |||||
| auipc ra, 0 | |||||
| addi sp, sp, -16 | |||||
| sw ra, 8(sp) | |||||
| /* Enable Interrupts and set trap vector */ | |||||
| #ifndef VEXRISCV_RWMTVEC | |||||
| la a0, trap_entry | |||||
| csrw mtvec, a0 | |||||
| #endif | |||||
| li a0, 0x880 //880 enable timer + external interrupts | |||||
| csrw mie, a0 | |||||
| li a0, 0x1808 //1808 enable interrupts | |||||
| csrw mstatus, a0 | |||||
| /* argc = argv = 0 */ | |||||
| li a0, 0 | |||||
| li a1, 0 | |||||
| call main | |||||
| tail exit | |||||
| 1: | |||||
| j 1b | |||||
| .cfi_endproc | |||||
| .align 4 | |||||
| .weak trap_entry | |||||
| .global trap_entry | |||||
| trap_entry: | |||||
| addi sp, sp, -32*4 | |||||
| sw x1, 1*4(sp) | |||||
| sw x2, 2*4(sp) | |||||
| sw x3, 3*4(sp) | |||||
| sw x4, 4*4(sp) | |||||
| sw x5, 5*4(sp) | |||||
| sw x6, 6*4(sp) | |||||
| sw x7, 7*4(sp) | |||||
| sw x8, 8*4(sp) | |||||
| sw x9, 9*4(sp) | |||||
| sw x10, 10*4(sp) | |||||
| sw x11, 11*4(sp) | |||||
| sw x12, 12*4(sp) | |||||
| sw x13, 13*4(sp) | |||||
| sw x14, 14*4(sp) | |||||
| sw x15, 15*4(sp) | |||||
| sw x16, 16*4(sp) | |||||
| sw x17, 17*4(sp) | |||||
| sw x18, 18*4(sp) | |||||
| sw x19, 19*4(sp) | |||||
| sw x20, 20*4(sp) | |||||
| sw x21, 21*4(sp) | |||||
| sw x22, 22*4(sp) | |||||
| sw x23, 23*4(sp) | |||||
| sw x24, 24*4(sp) | |||||
| sw x25, 25*4(sp) | |||||
| sw x26, 26*4(sp) | |||||
| sw x27, 27*4(sp) | |||||
| sw x28, 28*4(sp) | |||||
| sw x29, 29*4(sp) | |||||
| sw x30, 30*4(sp) | |||||
| sw x31, 31*4(sp) | |||||
| call irqCallback | |||||
| lw x1, 1*4(sp) | |||||
| lw x2, 2*4(sp) | |||||
| lw x3, 3*4(sp) | |||||
| lw x4, 4*4(sp) | |||||
| lw x5, 5*4(sp) | |||||
| lw x6, 6*4(sp) | |||||
| lw x7, 7*4(sp) | |||||
| lw x8, 8*4(sp) | |||||
| lw x9, 9*4(sp) | |||||
| lw x10, 10*4(sp) | |||||
| lw x11, 11*4(sp) | |||||
| lw x12, 12*4(sp) | |||||
| lw x13, 13*4(sp) | |||||
| lw x14, 14*4(sp) | |||||
| lw x15, 15*4(sp) | |||||
| lw x16, 16*4(sp) | |||||
| lw x17, 17*4(sp) | |||||
| lw x18, 18*4(sp) | |||||
| lw x19, 19*4(sp) | |||||
| lw x20, 20*4(sp) | |||||
| lw x21, 21*4(sp) | |||||
| lw x22, 22*4(sp) | |||||
| lw x23, 23*4(sp) | |||||
| lw x24, 24*4(sp) | |||||
| lw x25, 25*4(sp) | |||||
| lw x26, 26*4(sp) | |||||
| lw x27, 27*4(sp) | |||||
| lw x28, 28*4(sp) | |||||
| lw x29, 29*4(sp) | |||||
| lw x30, 30*4(sp) | |||||
| lw x31, 31*4(sp) | |||||
| addi sp, sp, 32*4 | |||||
| mret | |||||
| .weak irqCallback | |||||
| irqCallback: | |||||
| 1: | |||||
| j 1b | |||||
| @ -0,0 +1,137 @@ | |||||
| /* SECTIONS for volatile chip configuration, i.e. chips without flash */ | |||||
| SECTIONS | |||||
| { | |||||
| .init : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.init))) | |||||
| } >rom | |||||
| .text : | |||||
| { | |||||
| *(.text.unlikely .text.unlikely.*) | |||||
| *(.text.startup .text.startup.*) | |||||
| *(.text .text.*) | |||||
| *(.gnu.linkonce.t.*) | |||||
| } >rom | |||||
| .fini : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.fini))) | |||||
| } >rom | |||||
| PROVIDE (__etext = .); | |||||
| PROVIDE (_etext = .); | |||||
| PROVIDE (etext = .); | |||||
| . = ALIGN(4); | |||||
| .preinit_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__preinit_array_start = .); | |||||
| KEEP (*(.preinit_array)) | |||||
| PROVIDE_HIDDEN (__preinit_array_end = .); | |||||
| } >rom | |||||
| .init_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__init_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | |||||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | |||||
| PROVIDE_HIDDEN (__init_array_end = .); | |||||
| } >rom | |||||
| .fini_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__fini_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | |||||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | |||||
| PROVIDE_HIDDEN (__fini_array_end = .); | |||||
| } >rom | |||||
| .ctors : | |||||
| { | |||||
| /* gcc uses crtbegin.o to find the start of | |||||
| the constructors, so we make sure it is | |||||
| first. Because this is a wildcard, it | |||||
| doesn't matter if the user does not | |||||
| actually link against crtbegin.o; the | |||||
| linker won't look for a file to match a | |||||
| wildcard. The wildcard also means that it | |||||
| doesn't matter which directory crtbegin.o | |||||
| is in. */ | |||||
| KEEP (*crtbegin.o(.ctors)) | |||||
| KEEP (*crtbegin?.o(.ctors)) | |||||
| /* We don't want to include the .ctor section from | |||||
| the crtend.o file until after the sorted ctors. | |||||
| The .ctor section from the crtend file contains the | |||||
| end of ctors marker and it must be last */ | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |||||
| KEEP (*(SORT(.ctors.*))) | |||||
| KEEP (*(.ctors)) | |||||
| } >rom | |||||
| .dtors : | |||||
| { | |||||
| KEEP (*crtbegin.o(.dtors)) | |||||
| KEEP (*crtbegin?.o(.dtors)) | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |||||
| KEEP (*(SORT(.dtors.*))) | |||||
| KEEP (*(.dtors)) | |||||
| } >rom | |||||
| .dalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _data = . ); | |||||
| } >rom | |||||
| /* RODATA is usally in ROM, however in volatile configurations this doesn't | |||||
| make a lot of sense. */ | |||||
| .rodata : | |||||
| { | |||||
| *(.rdata) | |||||
| *(.rodata .rodata.*) | |||||
| *(.gnu.linkonce.r.*) | |||||
| } >ram | |||||
| .data : | |||||
| { | |||||
| *(.data .data.*) | |||||
| *(.gnu.linkonce.d.*) | |||||
| . = ALIGN(8); | |||||
| PROVIDE( __global_pointer$ = . + 0x800 ); | |||||
| *(.sdata .sdata.*) | |||||
| *(.gnu.linkonce.s.*) | |||||
| . = ALIGN(8); | |||||
| *(.srodata.cst16) | |||||
| *(.srodata.cst8) | |||||
| *(.srodata.cst4) | |||||
| *(.srodata.cst2) | |||||
| *(.srodata .srodata.*) | |||||
| } >ram | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _edata = . ); | |||||
| PROVIDE( edata = . ); | |||||
| PROVIDE( _fbss = . ); | |||||
| PROVIDE( __bss_start = . ); | |||||
| .bss : | |||||
| { | |||||
| *(.sbss*) | |||||
| *(.gnu.linkonce.sb.*) | |||||
| *(.bss .bss.*) | |||||
| *(.gnu.linkonce.b.*) | |||||
| *(COMMON) | |||||
| . = ALIGN(4); | |||||
| } >ram | |||||
| . = ALIGN(8); | |||||
| PROVIDE( _end = . ); | |||||
| PROVIDE( end = . ); | |||||
| } | |||||
| PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); | |||||
| PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); | |||||
| @ -0,0 +1,137 @@ | |||||
| /* SECTIONS for volatile chip configuration, i.e. chips without flash */ | |||||
| SECTIONS | |||||
| { | |||||
| .init : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.init))) | |||||
| } >ram | |||||
| .text : | |||||
| { | |||||
| *(.text.unlikely .text.unlikely.*) | |||||
| *(.text.startup .text.startup.*) | |||||
| *(.text .text.*) | |||||
| *(.gnu.linkonce.t.*) | |||||
| } >ram | |||||
| .fini : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.fini))) | |||||
| } >ram | |||||
| PROVIDE (__etext = .); | |||||
| PROVIDE (_etext = .); | |||||
| PROVIDE (etext = .); | |||||
| . = ALIGN(4); | |||||
| .preinit_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__preinit_array_start = .); | |||||
| KEEP (*(.preinit_array)) | |||||
| PROVIDE_HIDDEN (__preinit_array_end = .); | |||||
| } >ram | |||||
| .init_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__init_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | |||||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | |||||
| PROVIDE_HIDDEN (__init_array_end = .); | |||||
| } >ram | |||||
| .fini_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__fini_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | |||||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | |||||
| PROVIDE_HIDDEN (__fini_array_end = .); | |||||
| } >ram | |||||
| .ctors : | |||||
| { | |||||
| /* gcc uses crtbegin.o to find the start of | |||||
| the constructors, so we make sure it is | |||||
| first. Because this is a wildcard, it | |||||
| doesn't matter if the user does not | |||||
| actually link against crtbegin.o; the | |||||
| linker won't look for a file to match a | |||||
| wildcard. The wildcard also means that it | |||||
| doesn't matter which directory crtbegin.o | |||||
| is in. */ | |||||
| KEEP (*crtbegin.o(.ctors)) | |||||
| KEEP (*crtbegin?.o(.ctors)) | |||||
| /* We don't want to include the .ctor section from | |||||
| the crtend.o file until after the sorted ctors. | |||||
| The .ctor section from the crtend file contains the | |||||
| end of ctors marker and it must be last */ | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |||||
| KEEP (*(SORT(.ctors.*))) | |||||
| KEEP (*(.ctors)) | |||||
| } >ram | |||||
| .dtors : | |||||
| { | |||||
| KEEP (*crtbegin.o(.dtors)) | |||||
| KEEP (*crtbegin?.o(.dtors)) | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |||||
| KEEP (*(SORT(.dtors.*))) | |||||
| KEEP (*(.dtors)) | |||||
| } >ram | |||||
| .dalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _data = . ); | |||||
| } >ram | |||||
| /* RODATA is usally in ROM, however in volatile configurations this doesn't | |||||
| make a lot of sense. */ | |||||
| .rodata : | |||||
| { | |||||
| *(.rdata) | |||||
| *(.rodata .rodata.*) | |||||
| *(.gnu.linkonce.r.*) | |||||
| } >ram | |||||
| .data : | |||||
| { | |||||
| *(.data .data.*) | |||||
| *(.gnu.linkonce.d.*) | |||||
| . = ALIGN(8); | |||||
| PROVIDE( __global_pointer$ = . + 0x800 ); | |||||
| *(.sdata .sdata.*) | |||||
| *(.gnu.linkonce.s.*) | |||||
| . = ALIGN(8); | |||||
| *(.srodata.cst16) | |||||
| *(.srodata.cst8) | |||||
| *(.srodata.cst4) | |||||
| *(.srodata.cst2) | |||||
| *(.srodata .srodata.*) | |||||
| } >ram | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _edata = . ); | |||||
| PROVIDE( edata = . ); | |||||
| PROVIDE( _fbss = . ); | |||||
| PROVIDE( __bss_start = . ); | |||||
| .bss : | |||||
| { | |||||
| *(.sbss*) | |||||
| *(.gnu.linkonce.sb.*) | |||||
| *(.bss .bss.*) | |||||
| *(.gnu.linkonce.b.*) | |||||
| *(COMMON) | |||||
| . = ALIGN(4); | |||||
| } >ram | |||||
| . = ALIGN(8); | |||||
| PROVIDE( _end = . ); | |||||
| PROVIDE( end = . ); | |||||
| } | |||||
| PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); | |||||
| PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); | |||||
| @ -0,0 +1,7 @@ | |||||
| #ifndef WEAK_UNDER_ALIAS_H | |||||
| #define WEAK_UNDER_ALIAS_H | |||||
| #define weak_under_alias(name) \ | |||||
| extern __typeof (__weak_##name) name __attribute__ ((weak, alias ("__weak_"#name))) | |||||
| #endif /* WEAK_UNDER_ALIAS_H */ | |||||
| @ -0,0 +1 @@ | |||||
| riscv64-unknown-elf-gcc -o main.elf -Os -g -Wall -Wextra -Wimplicit-function-declaration -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes -Wundef -Wshadow -fno-common -MD -DPQRISCV_PLATFORM=vexriscv -march=rv32im -mabi=ilp32 -mcmodel=medany -fstrict-volatile-bitfields -DVEXRISCV_PLATFORM=pqvexriscvup5k -DMUPQ_NAMESPACE= hal.c hal-vexriscv.c main.c memcpy.c memset.c printf.c -I"" --specs=nano.specs --specs=nosys.specs -Wl,-Tbsp/vexriscv/pqvexriscvup5k.ld -nostartfiles -ffreestanding -Wl,--gc-sections -Lbsp/vexriscv -Wl,--start-group -lpqvexriscvup5kbsp -lc -lm -Wl,--end-group | |||||
| @ -0,0 +1,60 @@ | |||||
| #include "hal.h" | |||||
| #include <stddef.h> | |||||
| /* Murax UART */ | |||||
| typedef struct { | |||||
| volatile uint32_t DATA; | |||||
| volatile uint32_t STATUS; | |||||
| volatile uint32_t CLOCK_DIVIDER; | |||||
| volatile uint32_t FRAME_CONFIG; | |||||
| } Uart_Reg; | |||||
| enum UartParity { NONE = 0, EVEN = 1, ODD = 2 }; | |||||
| enum UartStop { ONE = 0, TWO = 1 }; | |||||
| typedef struct { | |||||
| uint32_t dataLength; | |||||
| enum UartParity parity; | |||||
| enum UartStop stop; | |||||
| uint32_t clockDivider; | |||||
| } Uart_Config; | |||||
| static uint32_t uart_writeAvailability(Uart_Reg* reg) | |||||
| { | |||||
| return (reg->STATUS >> 16) & 0xFF; | |||||
| } | |||||
| static void uart_write(Uart_Reg* reg, uint32_t data) | |||||
| { | |||||
| while (uart_writeAvailability(reg) == 0) | |||||
| ; | |||||
| reg->DATA = data; | |||||
| } | |||||
| #define UART ((Uart_Reg*)(0xF0010000)) | |||||
| void hal_send(const uint8_t* in, const size_t len) { | |||||
| for (size_t i = 0; i < len; i++) { | |||||
| uart_write(UART, in[i]); | |||||
| } | |||||
| } | |||||
| void hal_send_str(const char* in) | |||||
| { | |||||
| const char* cur = in; | |||||
| while(*cur) { | |||||
| uart_write(UART, *cur); | |||||
| cur += 1; | |||||
| } | |||||
| } | |||||
| __attribute__((naked)) uint64_t hal_get_time(void) | |||||
| { | |||||
| #define LE "\n\t" | |||||
| asm volatile (LE"csrr a1, mcycleh" | |||||
| LE"csrr a0, mcycle" | |||||
| LE"csrr a2, mcycleh" | |||||
| LE"bne a1, a2, hal_get_time" | |||||
| LE"ret"); | |||||
| } | |||||
| @ -0,0 +1,21 @@ | |||||
| #include <stdio.h> | |||||
| #include <stdint.h> | |||||
| #include <stddef.h> | |||||
| #include <errno.h> | |||||
| #undef errno | |||||
| extern int errno; | |||||
| #include "hal.h" | |||||
| void _putchar(char c) { | |||||
| hal_send((uint8_t*)&c, 1); | |||||
| } | |||||
| void _write(int fd, const void* ptr, size_t len) { | |||||
| // Don't care about the fd. Just put everything on the UART console. | |||||
| (void)fd; | |||||
| hal_send(ptr, len); | |||||
| } | |||||
| @ -0,0 +1,18 @@ | |||||
| #ifndef VECRISCV_HAL_H_ | |||||
| #define VECRISCV_HAL_H_ | |||||
| #include <stddef.h> | |||||
| #include <stdint.h> | |||||
| #include <sys/types.h> | |||||
| #define printf printf_ | |||||
| void hal_send(const uint8_t* in, const size_t len); | |||||
| void hal_send_str(const char* in); | |||||
| int printf_(const char* format, ...); | |||||
| void _putchar(char c); | |||||
| void _write(int fd, const void* ptr, size_t len); | |||||
| #endif /* VECRISCV_HAL_H_ */ | |||||
| @ -0,0 +1,29 @@ | |||||
| #include <stdbool.h> | |||||
| #include "hal.h" | |||||
| // typedef struct { | |||||
| // volatile uint32_t state; | |||||
| // } My_Mem; | |||||
| // #define MY_MEM ((My_Mem*)(0xF0030000)) | |||||
| int main(void) | |||||
| { | |||||
| printf("HELLO WORLD\n"); | |||||
| uint32_t state = 10000; | |||||
| // uint32_t state_return; | |||||
| while (1) | |||||
| { | |||||
| printf("State in : %i\n", state); | |||||
| // MY_MEM->state = state; | |||||
| // state_return = MY_MEM->state; | |||||
| state = state + 1; | |||||
| printf("State out: %i\n", state); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| @ -0,0 +1,6 @@ | |||||
| main.elf: printf.c \ | |||||
| /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/include/stdbool.h \ | |||||
| /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/include/stdint.h \ | |||||
| /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/include/stdint-gcc.h \ | |||||
| printf.h /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/include/stdarg.h \ | |||||
| /opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/include/stddef.h | |||||
| @ -0,0 +1,16 @@ | |||||
| /* Public domain. */ | |||||
| #include <stddef.h> | |||||
| int | |||||
| memcmp (const void *str1, const void *str2, size_t count) | |||||
| { | |||||
| const unsigned char *s1 = str1; | |||||
| const unsigned char *s2 = str2; | |||||
| while (count-- > 0) | |||||
| { | |||||
| if (*s1++ != *s2++) | |||||
| return s1[-1] < s2[-1] ? -1 : 1; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| @ -0,0 +1,61 @@ | |||||
| /* Public domain. */ | |||||
| #include <stddef.h> | |||||
| /* | |||||
| ** Copyright 2001, Travis Geiselbrecht. All rights reserved. | |||||
| ** Distributed under the terms of the NewOS License. | |||||
| */ | |||||
| /* | |||||
| * Copyright (c) 2008 Travis Geiselbrecht | |||||
| * | |||||
| * Permission is hereby granted, free of charge, to any person obtaining | |||||
| * a copy of this software and associated documentation files | |||||
| * (the "Software"), to deal in the Software without restriction, | |||||
| * including without limitation the rights to use, copy, modify, merge, | |||||
| * publish, distribute, sublicense, and/or sell copies of the Software, | |||||
| * and to permit persons to whom the Software is furnished to do so, | |||||
| * subject to the following conditions: | |||||
| * | |||||
| * The above copyright notice and this permission notice shall be | |||||
| * included in all copies or substantial portions of the Software. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||||
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||||
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||||
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||||
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| */ | |||||
| #include <string.h> | |||||
| #include <sys/types.h> | |||||
| typedef long word; | |||||
| #define lsize sizeof(word) | |||||
| #define lmask (lsize - 1) | |||||
| void *memcpy(void *dest, const void *src, size_t count) | |||||
| { | |||||
| char *d = (char *)dest; | |||||
| const char *s = (const char *)src; | |||||
| int len; | |||||
| if(count == 0 || dest == src) | |||||
| return dest; | |||||
| if(((long)d | (long)s) & lmask) { | |||||
| // src and/or dest do not align on word boundary | |||||
| if((((long)d ^ (long)s) & lmask) || (count < lsize)) | |||||
| len = count; // copy the rest of the buffer with the byte mover | |||||
| else | |||||
| len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary | |||||
| count -= len; | |||||
| for(; len > 0; len--) | |||||
| *d++ = *s++; | |||||
| } | |||||
| for(len = count / lsize; len > 0; len--) { | |||||
| *(word *)d = *(word *)s; | |||||
| d += lsize; | |||||
| s += lsize; | |||||
| } | |||||
| for(len = count & lmask; len > 0; len--) | |||||
| *d++ = *s++; | |||||
| return dest; | |||||
| } | |||||
| @ -0,0 +1,64 @@ | |||||
| /* | |||||
| ** Copyright 2005, Michael Noisternig. All rights reserved. | |||||
| ** Copyright 2001, Travis Geiselbrecht. All rights reserved. | |||||
| ** Distributed under the terms of the NewOS License. | |||||
| */ | |||||
| /* | |||||
| * Copyright (c) 2008 Travis Geiselbrecht | |||||
| * | |||||
| * Permission is hereby granted, free of charge, to any person obtaining | |||||
| * a copy of this software and associated documentation files | |||||
| * (the "Software"), to deal in the Software without restriction, | |||||
| * including without limitation the rights to use, copy, modify, merge, | |||||
| * publish, distribute, sublicense, and/or sell copies of the Software, | |||||
| * and to permit persons to whom the Software is furnished to do so, | |||||
| * subject to the following conditions: | |||||
| * | |||||
| * The above copyright notice and this permission notice shall be | |||||
| * included in all copies or substantial portions of the Software. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||||
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |||||
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||||
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||||
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| */ | |||||
| #include <string.h> | |||||
| #include <sys/types.h> | |||||
| // void * | |||||
| // memset(void *s, int c, size_t count) | |||||
| // { | |||||
| // char *xs = (char *) s; | |||||
| // // size_t len = (-(size_t)s) & (sizeof(size_t)-1); | |||||
| // // int cc = c & 0xff; | |||||
| // // if ( count > len ) { | |||||
| // // count -= len; | |||||
| // // cc |= cc << 8; | |||||
| // // cc |= cc << 16; | |||||
| // // // write to non-aligned memory byte-wise | |||||
| // // for ( ; len > 0; len-- ) | |||||
| // // *xs++ = c; | |||||
| // // // write to aligned memory dword-wise | |||||
| // // for ( len = count/sizeof(size_t); len > 0; len-- ) { | |||||
| // // *((size_t *)xs) = cc; | |||||
| // // xs += sizeof(size_t); | |||||
| // // } | |||||
| // // count &= sizeof(size_t)-1; | |||||
| // // } | |||||
| // // write remaining bytes | |||||
| // for ( ; count > 0; count-- ) | |||||
| // *xs++ = (char) c; | |||||
| // return s; | |||||
| // } | |||||
| void * | |||||
| memset (void *dest, int val, size_t len) | |||||
| { | |||||
| unsigned char *ptr = dest; | |||||
| while (len-- > 0) | |||||
| *ptr++ = (unsigned char) val; | |||||
| return dest; | |||||
| } | |||||
| @ -0,0 +1,14 @@ | |||||
| OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") | |||||
| OUTPUT_ARCH(riscv) | |||||
| ENTRY( _start ) | |||||
| __ram_size = 128K; | |||||
| MEMORY | |||||
| { | |||||
| rom (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 64K | |||||
| ram (wxa!ri) : ORIGIN = 0x80010000, LENGTH = 64K | |||||
| } | |||||
| INCLUDE volatile-split.ld | |||||
| @ -0,0 +1,987 @@ | |||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| // \author (c) Marco Paland (info@paland.com) | |||||
| // 2014-2019, PALANDesign Hannover, Germany | |||||
| // | |||||
| // \license The MIT License (MIT) | |||||
| // | |||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| // of this software and associated documentation files (the "Software"), to deal | |||||
| // in the Software without restriction, including without limitation the rights | |||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| // copies of the Software, and to permit persons to whom the Software is | |||||
| // furnished to do so, subject to the following conditions: | |||||
| // | |||||
| // The above copyright notice and this permission notice shall be included in | |||||
| // all copies or substantial portions of the Software. | |||||
| // | |||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||||
| // THE SOFTWARE. | |||||
| // | |||||
| // \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on | |||||
| // embedded systems with a very limited resources. These routines are thread | |||||
| // safe and reentrant! | |||||
| // Use this instead of the bloated standard/newlib printf cause these use | |||||
| // malloc for printf (and may not be thread safe). | |||||
| // | |||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| #include <stdbool.h> | |||||
| #include <stdint.h> | |||||
| #include "printf.h" | |||||
| // define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the | |||||
| // printf_config.h header file | |||||
| // default: undefined | |||||
| #ifdef PRINTF_INCLUDE_CONFIG_H | |||||
| #include "printf_config.h" | |||||
| #endif | |||||
| // 'ntoa' conversion buffer size, this must be big enough to hold one converted | |||||
| // numeric number including padded zeros (dynamically created on stack) | |||||
| // default: 32 byte | |||||
| #ifndef PRINTF_NTOA_BUFFER_SIZE | |||||
| #define PRINTF_NTOA_BUFFER_SIZE 32U | |||||
| #endif | |||||
| // 'ftoa' conversion buffer size, this must be big enough to hold one converted | |||||
| // float number including padded zeros (dynamically created on stack) | |||||
| // default: 32 byte | |||||
| #ifndef PRINTF_FTOA_BUFFER_SIZE | |||||
| #define PRINTF_FTOA_BUFFER_SIZE 32U | |||||
| #endif | |||||
| // support for the floating point type (%f) | |||||
| // default: activated | |||||
| // #ifndef PRINTF_DISABLE_SUPPORT_FLOAT | |||||
| // #define PRINTF_SUPPORT_FLOAT | |||||
| // #endif | |||||
| // support for exponential floating point notation (%e/%g) | |||||
| // default: activated | |||||
| // #ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL | |||||
| // #define PRINTF_SUPPORT_EXPONENTIAL | |||||
| // #endif | |||||
| // define the default floating point precision | |||||
| // default: 6 digits | |||||
| // #ifndef PRINTF_DEFAULT_FLOAT_PRECISION | |||||
| // #define PRINTF_DEFAULT_FLOAT_PRECISION 6U | |||||
| // #endif | |||||
| // define the largest float suitable to print with %f | |||||
| // default: 1e9 | |||||
| // #ifndef PRINTF_MAX_FLOAT | |||||
| // #define PRINTF_MAX_FLOAT 1e9 | |||||
| // #endif | |||||
| // support for the long long types (%llu or %p) | |||||
| // default: activated | |||||
| #ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG | |||||
| #define PRINTF_SUPPORT_LONG_LONG | |||||
| #endif | |||||
| // support for the ptrdiff_t type (%t) | |||||
| // ptrdiff_t is normally defined in <stddef.h> as long or long long type | |||||
| // default: activated | |||||
| // #ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T | |||||
| // #define PRINTF_SUPPORT_PTRDIFF_T | |||||
| // #endif | |||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| // internal flag definitions | |||||
| #define FLAGS_ZEROPAD (1U << 0U) | |||||
| #define FLAGS_LEFT (1U << 1U) | |||||
| #define FLAGS_PLUS (1U << 2U) | |||||
| #define FLAGS_SPACE (1U << 3U) | |||||
| #define FLAGS_HASH (1U << 4U) | |||||
| #define FLAGS_UPPERCASE (1U << 5U) | |||||
| #define FLAGS_CHAR (1U << 6U) | |||||
| #define FLAGS_SHORT (1U << 7U) | |||||
| #define FLAGS_LONG (1U << 8U) | |||||
| #define FLAGS_LONG_LONG (1U << 9U) | |||||
| #define FLAGS_PRECISION (1U << 10U) | |||||
| #define FLAGS_ADAPT_EXP (1U << 11U) | |||||
| // import float.h for DBL_MAX | |||||
| // #if defined(PRINTF_SUPPORT_FLOAT) | |||||
| // #include <float.h> | |||||
| // #endif | |||||
| // output function type | |||||
| typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen); | |||||
| // wrapper (used as buffer) for output function type | |||||
| typedef struct { | |||||
| void (*fct)(char character, void* arg); | |||||
| void* arg; | |||||
| } out_fct_wrap_type; | |||||
| // Sometimes div modulo is not available, we implement one with shift/and/or | |||||
| static int divmod(int* Qptr, int* Rptr, const int N, const int D) { | |||||
| if (D == 0) { | |||||
| return -1; | |||||
| } | |||||
| int Q = 0; | |||||
| int R = 0; | |||||
| for (int i = 8*sizeof(int) - 1; i >= 0; i--) { | |||||
| R <<= 1; | |||||
| R |= (N >> i) & 0x1; | |||||
| if (R >= D) { | |||||
| R -= D; | |||||
| Q |= 1 << i; | |||||
| } | |||||
| } | |||||
| *Qptr = Q; | |||||
| *Rptr = R; | |||||
| return 0; | |||||
| } | |||||
| // Sometimes div modulo is not available, we implement one with shift/and/or | |||||
| static int divmod_long_long(long long* Qptr, long long* Rptr, const long long N, const int D) { | |||||
| if (D == 0) { | |||||
| return -1; | |||||
| } | |||||
| long long Q = 0; | |||||
| long long R = 0; | |||||
| for (long long i = 8*sizeof(long long) - 1; i >= 0; i--) { | |||||
| R <<= 1; | |||||
| R |= (N >> i) & 0x1; | |||||
| if (R >= D) { | |||||
| R -= D; | |||||
| Q |= 1 << i; | |||||
| } | |||||
| } | |||||
| *Qptr = Q; | |||||
| *Rptr = R; | |||||
| return 0; | |||||
| } | |||||
| // internal buffer output | |||||
| static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen) | |||||
| { | |||||
| if (idx < maxlen) { | |||||
| ((char*)buffer)[idx] = character; | |||||
| } | |||||
| } | |||||
| // internal null output | |||||
| static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen) | |||||
| { | |||||
| (void)character; (void)buffer; (void)idx; (void)maxlen; | |||||
| } | |||||
| // internal _putchar wrapper | |||||
| static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen) | |||||
| { | |||||
| (void)buffer; (void)idx; (void)maxlen; | |||||
| if (character) { | |||||
| _putchar(character); | |||||
| } | |||||
| } | |||||
| // internal output function wrapper | |||||
| static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen) | |||||
| { | |||||
| (void)idx; (void)maxlen; | |||||
| if (character) { | |||||
| // buffer is the output fct pointer | |||||
| ((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg); | |||||
| } | |||||
| } | |||||
| // internal secure strlen | |||||
| // \return The length of the string (excluding the terminating 0) limited by 'maxsize' | |||||
| static inline unsigned int _strnlen_s(const char* str, size_t maxsize) | |||||
| { | |||||
| const char* s; | |||||
| for (s = str; *s && maxsize--; ++s); | |||||
| return (unsigned int)(s - str); | |||||
| } | |||||
| // internal test if char is a digit (0-9) | |||||
| // \return true if char is a digit | |||||
| static inline bool _is_digit(char ch) | |||||
| { | |||||
| return (ch >= '0') && (ch <= '9'); | |||||
| } | |||||
| // internal ASCII string to unsigned int conversion | |||||
| static unsigned int _atoi(const char** str) | |||||
| { | |||||
| unsigned int i = 0U; | |||||
| while (_is_digit(**str)) { | |||||
| i = i * 10U + (unsigned int)(*((*str)++) - '0'); | |||||
| } | |||||
| return i; | |||||
| } | |||||
| // output the specified string in reverse, taking care of any zero-padding | |||||
| static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags) | |||||
| { | |||||
| const size_t start_idx = idx; | |||||
| // pad spaces up to given width | |||||
| if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { | |||||
| for (size_t i = len; i < width; i++) { | |||||
| out(' ', buffer, idx++, maxlen); | |||||
| } | |||||
| } | |||||
| // reverse string | |||||
| while (len) { | |||||
| out(buf[--len], buffer, idx++, maxlen); | |||||
| } | |||||
| // append pad spaces up to given width | |||||
| if (flags & FLAGS_LEFT) { | |||||
| while (idx - start_idx < width) { | |||||
| out(' ', buffer, idx++, maxlen); | |||||
| } | |||||
| } | |||||
| return idx; | |||||
| } | |||||
| // internal itoa format | |||||
| static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) | |||||
| { | |||||
| // pad leading zeros | |||||
| if (!(flags & FLAGS_LEFT)) { | |||||
| if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { | |||||
| width--; | |||||
| } | |||||
| while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | |||||
| buf[len++] = '0'; | |||||
| } | |||||
| while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | |||||
| buf[len++] = '0'; | |||||
| } | |||||
| } | |||||
| // handle hash | |||||
| if (flags & FLAGS_HASH) { | |||||
| if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) { | |||||
| len--; | |||||
| if (len && (base == 16U)) { | |||||
| len--; | |||||
| } | |||||
| } | |||||
| if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | |||||
| buf[len++] = 'x'; | |||||
| } | |||||
| else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | |||||
| buf[len++] = 'X'; | |||||
| } | |||||
| else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) { | |||||
| buf[len++] = 'b'; | |||||
| } | |||||
| if (len < PRINTF_NTOA_BUFFER_SIZE) { | |||||
| buf[len++] = '0'; | |||||
| } | |||||
| } | |||||
| if (len < PRINTF_NTOA_BUFFER_SIZE) { | |||||
| if (negative) { | |||||
| buf[len++] = '-'; | |||||
| } | |||||
| else if (flags & FLAGS_PLUS) { | |||||
| buf[len++] = '+'; // ignore the space if the '+' exists | |||||
| } | |||||
| else if (flags & FLAGS_SPACE) { | |||||
| buf[len++] = ' '; | |||||
| } | |||||
| } | |||||
| return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); | |||||
| } | |||||
| // internal itoa for 'long' type | |||||
| static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) | |||||
| { | |||||
| char buf[PRINTF_NTOA_BUFFER_SIZE]; | |||||
| size_t len = 0U; | |||||
| int q, r; | |||||
| // no hash for 0 values | |||||
| if (!value) { | |||||
| flags &= ~FLAGS_HASH; | |||||
| } | |||||
| // write if precision != 0 and value is != 0 | |||||
| if (!(flags & FLAGS_PRECISION) || value) { | |||||
| q = 0, r = 0; | |||||
| len = 0; | |||||
| do { | |||||
| divmod(&q, &r, value, base); | |||||
| const char digit = (char)(r); | |||||
| // buf[idx2++] = '0' + digit; | |||||
| buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; | |||||
| value = q; | |||||
| } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); | |||||
| // while (idx2 > 0) { | |||||
| // _putchar(buf[--idx2]); | |||||
| // written++; | |||||
| // } | |||||
| // idx++; | |||||
| // do { | |||||
| // const char digit = (char)(value % base); | |||||
| // buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; | |||||
| // value /= base; | |||||
| // } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); | |||||
| } | |||||
| return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); | |||||
| } | |||||
| // // internal itoa for 'long long' type | |||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | |||||
| static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) | |||||
| { | |||||
| char buf[PRINTF_NTOA_BUFFER_SIZE]; | |||||
| size_t len = 0U; | |||||
| long long q, r; | |||||
| // no hash for 0 values | |||||
| if (!value) { | |||||
| flags &= ~FLAGS_HASH; | |||||
| } | |||||
| // write if precision != 0 and value is != 0 | |||||
| if (!(flags & FLAGS_PRECISION) || value) { | |||||
| q = 0, r = 0; | |||||
| len = 0; | |||||
| do { | |||||
| divmod_long_long(&q, &r, value, base); | |||||
| const char digit = (char)(r); | |||||
| // buf[idx2++] = '0' + digit; | |||||
| buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; | |||||
| value = q; | |||||
| } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); | |||||
| // do { | |||||
| // const char digit = (char)(value % base); | |||||
| // buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; | |||||
| // value /= base; | |||||
| // } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); | |||||
| } | |||||
| return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); | |||||
| } | |||||
| #endif // PRINTF_SUPPORT_LONG_LONG | |||||
| // #if defined(PRINTF_SUPPORT_FLOAT) | |||||
| // | |||||
| // #if defined(PRINTF_SUPPORT_EXPONENTIAL) | |||||
| // // forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT | |||||
| // static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); | |||||
| // #endif | |||||
| // | |||||
| // | |||||
| // // internal ftoa for fixed decimal floating point | |||||
| // static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) | |||||
| // { | |||||
| // char buf[PRINTF_FTOA_BUFFER_SIZE]; | |||||
| // size_t len = 0U; | |||||
| // double diff = 0.0; | |||||
| // | |||||
| // // powers of 10 | |||||
| // static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; | |||||
| // | |||||
| // // test for special values | |||||
| // if (value != value) | |||||
| // return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); | |||||
| // if (value < -DBL_MAX) | |||||
| // return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); | |||||
| // if (value > DBL_MAX) | |||||
| // return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); | |||||
| // | |||||
| // // test for very large values | |||||
| // // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad | |||||
| // if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) { | |||||
| // #if defined(PRINTF_SUPPORT_EXPONENTIAL) | |||||
| // return _etoa(out, buffer, idx, maxlen, value, prec, width, flags); | |||||
| // #else | |||||
| // return 0U; | |||||
| // #endif | |||||
| // } | |||||
| // | |||||
| // // test for negative | |||||
| // bool negative = false; | |||||
| // if (value < 0) { | |||||
| // negative = true; | |||||
| // value = 0 - value; | |||||
| // } | |||||
| // | |||||
| // // set default precision, if not set explicitly | |||||
| // if (!(flags & FLAGS_PRECISION)) { | |||||
| // prec = PRINTF_DEFAULT_FLOAT_PRECISION; | |||||
| // } | |||||
| // // limit precision to 9, cause a prec >= 10 can lead to overflow errors | |||||
| // while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) { | |||||
| // buf[len++] = '0'; | |||||
| // prec--; | |||||
| // } | |||||
| // | |||||
| // int whole = (int)value; | |||||
| // double tmp = (value - whole) * pow10[prec]; | |||||
| // unsigned long frac = (unsigned long)tmp; | |||||
| // diff = tmp - frac; | |||||
| // | |||||
| // if (diff > 0.5) { | |||||
| // ++frac; | |||||
| // // handle rollover, e.g. case 0.99 with prec 1 is 1.0 | |||||
| // if (frac >= pow10[prec]) { | |||||
| // frac = 0; | |||||
| // ++whole; | |||||
| // } | |||||
| // } | |||||
| // else if (diff < 0.5) { | |||||
| // } | |||||
| // else if ((frac == 0U) || (frac & 1U)) { | |||||
| // // if halfway, round up if odd OR if last digit is 0 | |||||
| // ++frac; | |||||
| // } | |||||
| // | |||||
| // if (prec == 0U) { | |||||
| // diff = value - (double)whole; | |||||
| // if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) { | |||||
| // // exactly 0.5 and ODD, then round up | |||||
| // // 1.5 -> 2, but 2.5 -> 2 | |||||
| // ++whole; | |||||
| // } | |||||
| // } | |||||
| // else { | |||||
| // unsigned int count = prec; | |||||
| // // now do fractional part, as an unsigned number | |||||
| // while (len < PRINTF_FTOA_BUFFER_SIZE) { | |||||
| // --count; | |||||
| // buf[len++] = (char)(48U + (frac % 10U)); | |||||
| // if (!(frac /= 10U)) { | |||||
| // break; | |||||
| // } | |||||
| // } | |||||
| // // add extra 0s | |||||
| // while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) { | |||||
| // buf[len++] = '0'; | |||||
| // } | |||||
| // if (len < PRINTF_FTOA_BUFFER_SIZE) { | |||||
| // // add decimal | |||||
| // buf[len++] = '.'; | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // // do whole part, number is reversed | |||||
| // while (len < PRINTF_FTOA_BUFFER_SIZE) { | |||||
| // buf[len++] = (char)(48 + (whole % 10)); | |||||
| // if (!(whole /= 10)) { | |||||
| // break; | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // // pad leading zeros | |||||
| // if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { | |||||
| // if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { | |||||
| // width--; | |||||
| // } | |||||
| // while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { | |||||
| // buf[len++] = '0'; | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // if (len < PRINTF_FTOA_BUFFER_SIZE) { | |||||
| // if (negative) { | |||||
| // buf[len++] = '-'; | |||||
| // } | |||||
| // else if (flags & FLAGS_PLUS) { | |||||
| // buf[len++] = '+'; // ignore the space if the '+' exists | |||||
| // } | |||||
| // else if (flags & FLAGS_SPACE) { | |||||
| // buf[len++] = ' '; | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags); | |||||
| // } | |||||
| // | |||||
| // | |||||
| // #if defined(PRINTF_SUPPORT_EXPONENTIAL) | |||||
| // // internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com> | |||||
| // static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) | |||||
| // { | |||||
| // // check for NaN and special values | |||||
| // if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) { | |||||
| // return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags); | |||||
| // } | |||||
| // | |||||
| // // determine the sign | |||||
| // const bool negative = value < 0; | |||||
| // if (negative) { | |||||
| // value = -value; | |||||
| // } | |||||
| // | |||||
| // // default precision | |||||
| // if (!(flags & FLAGS_PRECISION)) { | |||||
| // prec = PRINTF_DEFAULT_FLOAT_PRECISION; | |||||
| // } | |||||
| // | |||||
| // // determine the decimal exponent | |||||
| // // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) | |||||
| // union { | |||||
| // uint64_t U; | |||||
| // double F; | |||||
| // } conv; | |||||
| // | |||||
| // conv.F = value; | |||||
| // int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 | |||||
| // conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) | |||||
| // // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 | |||||
| // int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); | |||||
| // // now we want to compute 10^expval but we want to be sure it won't overflow | |||||
| // exp2 = (int)(expval * 3.321928094887362 + 0.5); | |||||
| // const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; | |||||
| // const double z2 = z * z; | |||||
| // conv.U = (uint64_t)(exp2 + 1023) << 52U; | |||||
| // // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex | |||||
| // conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); | |||||
| // // correct for rounding errors | |||||
| // if (value < conv.F) { | |||||
| // expval--; | |||||
| // conv.F /= 10; | |||||
| // } | |||||
| // | |||||
| // // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters | |||||
| // unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; | |||||
| // | |||||
| // // in "%g" mode, "prec" is the number of *significant figures* not decimals | |||||
| // if (flags & FLAGS_ADAPT_EXP) { | |||||
| // // do we want to fall-back to "%f" mode? | |||||
| // if ((value >= 1e-4) && (value < 1e6)) { | |||||
| // if ((int)prec > expval) { | |||||
| // prec = (unsigned)((int)prec - expval - 1); | |||||
| // } | |||||
| // else { | |||||
| // prec = 0; | |||||
| // } | |||||
| // flags |= FLAGS_PRECISION; // make sure _ftoa respects precision | |||||
| // // no characters in exponent | |||||
| // minwidth = 0U; | |||||
| // expval = 0; | |||||
| // } | |||||
| // else { | |||||
| // // we use one sigfig for the whole part | |||||
| // if ((prec > 0) && (flags & FLAGS_PRECISION)) { | |||||
| // --prec; | |||||
| // } | |||||
| // } | |||||
| // } | |||||
| // | |||||
| // // will everything fit? | |||||
| // unsigned int fwidth = width; | |||||
| // if (width > minwidth) { | |||||
| // // we didn't fall-back so subtract the characters required for the exponent | |||||
| // fwidth -= minwidth; | |||||
| // } else { | |||||
| // // not enough characters, so go back to default sizing | |||||
| // fwidth = 0U; | |||||
| // } | |||||
| // if ((flags & FLAGS_LEFT) && minwidth) { | |||||
| // // if we're padding on the right, DON'T pad the floating part | |||||
| // fwidth = 0U; | |||||
| // } | |||||
| // | |||||
| // // rescale the float value | |||||
| // if (expval) { | |||||
| // value /= conv.F; | |||||
| // } | |||||
| // | |||||
| // // output the floating part | |||||
| // const size_t start_idx = idx; | |||||
| // idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP); | |||||
| // | |||||
| // // output the exponent part | |||||
| // if (minwidth) { | |||||
| // // output the exponential symbol | |||||
| // out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); | |||||
| // // output the exponent value | |||||
| // idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS); | |||||
| // // might need to right-pad spaces | |||||
| // if (flags & FLAGS_LEFT) { | |||||
| // while (idx - start_idx < width) out(' ', buffer, idx++, maxlen); | |||||
| // } | |||||
| // } | |||||
| // return idx; | |||||
| // } | |||||
| // #endif // PRINTF_SUPPORT_EXPONENTIAL | |||||
| // #endif // PRINTF_SUPPORT_FLOAT | |||||
| // internal vsnprintf | |||||
| static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va) | |||||
| { | |||||
| unsigned int flags, width, precision, n; | |||||
| size_t idx = 0U; | |||||
| if (!buffer) { | |||||
| // use null output function | |||||
| out = _out_null; | |||||
| } | |||||
| while (*format) | |||||
| { | |||||
| // format specifier? %[flags][width][.precision][length] | |||||
| if (*format != '%') { | |||||
| // no | |||||
| out(*format, buffer, idx++, maxlen); | |||||
| format++; | |||||
| continue; | |||||
| } | |||||
| else { | |||||
| // yes, evaluate it | |||||
| format++; | |||||
| } | |||||
| // evaluate flags | |||||
| flags = 0U; | |||||
| do { | |||||
| switch (*format) { | |||||
| case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break; | |||||
| case '-': flags |= FLAGS_LEFT; format++; n = 1U; break; | |||||
| case '+': flags |= FLAGS_PLUS; format++; n = 1U; break; | |||||
| case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break; | |||||
| case '#': flags |= FLAGS_HASH; format++; n = 1U; break; | |||||
| default : n = 0U; break; | |||||
| } | |||||
| } while (n); | |||||
| // evaluate width field | |||||
| width = 0U; | |||||
| if (_is_digit(*format)) { | |||||
| width = _atoi(&format); | |||||
| } | |||||
| else if (*format == '*') { | |||||
| const int w = va_arg(va, int); | |||||
| if (w < 0) { | |||||
| flags |= FLAGS_LEFT; // reverse padding | |||||
| width = (unsigned int)-w; | |||||
| } | |||||
| else { | |||||
| width = (unsigned int)w; | |||||
| } | |||||
| format++; | |||||
| } | |||||
| // evaluate precision field | |||||
| precision = 0U; | |||||
| if (*format == '.') { | |||||
| flags |= FLAGS_PRECISION; | |||||
| format++; | |||||
| if (_is_digit(*format)) { | |||||
| precision = _atoi(&format); | |||||
| } | |||||
| else if (*format == '*') { | |||||
| const int prec = (int)va_arg(va, int); | |||||
| precision = prec > 0 ? (unsigned int)prec : 0U; | |||||
| format++; | |||||
| } | |||||
| } | |||||
| // evaluate length field | |||||
| switch (*format) { | |||||
| case 'l' : | |||||
| flags |= FLAGS_LONG; | |||||
| format++; | |||||
| if (*format == 'l') { | |||||
| flags |= FLAGS_LONG_LONG; | |||||
| format++; | |||||
| } | |||||
| break; | |||||
| case 'h' : | |||||
| flags |= FLAGS_SHORT; | |||||
| format++; | |||||
| if (*format == 'h') { | |||||
| flags |= FLAGS_CHAR; | |||||
| format++; | |||||
| } | |||||
| break; | |||||
| // #if defined(PRINTF_SUPPORT_PTRDIFF_T) | |||||
| // case 't' : | |||||
| // flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); | |||||
| // format++; | |||||
| // break; | |||||
| // #endif | |||||
| case 'j' : | |||||
| flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); | |||||
| format++; | |||||
| break; | |||||
| case 'z' : | |||||
| flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); | |||||
| format++; | |||||
| break; | |||||
| default : | |||||
| break; | |||||
| } | |||||
| // evaluate specifier | |||||
| switch (*format) { | |||||
| case 'd' : | |||||
| case 'i' : | |||||
| case 'u' : | |||||
| case 'x' : | |||||
| case 'X' : | |||||
| case 'o' : | |||||
| case 'b' : { | |||||
| // set the base | |||||
| unsigned int base; | |||||
| if (*format == 'x' || *format == 'X') { | |||||
| base = 16U; | |||||
| } | |||||
| else if (*format == 'o') { | |||||
| base = 8U; | |||||
| } | |||||
| else if (*format == 'b') { | |||||
| base = 2U; | |||||
| } | |||||
| else { | |||||
| base = 10U; | |||||
| flags &= ~FLAGS_HASH; // no hash for dec format | |||||
| } | |||||
| // uppercase | |||||
| if (*format == 'X') { | |||||
| flags |= FLAGS_UPPERCASE; | |||||
| } | |||||
| // no plus or space flag for u, x, X, o, b | |||||
| if ((*format != 'i') && (*format != 'd')) { | |||||
| flags &= ~(FLAGS_PLUS | FLAGS_SPACE); | |||||
| } | |||||
| // ignore '0' flag when precision is given | |||||
| if (flags & FLAGS_PRECISION) { | |||||
| flags &= ~FLAGS_ZEROPAD; | |||||
| } | |||||
| // convert the integer | |||||
| if ((*format == 'i') || (*format == 'd')) { | |||||
| // signed | |||||
| if (flags & FLAGS_LONG_LONG) { | |||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | |||||
| const long long value = va_arg(va, long long); | |||||
| idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); | |||||
| #endif | |||||
| } | |||||
| else if (flags & FLAGS_LONG) { | |||||
| const long value = va_arg(va, long); | |||||
| idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); | |||||
| } | |||||
| else { | |||||
| const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); | |||||
| idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); | |||||
| } | |||||
| } | |||||
| else { | |||||
| // unsigned | |||||
| if (flags & FLAGS_LONG_LONG) { | |||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | |||||
| idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); | |||||
| #endif | |||||
| } | |||||
| else if (flags & FLAGS_LONG) { | |||||
| idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); | |||||
| } | |||||
| else { | |||||
| const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int); | |||||
| idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); | |||||
| } | |||||
| } | |||||
| format++; | |||||
| break; | |||||
| } | |||||
| // #if defined(PRINTF_SUPPORT_FLOAT) | |||||
| // case 'f' : | |||||
| // case 'F' : | |||||
| // if (*format == 'F') flags |= FLAGS_UPPERCASE; | |||||
| // idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); | |||||
| // format++; | |||||
| // break; | |||||
| // #if defined(PRINTF_SUPPORT_EXPONENTIAL) | |||||
| // case 'e': | |||||
| // case 'E': | |||||
| // case 'g': | |||||
| // case 'G': | |||||
| // if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; | |||||
| // if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; | |||||
| // idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); | |||||
| // format++; | |||||
| // break; | |||||
| // #endif // PRINTF_SUPPORT_EXPONENTIAL | |||||
| // #endif // PRINTF_SUPPORT_FLOAT | |||||
| case 'c' : { | |||||
| unsigned int l = 1U; | |||||
| // pre padding | |||||
| if (!(flags & FLAGS_LEFT)) { | |||||
| while (l++ < width) { | |||||
| out(' ', buffer, idx++, maxlen); | |||||
| } | |||||
| } | |||||
| // char output | |||||
| out((char)va_arg(va, int), buffer, idx++, maxlen); | |||||
| // post padding | |||||
| if (flags & FLAGS_LEFT) { | |||||
| while (l++ < width) { | |||||
| out(' ', buffer, idx++, maxlen); | |||||
| } | |||||
| } | |||||
| format++; | |||||
| break; | |||||
| } | |||||
| case 's' : { | |||||
| const char* p = va_arg(va, char*); | |||||
| unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1); | |||||
| // pre padding | |||||
| if (flags & FLAGS_PRECISION) { | |||||
| l = (l < precision ? l : precision); | |||||
| } | |||||
| if (!(flags & FLAGS_LEFT)) { | |||||
| while (l++ < width) { | |||||
| out(' ', buffer, idx++, maxlen); | |||||
| } | |||||
| } | |||||
| // string output | |||||
| while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { | |||||
| out(*(p++), buffer, idx++, maxlen); | |||||
| } | |||||
| // post padding | |||||
| if (flags & FLAGS_LEFT) { | |||||
| while (l++ < width) { | |||||
| out(' ', buffer, idx++, maxlen); | |||||
| } | |||||
| } | |||||
| format++; | |||||
| break; | |||||
| } | |||||
| case 'p' : { | |||||
| width = sizeof(void*) * 2U; | |||||
| flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; | |||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | |||||
| const bool is_ll = sizeof(uintptr_t) == sizeof(long long); | |||||
| if (is_ll) { | |||||
| idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags); | |||||
| } | |||||
| else { | |||||
| #endif | |||||
| idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags); | |||||
| #if defined(PRINTF_SUPPORT_LONG_LONG) | |||||
| } | |||||
| #endif | |||||
| format++; | |||||
| break; | |||||
| } | |||||
| case '%' : | |||||
| out('%', buffer, idx++, maxlen); | |||||
| format++; | |||||
| break; | |||||
| default : | |||||
| out(*format, buffer, idx++, maxlen); | |||||
| format++; | |||||
| break; | |||||
| } | |||||
| } | |||||
| // termination | |||||
| out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); | |||||
| // return written chars without terminating \0 | |||||
| return (int)idx; | |||||
| } | |||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| int printf_(const char* format, ...) | |||||
| { | |||||
| va_list va; | |||||
| va_start(va, format); | |||||
| char buffer[1]; | |||||
| const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); | |||||
| va_end(va); | |||||
| return ret; | |||||
| } | |||||
| int sprintf_(char* buffer, const char* format, ...) | |||||
| { | |||||
| va_list va; | |||||
| va_start(va, format); | |||||
| const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va); | |||||
| va_end(va); | |||||
| return ret; | |||||
| } | |||||
| int snprintf_(char* buffer, size_t count, const char* format, ...) | |||||
| { | |||||
| va_list va; | |||||
| va_start(va, format); | |||||
| const int ret = _vsnprintf(_out_buffer, buffer, count, format, va); | |||||
| va_end(va); | |||||
| return ret; | |||||
| } | |||||
| int vprintf_(const char* format, va_list va) | |||||
| { | |||||
| char buffer[1]; | |||||
| return _vsnprintf(_out_char, buffer, (size_t)-1, format, va); | |||||
| } | |||||
| int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) | |||||
| { | |||||
| return _vsnprintf(_out_buffer, buffer, count, format, va); | |||||
| } | |||||
| int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) | |||||
| { | |||||
| va_list va; | |||||
| va_start(va, format); | |||||
| const out_fct_wrap_type out_fct_wrap = { out, arg }; | |||||
| const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); | |||||
| va_end(va); | |||||
| return ret; | |||||
| } | |||||
| @ -0,0 +1,121 @@ | |||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| // \author (c) Marco Paland (info@paland.com) | |||||
| // 2014-2019, PALANDesign Hannover, Germany | |||||
| // | |||||
| // \license The MIT License (MIT) | |||||
| // | |||||
| // Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| // of this software and associated documentation files (the "Software"), to deal | |||||
| // in the Software without restriction, including without limitation the rights | |||||
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| // copies of the Software, and to permit persons to whom the Software is | |||||
| // furnished to do so, subject to the following conditions: | |||||
| // | |||||
| // The above copyright notice and this permission notice shall be included in | |||||
| // all copies or substantial portions of the Software. | |||||
| // | |||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||||
| // THE SOFTWARE. | |||||
| // | |||||
| // \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on | |||||
| // embedded systems with a very limited resources. | |||||
| // Use this instead of bloated standard/newlib printf. | |||||
| // These routines are thread safe and reentrant. | |||||
| // | |||||
| /////////////////////////////////////////////////////////////////////////////// | |||||
| #ifndef _PRINTF_H_ | |||||
| #define _PRINTF_H_ | |||||
| #include <stdarg.h> | |||||
| #include <stddef.h> | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| #define PRINTF_DISABLE_SUPPORT_FLOAT | |||||
| #define PRINTF_DISABLE_SUPPORT_EXPONENTIAL | |||||
| // #define PRINTF_DISABLE_SUPPORT_LONG_LONG | |||||
| #define PRINTF_DISABLE_SUPPORT_PTRDIFF_T | |||||
| /** | |||||
| * Output a character to a custom device like UART, used by the printf() function | |||||
| * This function is declared here only. You have to write your custom implementation somewhere | |||||
| * \param character Character to output | |||||
| */ | |||||
| void _putchar(char character); | |||||
| /** | |||||
| * Tiny printf implementation | |||||
| * You have to implement _putchar if you use printf() | |||||
| * To avoid conflicts with the regular printf() API it is overridden by macro defines | |||||
| * and internal underscore-appended functions like printf_() are used | |||||
| * \param format A string that specifies the format of the output | |||||
| * \return The number of characters that are written into the array, not counting the terminating null character | |||||
| */ | |||||
| #define printf printf_ | |||||
| int printf_(const char* format, ...); | |||||
| /** | |||||
| * Tiny sprintf implementation | |||||
| * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! | |||||
| * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! | |||||
| * \param format A string that specifies the format of the output | |||||
| * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character | |||||
| */ | |||||
| #define sprintf sprintf_ | |||||
| int sprintf_(char* buffer, const char* format, ...); | |||||
| /** | |||||
| * Tiny snprintf/vsnprintf implementation | |||||
| * \param buffer A pointer to the buffer where to store the formatted string | |||||
| * \param count The maximum number of characters to store in the buffer, including a terminating null character | |||||
| * \param format A string that specifies the format of the output | |||||
| * \param va A value identifying a variable arguments list | |||||
| * \return The number of characters that COULD have been written into the buffer, not counting the terminating | |||||
| * null character. A value equal or larger than count indicates truncation. Only when the returned value | |||||
| * is non-negative and less than count, the string has been completely written. | |||||
| */ | |||||
| #define snprintf snprintf_ | |||||
| #define vsnprintf vsnprintf_ | |||||
| int snprintf_(char* buffer, size_t count, const char* format, ...); | |||||
| int vsnprintf_(char* buffer, size_t count, const char* format, va_list va); | |||||
| /** | |||||
| * Tiny vprintf implementation | |||||
| * \param format A string that specifies the format of the output | |||||
| * \param va A value identifying a variable arguments list | |||||
| * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character | |||||
| */ | |||||
| #define vprintf vprintf_ | |||||
| int vprintf_(const char* format, va_list va); | |||||
| /** | |||||
| * printf with output function | |||||
| * You may use this as dynamic alternative to printf() with its fixed _putchar() output | |||||
| * \param out An output function which takes one character and an argument pointer | |||||
| * \param arg An argument pointer for user data passed to output function | |||||
| * \param format A string that specifies the format of the output | |||||
| * \return The number of characters that are sent to the output function, not counting the terminating null character | |||||
| */ | |||||
| int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...); | |||||
| #ifdef __cplusplus | |||||
| } | |||||
| #endif | |||||
| #endif // _PRINTF_H_ | |||||
| @ -0,0 +1,137 @@ | |||||
| /* SECTIONS for volatile chip configuration, i.e. chips without flash */ | |||||
| SECTIONS | |||||
| { | |||||
| .init : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.init))) | |||||
| } >rom | |||||
| .text : | |||||
| { | |||||
| *(.text.unlikely .text.unlikely.*) | |||||
| *(.text.startup .text.startup.*) | |||||
| *(.text .text.*) | |||||
| *(.gnu.linkonce.t.*) | |||||
| } >rom | |||||
| .fini : | |||||
| { | |||||
| KEEP (*(SORT_NONE(.fini))) | |||||
| } >rom | |||||
| PROVIDE (__etext = .); | |||||
| PROVIDE (_etext = .); | |||||
| PROVIDE (etext = .); | |||||
| . = ALIGN(4); | |||||
| .preinit_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__preinit_array_start = .); | |||||
| KEEP (*(.preinit_array)) | |||||
| PROVIDE_HIDDEN (__preinit_array_end = .); | |||||
| } >rom | |||||
| .init_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__init_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) | |||||
| KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) | |||||
| PROVIDE_HIDDEN (__init_array_end = .); | |||||
| } >rom | |||||
| .fini_array : | |||||
| { | |||||
| PROVIDE_HIDDEN (__fini_array_start = .); | |||||
| KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) | |||||
| KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) | |||||
| PROVIDE_HIDDEN (__fini_array_end = .); | |||||
| } >rom | |||||
| .ctors : | |||||
| { | |||||
| /* gcc uses crtbegin.o to find the start of | |||||
| the constructors, so we make sure it is | |||||
| first. Because this is a wildcard, it | |||||
| doesn't matter if the user does not | |||||
| actually link against crtbegin.o; the | |||||
| linker won't look for a file to match a | |||||
| wildcard. The wildcard also means that it | |||||
| doesn't matter which directory crtbegin.o | |||||
| is in. */ | |||||
| KEEP (*crtbegin.o(.ctors)) | |||||
| KEEP (*crtbegin?.o(.ctors)) | |||||
| /* We don't want to include the .ctor section from | |||||
| the crtend.o file until after the sorted ctors. | |||||
| The .ctor section from the crtend file contains the | |||||
| end of ctors marker and it must be last */ | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) | |||||
| KEEP (*(SORT(.ctors.*))) | |||||
| KEEP (*(.ctors)) | |||||
| } >rom | |||||
| .dtors : | |||||
| { | |||||
| KEEP (*crtbegin.o(.dtors)) | |||||
| KEEP (*crtbegin?.o(.dtors)) | |||||
| KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) | |||||
| KEEP (*(SORT(.dtors.*))) | |||||
| KEEP (*(.dtors)) | |||||
| } >rom | |||||
| .dalign : | |||||
| { | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _data = . ); | |||||
| } >rom | |||||
| /* RODATA is usally in ROM, however in volatile configurations this doesn't | |||||
| make a lot of sense. */ | |||||
| .rodata : | |||||
| { | |||||
| *(.rdata) | |||||
| *(.rodata .rodata.*) | |||||
| *(.gnu.linkonce.r.*) | |||||
| } >ram | |||||
| .data : | |||||
| { | |||||
| *(.data .data.*) | |||||
| *(.gnu.linkonce.d.*) | |||||
| . = ALIGN(8); | |||||
| PROVIDE( __global_pointer$ = . + 0x800 ); | |||||
| *(.sdata .sdata.*) | |||||
| *(.gnu.linkonce.s.*) | |||||
| . = ALIGN(8); | |||||
| *(.srodata.cst16) | |||||
| *(.srodata.cst8) | |||||
| *(.srodata.cst4) | |||||
| *(.srodata.cst2) | |||||
| *(.srodata .srodata.*) | |||||
| } >ram | |||||
| . = ALIGN(4); | |||||
| PROVIDE( _edata = . ); | |||||
| PROVIDE( edata = . ); | |||||
| PROVIDE( _fbss = . ); | |||||
| PROVIDE( __bss_start = . ); | |||||
| .bss : | |||||
| { | |||||
| *(.sbss*) | |||||
| *(.gnu.linkonce.sb.*) | |||||
| *(.bss .bss.*) | |||||
| *(.gnu.linkonce.b.*) | |||||
| *(COMMON) | |||||
| . = ALIGN(4); | |||||
| } >ram | |||||
| . = ALIGN(8); | |||||
| PROVIDE( _end = . ); | |||||
| PROVIDE( end = . ); | |||||
| } | |||||
| PROVIDE(_sp = ORIGIN(ram) + LENGTH(ram)); | |||||
| PROVIDE(_heap_end = ORIGIN(ram) + LENGTH(ram)); | |||||