/*******************************************************************************
* Copyright (c) 2015 ARM Ltd. and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* ARM Ltd and ARM Germany GmbH - Initial API and implementation
*******************************************************************************/
package com.arm.cmsis.pack.build.armcc;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.runtime.CoreException;
import com.arm.cmsis.pack.build.IMemorySettings;
import com.arm.cmsis.pack.build.settings.ILinkerScriptGenerator;
import com.arm.cmsis.pack.common.CmsisConstants;
import com.arm.cmsis.pack.data.ICpMemory;
/**
* Scatter file generator for ARMCC 5 compiler
*/
public class ScatterFileGenerator implements ILinkerScriptGenerator {
final static protected String BAR_COMMENT = "; *************************************************************"; //$NON-NLS-1$
final static protected String HEAD_COMMENT = "; ** Scatter-Loading Description File generated by RTE CMSIS Plug-in **";//$NON-NLS-1$
final static protected String _UNINIT_ = " UNINIT "; //$NON-NLS-1$
final static protected String SPACE = " "; //$NON-NLS-1$
final static protected String SCT = "sct"; //$NON-NLS-1$
StringBuilder sb;
@Override
public String generate(IMemorySettings memorySetttings) throws CoreException {
if(memorySetttings == null)
return null;
sb = new StringBuilder(BAR_COMMENT);
sb.append(System.lineSeparator());
sb.append(HEAD_COMMENT);
sb.append(System.lineSeparator());
sb.append(BAR_COMMENT);
sb.append(System.lineSeparator());
sb.append(System.lineSeparator());
if( !generateStartupRom(memorySetttings))
return null;
generateRemainingRoms(memorySetttings);
sb.append(System.lineSeparator());
return sb.toString();
}
protected boolean generateStartupRom(IMemorySettings memorySetttings) {
String id = memorySetttings.getStartupRegionId();
ICpMemory m = memorySetttings.getRegion(id);
if(m == null)
return false;
generateAddressLine("LR_", id, " { ; load region size_region", m, false); //$NON-NLS-1$//$NON-NLS-2$
generateAddressLine(" ER_", id, " { ; load address = execution address", m, false); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(" *.o (RESET, +First)").append(System.lineSeparator()); //$NON-NLS-1$
sb.append(" *(InRoot$$Sections)").append(System.lineSeparator()); //$NON-NLS-1$
sb.append(" .ANY (+RO)").append(System.lineSeparator()); //$NON-NLS-1$
sb.append(" }").append(System.lineSeparator()); //$NON-NLS-1$
generateDefaultRams(memorySetttings);
sb.append("}").append(System.lineSeparator()); //$NON-NLS-1$
return true;
}
protected void generateDefaultRams(IMemorySettings memorySetttings) {
Map<String, ICpMemory> entries = memorySetttings.getRegions();
for(Entry<String, ICpMemory> e : entries.entrySet()) {
String id = e.getKey();
ICpMemory m = e.getValue();
if(!m.isRAM())
continue;
if(!m.isDefault())
continue;
generateAddressLine(" RW_", id, " {", m, true); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(" .ANY (+RW +ZI)").append(System.lineSeparator()); //$NON-NLS-1$
sb.append(" }").append(System.lineSeparator()); //$NON-NLS-1$
}
}
protected void generateRemainingRoms(IMemorySettings memorySetttings) {
Map<String, ICpMemory> entries = memorySetttings.getRegions();
for(Entry<String, ICpMemory> e : entries.entrySet()) {
String id = e.getKey();
if(id.equals(memorySetttings.getStartupRegionId()))
continue;
ICpMemory m = e.getValue();
if(!m.isROM())
continue;
generateAddressLine("LR_", id, " {", m, false); //$NON-NLS-1$//$NON-NLS-2$
generateAddressLine(" ER_", id, " { ; load address = execution address", m, false); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(" .ANY (+RO)").append(System.lineSeparator()); //$NON-NLS-1$
sb.append(" }").append(System.lineSeparator()); //$NON-NLS-1$
sb.append("}").append(System.lineSeparator()); //$NON-NLS-1$
}
}
protected void generateAddressLine(String prefix, String id, String suffix, ICpMemory m, boolean bRam){
String start = m.getAttribute(CmsisConstants.START);
String size = m.getAttribute(CmsisConstants.SIZE);
String uninit = (bRam && m.attributes().getAttributeAsBoolean(CmsisConstants.INIT, false)) ? _UNINIT_ : SPACE;
sb.append(prefix);
sb.append(id);
sb.append(SPACE);
sb.append(start);
sb.append(uninit);
sb.append(size);
sb.append(suffix);
sb.append(System.lineSeparator());
}
@Override
public String getFileExtension() {
return SCT;
}
}