Skip to content

Commit

Permalink
[packchk] check if the device's memory attribute startup, uninit, etc…
Browse files Browse the repository at this point in the history
…. are present for all devices #1733 (#1153)
  • Loading branch information
thorstendb-ARM authored Feb 20, 2025
1 parent c14e6f5 commit 5a581a2
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 29 deletions.
21 changes: 21 additions & 0 deletions RTE/_Test/RTE_Components.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

/*
* Auto generated Run-Time-Environment Configuration File
* *** Do not modify ! ***
*
* Project: ''
* Target: 'Test'
*/

#ifndef RTE_COMPONENTS_H
#define RTE_COMPONENTS_H


/*
* Define the Device Header File:
*/
#define CMSIS_device_header "TestDevices.h"



#endif /* RTE_COMPONENTS_H */
3 changes: 3 additions & 0 deletions libs/errlog/include/ErrLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,13 @@ struct MessageEntry {
#define TAG2(tag) VAL("TAG2", tag)
#define TAG3(tag) VAL("TAG3", tag)
#define VALUE(val) VAL("VALUE", val)
#define VALUE2(val) VAL("VALUE2", val)
#define ACCESS2(acc) VAL("ACCESS2", acc)
#define ACCESS(acc) VAL("ACCESS", acc)
#define USAGE2(usage) VAL("USAGE2", usage)
#define USAGE(usage) VAL("USAGE", usage)
#define ATTR(val) VAL("ATTR", val)
#define ATTR2(val) VAL("ATTR2", val)
#define CHR(c) VAL("CHAR", c)
#define RELEASEDATE(date) VAL("RELEASEDATE", date)
#define RELEASEVER(ver) VAL("RELEASEVER", ver)
Expand Down
2 changes: 1 addition & 1 deletion tools/packchk/include/ValidateSemantic.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ValidateSemantic : public Validate
bool TestComponentDependencies();
bool TestApis();
bool CheckForUnsupportedChars(const std::string& name, const std::string& tag, int lineNo);
bool CheckMemory(RteDeviceItem* device);
bool CheckMemories(RteDeviceItem* device);
bool GatherCompilers(RtePackage* pKg);
bool CheckDeviceDescription(RteDeviceItem* device, RteDeviceProperty* processorProperty);
bool FindName(const std::string& name, const std::string& searchName, const std::string& searchExt);
Expand Down
4 changes: 2 additions & 2 deletions tools/packchk/src/PackChk_Msgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ const MsgTable PackChk::msgTable = {
{ "M605", { MsgLevel::LEVEL_WARNING, CRLF_B, "Required Dcore '%NAME%' feature '%NAME2%' not defined" } },
{ "M606", { MsgLevel::LEVEL_WARNING, CRLF_B, "" } },
{ "M607", { MsgLevel::LEVEL_WARNING, CRLF_B, "Tag '%TAG%' does not allow wildcard specification: '%NAME%'" } },
{ "M608", { MsgLevel::LEVEL_WARNING, CRLF_B, "" } },
{ "M609", { MsgLevel::LEVEL_WARNING, CRLF_B, "" } },
{ "M608", { MsgLevel::LEVEL_WARNING, CRLF_B, "Memory '%NAME%' with '%ATTR%'='%VALUE%' must have '%ATTR2%'='%VALUE2%'" } },
{ "M609", { MsgLevel::LEVEL_WARNING, CRLF_B, "Processor '%NAME%': Exact one memory with attribute \"startup=1\" must be configured, but found %NUM%" } },
{ "M610", { MsgLevel::LEVEL_WARNING, CRLF_B, "" } },

};
Expand Down
67 changes: 41 additions & 26 deletions tools/packchk/src/ValidateSemantic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,43 +194,45 @@ bool ValidateSemantic::OutputDepResults(const RteDependencyResult& dependencyRes
* @param device RteDeviceItem to run on
* @return passed / failed
*/
bool ValidateSemantic::CheckMemory(RteDeviceItem* device)
bool ValidateSemantic::CheckMemories(RteDeviceItem* device)
{
string devName = device->GetName();

list<RteDeviceProperty*> processors;
device->GetEffectiveProcessors(processors);
for(auto proc : processors) {
const string& pName = proc->GetName();
for(auto processor : processors) {
const string& pName = processor->GetName();
if(!pName.empty()) {
devName += ":";
devName += pName;
}

LogMsg("M071", NAME(devName), proc->GetLineNumber());
LogMsg("M071", NAME(devName), processor->GetLineNumber());

const list<RteDeviceProperty*>& propGroup = device->GetEffectiveProperties("memory", pName);
if(propGroup.empty()) {
const list<RteDeviceProperty*>& memories = device->GetEffectiveProperties("memory", pName);
if(memories.empty()) {
LogMsg("M312", TAG("memory"), NAME(device->GetName()), device->GetLineNumber());
return false;
}

map<const string, RteDeviceProperty*> propNameCheck;
for(auto prop : propGroup) {
const string& id = prop->GetEffectiveAttribute("id");
const string& name = prop->GetEffectiveAttribute("name");
const string& access = prop->GetEffectiveAttribute("access");
const string& start = prop->GetEffectiveAttribute("start");
const string& size = prop->GetEffectiveAttribute("size");
const string& pname = prop->GetEffectiveAttribute("pname");
int lineNo = prop->GetLineNumber();

string key = name.empty() ? id : name;
map<const string, RteDeviceProperty*> memoryNameCheck;
list<RteDeviceProperty*> rxRegionWithStartup;

for(auto memory : memories) {
int lineNo = memory->GetLineNumber();
const string& id = memory->GetEffectiveAttribute("id");
const string& name = memory->GetEffectiveAttribute("name");
const string& access = memory->GetEffectiveAttribute("access");
const string& start = memory->GetEffectiveAttribute("start");
const string& size = memory->GetEffectiveAttribute("size");
const string& pname = memory->GetEffectiveAttribute("pname");
const string& startup = memory->GetEffectiveAttribute("startup");

string memoryName = name.empty() ? id : name;
if(!pname.empty()) {
key += ":" + pname;
memoryName += ":" + pname;
}

LogMsg("M070", NAME(key), NAME2(devName), lineNo); // Checking Memory '%NAME%' for device '%NAME2%'
LogMsg("M070", NAME(memoryName), NAME2(devName), lineNo); // Checking Memory '%NAME%' for device '%NAME2%'

if(id.empty()) { // new description, where 'name' is just a string and 'access' describes the permissions
if(name.empty() && access.empty()) {
Expand Down Expand Up @@ -262,19 +264,32 @@ bool ValidateSemantic::CheckMemory(RteDeviceItem* device)
LogMsg("M308", TAG("size"), TAG2("memory"), lineNo); // Attribute '%TAG%' missing
}

if(!key.empty()) {
auto propNameCheckIt = propNameCheck.find(key);
if(propNameCheckIt != propNameCheck.end()) {
if(!memoryName.empty()) {
auto propNameCheckIt = memoryNameCheck.find(memoryName);
if(propNameCheckIt != memoryNameCheck.end()) {
RteDeviceProperty* propFound = propNameCheckIt->second;
if(propFound) {
LogMsg("M311", TAG("memory"), NAME(key), LINE(propFound->GetLineNumber()), lineNo);
LogMsg("M311", TAG("memory"), NAME(memoryName), LINE(propFound->GetLineNumber()), lineNo);
}
}
else {
propNameCheck[key] = prop;
memoryNameCheck[memoryName] = memory;
}
}

// Check startup attribute
if(startup == "1") {
rxRegionWithStartup.push_back(memory);
if(access.find_first_of("x") == string::npos) {
LogMsg("M608", NAME(memoryName), ATTR("startup"), VALUE("1"), ATTR2("access"), VALUE2("x"), lineNo);
}
}
}

const int numOfMemories = rxRegionWithStartup.size();
if(!numOfMemories || numOfMemories > 1) {
LogMsg("M609", NAME(devName), NUM(numOfMemories), processor->GetLineNumber());
}
}

return true;
Expand Down Expand Up @@ -562,7 +577,6 @@ bool ValidateSemantic::CheckDeviceDependencies(RteDeviceItem *device, RteProject
int lineNo = device->GetLineNumber();

CheckForUnsupportedChars(mcuName, "Dname", lineNo);
CheckMemory(device);

XmlItem deviceStartup;
deviceStartup.SetAttribute("Cclass", "Device");
Expand Down Expand Up @@ -842,6 +856,7 @@ bool ValidateSemantic::TestMcuDependencies(RtePackage* pKg)
pKg->GetEffectiveDeviceItems(devices);
for(auto device : devices) {
CheckDeviceDependencies(device, rteProject);
CheckMemories(device);
CheckDeviceAttributes(device);
}

Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>

<package schemaVersion="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="PACK.xsd">
<vendor>TestVendor</vendor>
<url>http://www.keil.com/pack/</url>
<name>MemoryAttributes</name>
<description>Test Memory Attributes</description>

<releases>
<release version="1.0.0" date="2025-02-20">
First Release version of Test Memory Attributes.
</release>
</releases>

<keywords>
<!-- keywords for indexing -->
<keyword>ARM</keyword>
</keywords>

<conditions>
<condition id="TestDevices">
<description>Test devices</description>
<require Dvendor="ARM:82" Dname="Test*"/>
</condition>
<condition id="Test ARMCC">
<description>filter for STM32F1xx Value Line Low Density Device and the ARM compiler</description>
<require condition="TestDevices"/>
<require Tcompiler="ARMCC"/>
</condition>
</conditions>


<devices>
<family Dfamily="TestFamily" Dvendor="ARM:82">
<algorithm name="Flash/ARMCMx_512.FLM" start="0x00000000" size="0x00040000" default="1"/>

<!-- ****************************** TestSubFamily ****************************** -->
<subFamily DsubFamily="TestSubFamily">
<compile header="Files/TestDevices.h" define="TESTDEVICES"/>

<description>
The TestSubFamily is ...
</description>

<!-- ****************************** TestDeviceOk ***************************** -->
<device Dname="TestDeviceOk">
<processor Dcore="Cortex-M4" DcoreVersion="r0p1" Dfpu="SP_FPU" Dmpu="MPU" Ddsp="NO_DSP" Dendian="Little-endian" Dclock="204000000"/>
<memory name="Flash" access="rx" start="0x08000000" size="0x00080000" default="1" startup="1" />
<memory name="IRAM1" access="rwx" start="0x10000000" size="0x00010000" default="1" />
<memory name="IRAM2" access="rwx" start="0x20000000" size="0x00010000" default="0" />
</device>

<!-- ****************************** TestDeviceNOk ***************************** -->
<device Dname="TestDeviceNOk">
<processor Dcore="Cortex-M4" DcoreVersion="r0p1" Dfpu="SP_FPU" Dmpu="MPU" Ddsp="NO_DSP" Dendian="Little-endian" Dclock="204000000"/>
<memory name="Flash" access="rx" start="0x08000000" size="0x00080000" default="1" startup="1" />
<memory name="Flash2" access="rx" start="0x09000000" size="0x00080000" default="1" startup="1" />
<memory name="IRAM1" access="rwx" start="0x10000000" size="0x00010000" default="1" />
<memory name="IRAM2" access="rwx" start="0x20000000" size="0x00010000" default="0" />
</device>

<!-- ****************************** TestDeviceNOk2 ***************************** -->
<device Dname="TestDeviceNOk2">
<processor Dcore="Cortex-M4" DcoreVersion="r0p1" Dfpu="SP_FPU" Dmpu="MPU" Ddsp="NO_DSP" Dendian="Little-endian" Dclock="204000000"/>
<memory name="Flash" access="rw" start="0x08000000" size="0x00080000" default="1" startup="1" />
<memory name="IRAM1" access="rwx" start="0x10000000" size="0x00010000" default="1" />
<memory name="IRAM2" access="rwx" start="0x20000000" size="0x00010000" default="0" />
</device>

<!-- ****************************** TestDeviceNOk3 ***************************** -->
<device Dname="TestDeviceNOk3">
<processor Dcore="Cortex-M4" DcoreVersion="r0p1" Dfpu="SP_FPU" Dmpu="MPU" Ddsp="NO_DSP" Dendian="Little-endian" Dclock="204000000"/>
<memory name="Flash" access="rwx" start="0x08000000" size="0x00080000" default="1" startup="0" />
<memory name="IRAM1" access="rwx" start="0x10000000" size="0x00010000" default="1" />
<memory name="IRAM2" access="rwx" start="0x20000000" size="0x00010000" default="0" />
</device>

<!-- ****************************** TestDeviceNOk4 ***************************** -->
<device Dname="TestDeviceNOk4">
<processor Dcore="Cortex-M4" DcoreVersion="r0p1" Dfpu="SP_FPU" Dmpu="MPU" Ddsp="NO_DSP" Dendian="Little-endian" Dclock="204000000"/>
<memory name="Flash" start="0x08000000" size="0x00080000" default="1" startup="1" />
<memory name="IRAM1" access="rwx" size="0x00010000" default="1" />
<memory name="IRAM2" access="rwx" default="0" />
</device>

</subFamily>
</family>
</devices>

<components>
<component Cclass="Device" Cgroup="Startup" Cversion="1.0.0" condition="TestDevices">
<description>System Startup for STMicroelectronics STM32F1xx device series</description>
<files>
<file category="include" name="Files/"/>
<file category="source" name="Files/startup_Test.s" attr="config" version="1.0.0" condition="Test ARMCC"/>
<file category="source" name="Files/system_Test.c" attr="config" version="1.0.0" />
</files>
</component>
</components>

</package>
43 changes: 43 additions & 0 deletions tools/packchk/test/integtests/src/PackChkIntegTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,49 @@ TEST_F(PackChkIntegTests, CheckFileAttributeDeprecated) {
}
}

// Validate invalid file path (file is directory)
TEST_F(PackChkIntegTests, CheckMemoryAttributes) {
const char* argv[3];

const string& pdscFile = PackChkIntegTestEnv::localtestdata_dir +
"/MemoryAttributes/TestVendor.MemoryAttributes.pdsc";
ASSERT_TRUE(RteFsUtils::Exists(pdscFile));

argv[0] = (char*)"";
argv[1] = (char*)pdscFile.c_str();
argv[2] = (char*)"--disable-validation";

PackChk packChk;
EXPECT_EQ(1, packChk.Check(3, argv, nullptr));

auto errMsgs = ErrLog::Get()->GetLogMessages();
int M608_foundCnt = 0;
int M609_foundCnt = 0;
int M308_foundCnt = 0;
int M309_foundCnt = 0;
for (const string& msg : errMsgs) {
size_t s;
if ((s = msg.find("M608")) != string::npos) {
M608_foundCnt++;
}
if ((s = msg.find("M609")) != string::npos) {
M609_foundCnt++;
}
if ((s = msg.find("M308")) != string::npos) {
M308_foundCnt++;
}
if ((s = msg.find("M309")) != string::npos) {
M309_foundCnt++;
}

}

if (M608_foundCnt != 2 || M609_foundCnt != 2 || M308_foundCnt != 3 || M309_foundCnt != 1) {
FAIL() << "error: missing message(s) on check device memories";
}
}


TEST_F(PackChkIntegTests, CheckConditionComponentDependency_Pos) {
const char* argv[7];

Expand Down

0 comments on commit 5a581a2

Please sign in to comment.