22using System ;
33using System . Collections . Generic ;
44using System . IO ;
5+ using System . IO . Compression ;
56using System . Linq ;
67using System . Text ;
78using System . Text . RegularExpressions ;
9+ using System . Xml ;
810
911namespace RenesasToolchainManager
1012{
@@ -14,24 +16,26 @@ struct RenamedFile
1416 {
1517 public string SourceFileFormat ;
1618 public string TargetFileName ;
19+ public bool MakeWeakFunctions ;
1720
18- public RenamedFile ( string sourceFileFormat , string targetFileName )
21+ public RenamedFile ( string sourceFileFormat , string targetFileName , bool makeWeakFunctions = false )
1922 {
2023 SourceFileFormat = sourceFileFormat ;
2124 TargetFileName = targetFileName ;
25+ MakeWeakFunctions = makeWeakFunctions ;
2226 }
2327 }
2428
2529 static RenamedFile [ ] RenamedFiles = new [ ]
2630 {
27- new RenamedFile ( @"IntPRG\{0}.c" , "inthandler.c" ) ,
31+ new RenamedFile ( @"IntPRG\{0}.c" , "inthandler.c" , true ) ,
2832 new RenamedFile ( @"iodefine\{0}.h" , "iodefine.h" ) ,
2933 new RenamedFile ( @"iodefine_ext\{0}.h" , "iodefine_ext.h" ) ,
3034 new RenamedFile ( @"vect\{0}.h" , "interrupt_handlers.h" ) ,
3135 new RenamedFile ( @"vecttbl\{0}.c" , "vects.c" ) ,
3236 } ;
3337
34- public static MCU GenerateMCUDefinition ( string bspDir , string linkerScript , string generatorResourceDir , string target )
38+ public static MCU GenerateMCUDefinition ( string bspDir , string linkerScript , string generatorResourceDir , string target , string debugComponentDir )
3539 {
3640 string mcuName = Path . GetFileNameWithoutExtension ( linkerScript ) . TrimStart ( 'D' ) ;
3741 string copiedFilesDir = Path . Combine ( bspDir , "DeviceFiles" , mcuName ) ;
@@ -47,19 +51,35 @@ public static MCU GenerateMCUDefinition(string bspDir, string linkerScript, stri
4751 memorySizes [ m . Groups [ 1 ] . Value ] = int . Parse ( m . Groups [ 3 ] . Value ) ;
4852 }
4953
50- List < string > sources = new List < string > ( ) , headers = new List < string > ( ) ;
54+ List < string > headers = new List < string > ( ) ;
5155
5256 foreach ( var rf in RenamedFiles )
5357 {
5458 string file = Path . Combine ( generatorResourceDir , string . Format ( rf . SourceFileFormat , mcuName ) ) ;
55- if ( File . Exists ( file ) )
59+ if ( ! File . Exists ( file ) )
5660 {
57- File . Copy ( file , Path . Combine ( copiedFilesDir , rf . TargetFileName ) ) ;
58- if ( file . EndsWith ( ".h" , StringComparison . InvariantCultureIgnoreCase ) )
59- headers . Add ( $ "$$SYS:BSP_ROOT$$/DeviceFiles/{ mcuName } /{ rf . TargetFileName } ") ;
60- else
61- sources . Add ( $ "$$SYS:BSP_ROOT$$/DeviceFiles/{ mcuName } /{ rf . TargetFileName } ") ;
61+ Directory . Delete ( copiedFilesDir , true ) ;
62+ return null ;
6263 }
64+
65+ var lines = File . ReadAllLines ( file ) ;
66+ if ( rf . MakeWeakFunctions )
67+ {
68+ Regex rgFunc = new Regex ( "void[ \t ]+(INT_[a-zA-Z0-9_]+)[ \t ]*\\ (void\\ )" ) ;
69+ for ( int i = 0 ; i < lines . Length ; i ++ )
70+ {
71+ var m = rgFunc . Match ( lines [ i ] ) ;
72+ if ( m . Success )
73+ {
74+ lines [ i ] = lines [ i ] . Substring ( 0 , m . Groups [ 1 ] . Index ) + "__attribute__((weak)) " + lines [ i ] . Substring ( m . Groups [ 1 ] . Index ) ;
75+ }
76+ }
77+ }
78+
79+ File . WriteAllLines ( Path . Combine ( copiedFilesDir , rf . TargetFileName ) , lines ) ;
80+
81+ if ( rf . TargetFileName . EndsWith ( ".h" ) )
82+ headers . Add ( $ "$$SYS:BSP_ROOT$$/DeviceFiles/{ mcuName } /rf.TargetFileName") ;
6383 }
6484
6585 var mcu = new MCU
@@ -73,22 +93,109 @@ public static MCU GenerateMCUDefinition(string bspDir, string linkerScript, stri
7393 LDFLAGS = "-nostartfiles -Wl,-e_PowerON_Reset" ,
7494 COMMONFLAGS = "$$com.sysprogs.renesas.doubles$$ $$com.sysprogs.renesas.core$$" ,
7595 } ,
76- AdditionalSourceFiles = sources . ToArray ( ) ,
77- AdditionalHeaderFiles = headers . ToArray ( ) ,
7896 AdditionalSourcesRequiredForTesting = true ,
97+ AdditionalHeaderFiles = headers . ToArray ( )
7998 } ;
8099
100+ string peripheralFile = Path . Combine ( debugComponentDir , "IoFiles" , mcuName + ".sfrx" ) ;
101+ if ( File . Exists ( peripheralFile ) )
102+ {
103+ var doc = new XmlDocument ( ) ;
104+ doc . Load ( peripheralFile ) ;
105+
106+ MCUDefinition definition = new MCUDefinition
107+ {
108+ MCUName = mcuName ,
109+ RegisterSets = doc . DocumentElement . SelectNodes ( "moduletable/module" ) . OfType < XmlElement > ( ) . Select ( TransformRegisterSet ) . Where ( s => s != null ) . ToArray ( )
110+ } ;
111+
112+ using ( var fs = new FileStream ( Path . Combine ( bspDir , "DeviceDefinitions" , mcuName + ".xml.gz" ) , FileMode . Create , FileAccess . Write ) )
113+ using ( var gs = new GZipStream ( fs , CompressionMode . Compress ) )
114+ XmlTools . SaveObjectToStream ( definition , gs ) ;
115+
116+ mcu . MCUDefinitionFile = $ "DeviceDefinitions/{ mcuName } .xml";
117+ }
118+
81119 memorySizes . TryGetValue ( "ROM" , out mcu . FLASHSize ) ;
82120 memorySizes . TryGetValue ( "RAM" , out mcu . RAMSize ) ;
83121 return mcu ;
84122 }
85123
124+ static int TryParseAddress ( string addrString )
125+ {
126+ if ( addrString ? . StartsWith ( "0x" ) != true || ! int . TryParse ( addrString . Substring ( 2 ) , System . Globalization . NumberStyles . HexNumber , null , out var addr ) )
127+ return 0 ;
128+ return addr ;
129+ }
130+
131+ private static HardwareRegisterSet TransformRegisterSet ( XmlElement el )
132+ {
133+ var name = el . GetAttribute ( "name" ) ;
134+ if ( name == null )
135+ return null ;
136+
137+ return new HardwareRegisterSet
138+ {
139+ UserFriendlyName = name ,
140+ Registers = el . SelectNodes ( "register" ) . OfType < XmlElement > ( ) . SelectMany ( r => new [ ] { r } . Concat ( r . SelectNodes ( "register" ) . OfType < XmlElement > ( ) ) ) . Select ( r =>
141+ {
142+ var regSize = r . GetAttribute ( "size" ) ;
143+ var regAccess = r . GetAttribute ( "access" ) ;
144+
145+ var reg = new HardwareRegister { Name = r . GetAttribute ( "name" ) , Address = r . GetAttribute ( "address" ) } ;
146+ if ( reg . Name == null || reg . Address == null )
147+ return null ;
148+
149+ switch ( regSize ?? "" )
150+ {
151+ case "B" :
152+ reg . SizeInBits = 8 ;
153+ break ;
154+ case "W" :
155+ reg . SizeInBits = 16 ;
156+ break ;
157+ default :
158+ return null ;
159+ }
160+
161+ switch ( regAccess )
162+ {
163+ case "R" :
164+ reg . ReadOnly = true ;
165+ break ;
166+ case "RW" :
167+ reg . ReadOnly = false ;
168+ break ;
169+ default :
170+ return null ;
171+ }
172+
173+ reg . SubRegisters = r . SelectNodes ( "bitfield" ) . OfType < XmlElement > ( ) . Select ( TransformSubregister ) . Where ( sr => sr != null ) . ToArray ( ) ;
174+ return reg ;
175+ } ) . Where ( r => r != null ) . ToArray ( )
176+ } ;
177+ }
178+
179+ private static HardwareSubRegister TransformSubregister ( XmlElement el )
180+ {
181+ string name = el . GetAttribute ( "name" ) ;
182+ if ( ! int . TryParse ( el . GetAttribute ( "bit" ) , out int bit ) )
183+ return null ;
184+ if ( ! int . TryParse ( el . GetAttribute ( "bitlength" ) , out int bitlength ) )
185+ return null ;
186+
187+ return new HardwareSubRegister { FirstBit = bit , SizeInBits = bitlength , Name = name } ;
188+ }
189+
86190 public static MCUFamily GenerateMCUFamilyDefinition ( string target )
87191 {
88192 return new MCUFamily
89193 {
90194 ID = target ,
91- AdditionalSourceFiles = new [ ] { "$$SYS:BSP_ROOT$$/start.S" } ,
195+ CompilationFlags = new ToolFlags
196+ {
197+ PreprocessorMacros = new [ ] { "__GCC__" , "$$com.sysprogs.renesas.cppapp$$" }
198+ } ,
92199 ConfigurableProperties = new PropertyList
93200 {
94201 PropertyGroups = new List < PropertyGroup >
@@ -150,12 +257,38 @@ public static MCUFamily GenerateMCUFamilyDefinition(string target)
150257 } ,
151258 } ,
152259 DefaultEntryIndex = 2
260+ } ,
261+
262+ new PropertyEntry . Boolean
263+ {
264+ UniqueID = "com.sysprogs.renesas.cppapp" ,
265+ Name = "Project Contains C++ Sources" ,
266+ ValueForTrue = "CPPAPP"
153267 }
154268 }
155269 }
156270 }
157271 }
158272 } ;
159273 }
274+
275+ public static EmbeddedFramework GenerateStartupFilesFramework ( string target )
276+ {
277+ return new EmbeddedFramework
278+ {
279+ ID = "com.sysprogs.renesas.startupfiles" ,
280+ UserFriendlyName = "Default Startup/Interrupt Files" ,
281+ DefaultEnabled = true ,
282+ AdditionalSourceFiles = RenamedFiles
283+ . Where ( rf => ! rf . TargetFileName . EndsWith ( ".h" ) )
284+ . Select ( rf => $ "$$SYS:BSP_ROOT$$/DeviceFiles/$$SYS:MCU_ID$$/{ rf . TargetFileName } ")
285+ . Concat ( new [ ]
286+ {
287+ "$$SYS:BSP_ROOT$$/start.S" ,
288+ "$$SYS:BSP_ROOT$$/stubs.c" ,
289+ } )
290+ . ToArray ( )
291+ } ;
292+ }
160293 }
161294}
0 commit comments