mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Added the "full" demo to the RISC-V_RV32_SiFive_HiFive1_GCC demo - backup check in only as still a work in progress.
This commit is contained in:
parent
71d9450836
commit
d4216903d9
|
@ -25,6 +25,7 @@
|
||||||
<option id="gnu.c.compiler.option.dialect.std.1648189865" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
<option id="gnu.c.compiler.option.dialect.std.1648189865" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
|
||||||
<option id="gnu.c.compiler.option.include.paths.1720192082" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
<option id="gnu.c.compiler.option.include.paths.1720192082" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/full_demo/Common_Demo_Tasks/include}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/RISC-V}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/RISC-V}""/>
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
|
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
|
||||||
|
@ -59,6 +60,16 @@
|
||||||
</tool>
|
</tool>
|
||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
|
<folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480.226910554" name="/" resourcePath="full_demo/Common_Demo_Tasks">
|
||||||
|
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.debug.1460593804" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.debug" unusedChildren="">
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1285988628" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler.1469975065"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.223438273" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler.420742449"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.609362678" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker.558060359"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1231291683" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker.2105463183"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.585811070" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver.424513814"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.376247243" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler.825438707"/>
|
||||||
|
</toolChain>
|
||||||
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
|
|
|
@ -29,6 +29,16 @@
|
||||||
<type>2</type>
|
<type>2</type>
|
||||||
<locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>
|
<locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>
|
||||||
</link>
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>full_demo/Common_Demo_Tasks</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal</locationURI>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>full_demo/Common_Demo_Tasks/include</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/include</locationURI>
|
||||||
|
</link>
|
||||||
</linkedResources>
|
</linkedResources>
|
||||||
<filteredResources>
|
<filteredResources>
|
||||||
<filter>
|
<filter>
|
||||||
|
@ -175,6 +185,42 @@
|
||||||
<arguments>1.0-name-matches-false-false-GCC</arguments>
|
<arguments>1.0-name-matches-false-false-GCC</arguments>
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005814144</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-TimerDemo.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005814150</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-blocktim.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005814159</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-dynamic.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005814167</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-TaskNotify.c</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>1570727992991</id>
|
<id>1570727992991</id>
|
||||||
<name>FreeRTOS_Source/portable/GCC</name>
|
<name>FreeRTOS_Source/portable/GCC</name>
|
||||||
|
@ -193,6 +239,51 @@
|
||||||
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
|
<arguments>1.0-name-matches-false-false-heap_4.c</arguments>
|
||||||
</matcher>
|
</matcher>
|
||||||
</filter>
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005832815</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks/include</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-TimerDemo.h</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005832820</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks/include</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-blocktim.h</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005832824</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks/include</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-dynamic.h</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005832829</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks/include</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-MessageBufferDemo.h</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
|
<filter>
|
||||||
|
<id>1571005832835</id>
|
||||||
|
<name>full_demo/Common_Demo_Tasks/include</name>
|
||||||
|
<type>5</type>
|
||||||
|
<matcher>
|
||||||
|
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||||
|
<arguments>1.0-name-matches-false-false-TaskNotify.h</arguments>
|
||||||
|
</matcher>
|
||||||
|
</filter>
|
||||||
<filter>
|
<filter>
|
||||||
<id>1570728021983</id>
|
<id>1570728021983</id>
|
||||||
<name>FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions</name>
|
<name>FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions</name>
|
||||||
|
|
|
@ -90,8 +90,8 @@
|
||||||
#define configCPU_CLOCK_HZ ( 32768 ) /*QEMU*/
|
#define configCPU_CLOCK_HZ ( 32768 ) /*QEMU*/
|
||||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||||
#define configMAX_PRIORITIES ( 7 )
|
#define configMAX_PRIORITIES ( 7 )
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */
|
||||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) 10000 )
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 )
|
||||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||||
#define configUSE_TRACE_FACILITY 0
|
#define configUSE_TRACE_FACILITY 0
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
@ -113,8 +113,8 @@
|
||||||
/* Software timer definitions. */
|
/* Software timer definitions. */
|
||||||
#define configUSE_TIMERS 1
|
#define configUSE_TIMERS 1
|
||||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||||
#define configTIMER_QUEUE_LENGTH 4
|
#define configTIMER_QUEUE_LENGTH 8
|
||||||
#define configTIMER_TASK_STACK_DEPTH ( 100 )
|
#define configTIMER_TASK_STACK_DEPTH ( 160 )
|
||||||
|
|
||||||
/* Task priorities. Allow these to be overridden. */
|
/* Task priorities. Allow these to be overridden. */
|
||||||
#ifndef uartPRIMARY_PRIORITY
|
#ifndef uartPRIMARY_PRIORITY
|
||||||
|
@ -138,16 +138,4 @@ header file. */
|
||||||
void vAssertCalled( void );
|
void vAssertCalled( void );
|
||||||
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
|
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
|
||||||
|
|
||||||
/* Overwrite some of the stack sizes allocated to various test and demo tasks.
|
|
||||||
Like all task stack sizes, the value is the number of words, not bytes. */
|
|
||||||
#define bktBLOCK_TIME_TASK_STACK_SIZE 100
|
|
||||||
#define notifyNOTIFIED_TASK_STACK_SIZE 120
|
|
||||||
#define priSUSPENDED_RX_TASK_STACK_SIZE 90
|
|
||||||
#define tmrTIMER_TEST_TASK_STACK_SIZE 100
|
|
||||||
#define ebRENDESVOUS_TEST_TASK_STACK_SIZE 100
|
|
||||||
#define ebEVENT_GROUP_SET_BITS_TEST_TASK_STACK_SIZE 115
|
|
||||||
#define genqMUTEX_TEST_TASK_STACK_SIZE 90
|
|
||||||
#define genqGENERIC_QUEUE_TEST_TASK_STACK_SIZE 100
|
|
||||||
#define recmuRECURSIVE_MUTEX_TEST_TASK_STACK_SIZE 90
|
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -191,14 +191,9 @@ extern void vToggleLED( void );
|
||||||
is it the expected value? If it is, toggle the LED. */
|
is it the expected value? If it is, toggle the LED. */
|
||||||
if( ulReceivedValue == ulExpectedValue )
|
if( ulReceivedValue == ulExpectedValue )
|
||||||
{
|
{
|
||||||
write( STDOUT_FILENO, pcPassMessage, strlen( pcPassMessage ) );
|
|
||||||
vToggleLED();
|
vToggleLED();
|
||||||
ulReceivedValue = 0U;
|
ulReceivedValue = 0U;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
write( STDOUT_FILENO, pcFailMessage, strlen( pcFailMessage ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
209
FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/bsp/design.dts
Normal file
209
FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/bsp/design.dts
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "sifive,hifive1-revb";
|
||||||
|
model = "sifive,hifive1-revb";
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
stdout-path = "/soc/serial@10013000:115200";
|
||||||
|
metal,entry = <&spi0 0x10000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
compatible = "sifive,fe310-g000";
|
||||||
|
L6: cpu@0 {
|
||||||
|
clocks = <&hfclk>;
|
||||||
|
compatible = "sifive,rocket0", "riscv";
|
||||||
|
device_type = "cpu";
|
||||||
|
i-cache-block-size = <64>;
|
||||||
|
i-cache-sets = <128>;
|
||||||
|
i-cache-size = <16384>;
|
||||||
|
next-level-cache = <&spi0>;
|
||||||
|
reg = <0>;
|
||||||
|
riscv,isa = "rv32imac";
|
||||||
|
riscv,pmpregions = <8>;
|
||||||
|
sifive,dtim = <&dtim>;
|
||||||
|
status = "okay";
|
||||||
|
timebase-frequency = <1000000>;
|
||||||
|
hardware-exec-breakpoint-count = <4>;
|
||||||
|
hlic: interrupt-controller {
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
compatible = "riscv,cpu-intc";
|
||||||
|
interrupt-controller;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
soc {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
compatible = "sifive,hifive1";
|
||||||
|
ranges;
|
||||||
|
hfxoscin: clock@0 {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <16000000>;
|
||||||
|
};
|
||||||
|
hfxoscout: clock@1 {
|
||||||
|
compatible = "sifive,fe310-g000,hfxosc";
|
||||||
|
clocks = <&hfxoscin>;
|
||||||
|
reg = <&prci 0x4>;
|
||||||
|
reg-names = "config";
|
||||||
|
};
|
||||||
|
hfroscin: clock@2 {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <72000000>;
|
||||||
|
};
|
||||||
|
hfroscout: clock@3 {
|
||||||
|
compatible = "sifive,fe310-g000,hfrosc";
|
||||||
|
clocks = <&hfroscin>;
|
||||||
|
reg = <&prci 0x0>;
|
||||||
|
reg-names = "config";
|
||||||
|
};
|
||||||
|
hfclk: clock@4 {
|
||||||
|
compatible = "sifive,fe310-g000,pll";
|
||||||
|
clocks = <&hfxoscout &hfroscout>;
|
||||||
|
clock-names = "pllref", "pllsel0";
|
||||||
|
reg = <&prci 0x8 &prci 0xc>;
|
||||||
|
reg-names = "config", "divider";
|
||||||
|
clock-frequency = <16000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
lfroscin: clock@5 {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
compatible = "fixed-clock";
|
||||||
|
clock-frequency = <32000000>;
|
||||||
|
};
|
||||||
|
lfclk: clock@6 {
|
||||||
|
compatible = "sifive,fe310-g000,lfrosc";
|
||||||
|
clocks = <&lfroscin>;
|
||||||
|
reg = <&aon 0x70>;
|
||||||
|
reg-names = "config";
|
||||||
|
};
|
||||||
|
|
||||||
|
aon: aon@10000000 {
|
||||||
|
compatible = "sifive,aon0";
|
||||||
|
reg = <0x10000000 0x8000>;
|
||||||
|
reg-names = "mem";
|
||||||
|
};
|
||||||
|
|
||||||
|
prci: prci@10008000 {
|
||||||
|
compatible = "sifive,fe310-g000,prci";
|
||||||
|
reg = <0x10008000 0x8000>;
|
||||||
|
reg-names = "mem";
|
||||||
|
};
|
||||||
|
|
||||||
|
clint: clint@2000000 {
|
||||||
|
compatible = "riscv,clint0";
|
||||||
|
interrupts-extended = <&hlic 3 &hlic 7>;
|
||||||
|
reg = <0x2000000 0x10000>;
|
||||||
|
reg-names = "control";
|
||||||
|
};
|
||||||
|
local-external-interrupts-0 {
|
||||||
|
compatible = "sifive,local-external-interrupts0";
|
||||||
|
interrupt-parent = <&hlic>;
|
||||||
|
interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
|
||||||
|
};
|
||||||
|
plic: interrupt-controller@c000000 {
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
compatible = "riscv,plic0";
|
||||||
|
interrupt-controller;
|
||||||
|
interrupts-extended = <&hlic 11>;
|
||||||
|
reg = <0xc000000 0x4000000>;
|
||||||
|
reg-names = "control";
|
||||||
|
riscv,max-priority = <7>;
|
||||||
|
riscv,ndev = <26>;
|
||||||
|
};
|
||||||
|
global-external-interrupts {
|
||||||
|
compatile = "sifive,global-external-interrupts0";
|
||||||
|
interrupt-parent = <&plic>;
|
||||||
|
interrupts = <1 2 3 4>;
|
||||||
|
};
|
||||||
|
|
||||||
|
debug-controller@0 {
|
||||||
|
compatible = "sifive,debug-011", "riscv,debug-011";
|
||||||
|
interrupts-extended = <&hlic 65535>;
|
||||||
|
reg = <0x0 0x100>;
|
||||||
|
reg-names = "control";
|
||||||
|
};
|
||||||
|
|
||||||
|
maskrom@1000 {
|
||||||
|
reg = <0x1000 0x2000>;
|
||||||
|
reg-names = "mem";
|
||||||
|
};
|
||||||
|
otp@20000 {
|
||||||
|
reg = <0x20000 0x2000 0x10010000 0x1000>;
|
||||||
|
reg-names = "mem", "control";
|
||||||
|
};
|
||||||
|
|
||||||
|
dtim: dtim@80000000 {
|
||||||
|
compatible = "sifive,dtim0";
|
||||||
|
reg = <0x80000000 0x4000>;
|
||||||
|
reg-names = "mem";
|
||||||
|
};
|
||||||
|
|
||||||
|
pwm@10015000 {
|
||||||
|
compatible = "sifive,pwm0";
|
||||||
|
interrupt-parent = <&plic>;
|
||||||
|
interrupts = <23 24 25 26>;
|
||||||
|
reg = <0x10015000 0x1000>;
|
||||||
|
reg-names = "control";
|
||||||
|
};
|
||||||
|
gpio0: gpio@10012000 {
|
||||||
|
compatible = "sifive,gpio0";
|
||||||
|
interrupt-parent = <&plic>;
|
||||||
|
interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>;
|
||||||
|
reg = <0x10012000 0x1000>;
|
||||||
|
reg-names = "control";
|
||||||
|
};
|
||||||
|
uart0: serial@10013000 {
|
||||||
|
compatible = "sifive,uart0";
|
||||||
|
interrupt-parent = <&plic>;
|
||||||
|
interrupts = <5>;
|
||||||
|
reg = <0x10013000 0x1000>;
|
||||||
|
reg-names = "control";
|
||||||
|
clocks = <&hfclk>;
|
||||||
|
pinmux = <&gpio0 0x30000 0x30000>;
|
||||||
|
};
|
||||||
|
spi0: spi@10014000 {
|
||||||
|
compatible = "sifive,spi0";
|
||||||
|
interrupt-parent = <&plic>;
|
||||||
|
interrupts = <6>;
|
||||||
|
reg = <0x10014000 0x1000 0x20000000 0x7A120>;
|
||||||
|
reg-names = "control", "mem";
|
||||||
|
clocks = <&hfclk>;
|
||||||
|
pinmux = <&gpio0 0x0003C 0x0003C>;
|
||||||
|
};
|
||||||
|
i2c0: i2c@10016000 {
|
||||||
|
compatible = "sifive,i2c0";
|
||||||
|
interrupt-parent = <&plic>;
|
||||||
|
interrupts = <52>;
|
||||||
|
reg = <0x10016000 0x1000>;
|
||||||
|
reg-names = "control";
|
||||||
|
};
|
||||||
|
led@0red {
|
||||||
|
compatible = "sifive,gpio-leds";
|
||||||
|
label = "LD0red";
|
||||||
|
gpios = <&gpio0 22>;
|
||||||
|
linux,default-trigger = "none";
|
||||||
|
};
|
||||||
|
led@0green {
|
||||||
|
compatible = "sifive,gpio-leds";
|
||||||
|
label = "LD0green";
|
||||||
|
gpios = <&gpio0 19>;
|
||||||
|
linux,default-trigger = "none";
|
||||||
|
};
|
||||||
|
led@0blue {
|
||||||
|
compatible = "sifive,gpio-leds";
|
||||||
|
label = "LD0blue";
|
||||||
|
gpios = <&gpio0 21>;
|
||||||
|
linux,default-trigger = "none";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,54 @@
|
||||||
|
zero
|
||||||
|
ra
|
||||||
|
sp
|
||||||
|
gp
|
||||||
|
tp
|
||||||
|
t0
|
||||||
|
t1
|
||||||
|
t2
|
||||||
|
fp
|
||||||
|
s1
|
||||||
|
a0
|
||||||
|
a1
|
||||||
|
a2
|
||||||
|
a3
|
||||||
|
a4
|
||||||
|
a5
|
||||||
|
a6
|
||||||
|
a7
|
||||||
|
s2
|
||||||
|
s3
|
||||||
|
s4
|
||||||
|
s5
|
||||||
|
s6
|
||||||
|
s7
|
||||||
|
s8
|
||||||
|
s9
|
||||||
|
s10
|
||||||
|
s11
|
||||||
|
t3
|
||||||
|
t4
|
||||||
|
t5
|
||||||
|
t6
|
||||||
|
pc
|
||||||
|
mstatus
|
||||||
|
misa
|
||||||
|
mie
|
||||||
|
mtvec
|
||||||
|
mscratch
|
||||||
|
mepc
|
||||||
|
mcause
|
||||||
|
mtval
|
||||||
|
mip
|
||||||
|
mvendorid
|
||||||
|
marchid
|
||||||
|
mimpid
|
||||||
|
mhartid
|
||||||
|
tselect
|
||||||
|
tdata1
|
||||||
|
tdata2
|
||||||
|
tdata3
|
||||||
|
dcsr
|
||||||
|
dpc
|
||||||
|
dscratch
|
||||||
|
priv
|
|
@ -26,7 +26,7 @@ SECTIONS
|
||||||
{
|
{
|
||||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
|
||||||
PROVIDE(__stack_size = __stack_size);
|
PROVIDE(__stack_size = __stack_size);
|
||||||
__heap_size = DEFINED(__heap_size) ? __heap_size : 0x400;
|
__heap_size = DEFINED(__heap_size) ? __heap_size : 0x4;
|
||||||
PROVIDE(__metal_boot_hart = 0);
|
PROVIDE(__metal_boot_hart = 0);
|
||||||
PROVIDE(__metal_chicken_bit = 0);
|
PROVIDE(__metal_chicken_bit = 0);
|
||||||
|
|
||||||
|
@ -216,7 +216,8 @@ SECTIONS
|
||||||
. = ALIGN(16);
|
. = ALIGN(16);
|
||||||
metal_segment_stack_begin = .;
|
metal_segment_stack_begin = .;
|
||||||
. += __stack_size;
|
. += __stack_size;
|
||||||
_sp = .;
|
. = ALIGN(16);
|
||||||
|
_sp = .;
|
||||||
PROVIDE(metal_segment_stack_end = .);
|
PROVIDE(metal_segment_stack_end = .);
|
||||||
__freertos_irq_stack_top = .;
|
__freertos_irq_stack_top = .;
|
||||||
} >ram AT>ram :ram
|
} >ram AT>ram :ram
|
||||||
|
|
|
@ -125,7 +125,7 @@ _start:
|
||||||
/* The RISC-V port only uses new-style constructors and destructors. */
|
/* The RISC-V port only uses new-style constructors and destructors. */
|
||||||
la a0, __libc_fini_array
|
la a0, __libc_fini_array
|
||||||
call atexit
|
call atexit
|
||||||
call __libc_init_array
|
/*_RB_ call __libc_init_array */
|
||||||
|
|
||||||
_skip_init:
|
_skip_init:
|
||||||
|
|
||||||
|
|
266
FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/full_demo/RegTest.S
Normal file
266
FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_GCC/full_demo/RegTest.S
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.2.1
|
||||||
|
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
.extern ulRegTest1LoopCounter
|
||||||
|
.extern ulRegTest2LoopCounter
|
||||||
|
|
||||||
|
.global vRegTest1Implementation
|
||||||
|
.global vRegTest2Implementation
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The register check tasks are described in the comments at the top of
|
||||||
|
* main_full.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align( 8 )
|
||||||
|
vRegTest1Implementation:
|
||||||
|
|
||||||
|
/* Fill the core registers with known values. */
|
||||||
|
li x5, 0x5
|
||||||
|
li x6, 0x6
|
||||||
|
li x7, 0x7
|
||||||
|
li x8, 0x8
|
||||||
|
li x9, 0x9
|
||||||
|
li x10, 0xa
|
||||||
|
li x11, 0xb
|
||||||
|
li x12, 0xc
|
||||||
|
li x13, 0xd
|
||||||
|
li x14, 0xe
|
||||||
|
li x15, 0xf
|
||||||
|
li x16, 0x10
|
||||||
|
li x17, 0x11
|
||||||
|
li x18, 0x12
|
||||||
|
li x19, 0x13
|
||||||
|
li x20, 0x14
|
||||||
|
li x21, 0x15
|
||||||
|
li x22, 0x16
|
||||||
|
li x23, 0x17
|
||||||
|
li x24, 0x18
|
||||||
|
li x25, 0x19
|
||||||
|
li x26, 0x1a
|
||||||
|
li x27, 0x1b
|
||||||
|
li x28, 0x1c
|
||||||
|
li x29, 0x1d
|
||||||
|
li x30, 0x1e
|
||||||
|
|
||||||
|
reg1_loop:
|
||||||
|
|
||||||
|
/* Check each register still contains the expected known value.
|
||||||
|
vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation
|
||||||
|
uses x5 as the temporary. */
|
||||||
|
li x31, 0x5
|
||||||
|
bne x31, x5, reg1_error_loop
|
||||||
|
li x31, 0x6
|
||||||
|
bne x31, x6, reg1_error_loop
|
||||||
|
li x31, 0x7
|
||||||
|
bne x31, x7, reg1_error_loop
|
||||||
|
li x31, 0x8
|
||||||
|
bne x31, x8, reg1_error_loop
|
||||||
|
li x31, 0x9
|
||||||
|
bne x31, x9, reg1_error_loop
|
||||||
|
li x31, 0xa
|
||||||
|
bne x31, x10, reg1_error_loop
|
||||||
|
li x31, 0xb
|
||||||
|
bne x31, x11, reg1_error_loop
|
||||||
|
li x31, 0xc
|
||||||
|
bne x31, x12, reg1_error_loop
|
||||||
|
li x31, 0xd
|
||||||
|
bne x31, x13, reg1_error_loop
|
||||||
|
li x31, 0xe
|
||||||
|
bne x31, x14, reg1_error_loop
|
||||||
|
li x31, 0xf
|
||||||
|
bne x31, x15, reg1_error_loop
|
||||||
|
li x31, 0x10
|
||||||
|
bne x31, x16, reg1_error_loop
|
||||||
|
li x31, 0x11
|
||||||
|
bne x31, x17, reg1_error_loop
|
||||||
|
li x31, 0x12
|
||||||
|
bne x31, x18, reg1_error_loop
|
||||||
|
li x31, 0x13
|
||||||
|
bne x31, x19, reg1_error_loop
|
||||||
|
li x31, 0x14
|
||||||
|
bne x31, x20, reg1_error_loop
|
||||||
|
li x31, 0x15
|
||||||
|
bne x31, x21, reg1_error_loop
|
||||||
|
li x31, 0x16
|
||||||
|
bne x31, x22, reg1_error_loop
|
||||||
|
li x31, 0x17
|
||||||
|
bne x31, x23, reg1_error_loop
|
||||||
|
li x31, 0x18
|
||||||
|
bne x31, x24, reg1_error_loop
|
||||||
|
li x31, 0x19
|
||||||
|
bne x31, x25, reg1_error_loop
|
||||||
|
li x31, 0x1a
|
||||||
|
bne x31, x26, reg1_error_loop
|
||||||
|
li x31, 0x1b
|
||||||
|
bne x31, x27, reg1_error_loop
|
||||||
|
li x31, 0x1c
|
||||||
|
bne x31, x28, reg1_error_loop
|
||||||
|
li x31, 0x1d
|
||||||
|
bne x31, x29, reg1_error_loop
|
||||||
|
li x31, 0x1e
|
||||||
|
bne x31, x30, reg1_error_loop
|
||||||
|
|
||||||
|
/* Everything passed, increment the loop counter. */
|
||||||
|
lw x31, ulRegTest1LoopCounterConst
|
||||||
|
lw x30, 0(x31)
|
||||||
|
addi x30, x30, 1
|
||||||
|
sw x30, 0(x31)
|
||||||
|
|
||||||
|
/* Restore clobbered register reading for next loop. */
|
||||||
|
li x30, 0x1e
|
||||||
|
|
||||||
|
/* Yield to increase code coverage. */
|
||||||
|
ecall
|
||||||
|
|
||||||
|
/* Start again. */
|
||||||
|
jal reg1_loop
|
||||||
|
|
||||||
|
reg1_error_loop:
|
||||||
|
/* Jump here if a register contains an uxpected value. This stops the loop
|
||||||
|
counter being incremented so the check task knows an error was found. */
|
||||||
|
ebreak
|
||||||
|
jal reg1_error_loop
|
||||||
|
|
||||||
|
.align( 16 )
|
||||||
|
ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
.align( 8 )
|
||||||
|
vRegTest2Implementation:
|
||||||
|
|
||||||
|
/* Fill the core registers with known values. */
|
||||||
|
li x6, 0x61
|
||||||
|
li x7, 0x71
|
||||||
|
li x8, 0x81
|
||||||
|
li x9, 0x91
|
||||||
|
li x10, 0xa1
|
||||||
|
li x11, 0xb1
|
||||||
|
li x12, 0xc1
|
||||||
|
li x13, 0xd1
|
||||||
|
li x14, 0xe1
|
||||||
|
li x15, 0xf1
|
||||||
|
li x16, 0x20
|
||||||
|
li x17, 0x21
|
||||||
|
li x18, 0x22
|
||||||
|
li x19, 0x23
|
||||||
|
li x20, 0x24
|
||||||
|
li x21, 0x25
|
||||||
|
li x22, 0x26
|
||||||
|
li x23, 0x27
|
||||||
|
li x24, 0x28
|
||||||
|
li x25, 0x29
|
||||||
|
li x26, 0x2a
|
||||||
|
li x27, 0x2b
|
||||||
|
li x28, 0x2c
|
||||||
|
li x29, 0x2d
|
||||||
|
li x30, 0x2e
|
||||||
|
li x31, 0x2f
|
||||||
|
|
||||||
|
Reg2_loop:
|
||||||
|
|
||||||
|
/* Check each register still contains the expected known value.
|
||||||
|
vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation
|
||||||
|
uses x31 as the temporary. */
|
||||||
|
li x5, 0x61
|
||||||
|
bne x5, x6, reg2_error_loop
|
||||||
|
li x5, 0x71
|
||||||
|
bne x5, x7, reg2_error_loop
|
||||||
|
li x5, 0x81
|
||||||
|
bne x5, x8, reg2_error_loop
|
||||||
|
li x5, 0x91
|
||||||
|
bne x5, x9, reg2_error_loop
|
||||||
|
li x5, 0xa1
|
||||||
|
bne x5, x10, reg2_error_loop
|
||||||
|
li x5, 0xb1
|
||||||
|
bne x5, x11, reg2_error_loop
|
||||||
|
li x5, 0xc1
|
||||||
|
bne x5, x12, reg2_error_loop
|
||||||
|
li x5, 0xd1
|
||||||
|
bne x5, x13, reg2_error_loop
|
||||||
|
li x5, 0xe1
|
||||||
|
bne x5, x14, reg2_error_loop
|
||||||
|
li x5, 0xf1
|
||||||
|
bne x5, x15, reg2_error_loop
|
||||||
|
li x5, 0x20
|
||||||
|
bne x5, x16, reg2_error_loop
|
||||||
|
li x5, 0x21
|
||||||
|
bne x5, x17, reg2_error_loop
|
||||||
|
li x5, 0x22
|
||||||
|
bne x5, x18, reg2_error_loop
|
||||||
|
li x5, 0x23
|
||||||
|
bne x5, x19, reg2_error_loop
|
||||||
|
li x5, 0x24
|
||||||
|
bne x5, x20, reg2_error_loop
|
||||||
|
li x5, 0x25
|
||||||
|
bne x5, x21, reg2_error_loop
|
||||||
|
li x5, 0x26
|
||||||
|
bne x5, x22, reg2_error_loop
|
||||||
|
li x5, 0x27
|
||||||
|
bne x5, x23, reg2_error_loop
|
||||||
|
li x5, 0x28
|
||||||
|
bne x5, x24, reg2_error_loop
|
||||||
|
li x5, 0x29
|
||||||
|
bne x5, x25, reg2_error_loop
|
||||||
|
li x5, 0x2a
|
||||||
|
bne x5, x26, reg2_error_loop
|
||||||
|
li x5, 0x2b
|
||||||
|
bne x5, x27, reg2_error_loop
|
||||||
|
li x5, 0x2c
|
||||||
|
bne x5, x28, reg2_error_loop
|
||||||
|
li x5, 0x2d
|
||||||
|
bne x5, x29, reg2_error_loop
|
||||||
|
li x5, 0x2e
|
||||||
|
bne x5, x30, reg2_error_loop
|
||||||
|
li x5, 0x2f
|
||||||
|
bne x5, x31, reg2_error_loop
|
||||||
|
|
||||||
|
/* Everything passed, increment the loop counter. */
|
||||||
|
lw x5, ulRegTest2LoopCounterConst
|
||||||
|
lw x6, 0(x5)
|
||||||
|
addi x6, x6, 1
|
||||||
|
sw x6, 0(x5)
|
||||||
|
|
||||||
|
/* Restore clobbered register reading for next loop. */
|
||||||
|
li x6, 0x61
|
||||||
|
|
||||||
|
/* Start again. */
|
||||||
|
jal Reg2_loop
|
||||||
|
|
||||||
|
reg2_error_loop:
|
||||||
|
/* Jump here if a register contains an uxpected value. This stops the loop
|
||||||
|
counter being incremented so the check task knows an error was found. */
|
||||||
|
ebreak
|
||||||
|
jal reg2_error_loop
|
||||||
|
|
||||||
|
.align( 16 )
|
||||||
|
ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,332 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel V10.2.1
|
||||||
|
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* http://www.FreeRTOS.org
|
||||||
|
* http://aws.amazon.com/freertos
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* NOTE 1: This project provides two demo applications. A simple blinky style
|
||||||
|
* project, and a more comprehensive test and demo application. The
|
||||||
|
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
|
||||||
|
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||||
|
* in main.c. This file implements the comprehensive test and demo version.
|
||||||
|
*
|
||||||
|
* NOTE 2: This file only contains the source code that is specific to the
|
||||||
|
* full demo. Generic functions, such FreeRTOS hook functions, and functions
|
||||||
|
* required to configure the hardware, are defined in main.c.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* main_full() creates all the demo application tasks and software timers, then
|
||||||
|
* starts the scheduler. The web documentation provides more details of the
|
||||||
|
* standard demo application tasks, which provide no particular functionality,
|
||||||
|
* but do provide a good example of how to use the FreeRTOS API.
|
||||||
|
*
|
||||||
|
* In addition to the standard demo tasks, the following tasks and tests are
|
||||||
|
* defined and/or created within this file:
|
||||||
|
*
|
||||||
|
* "Reg test" tasks - These fill both the core registers with known values, then
|
||||||
|
* check that each register maintains its expected value for the lifetime of the
|
||||||
|
* task. Each task uses a different set of values. The reg test tasks execute
|
||||||
|
* with a very low priority, so get preempted very frequently. A register
|
||||||
|
* containing an unexpected value is indicative of an error in the context
|
||||||
|
* switching mechanism.
|
||||||
|
*
|
||||||
|
* "Check" task - The check executes every three seconds. It checks that all
|
||||||
|
* the standard demo tasks, and the register check tasks, are not only still
|
||||||
|
* executing, but are executing without reporting any errors. If the check task
|
||||||
|
* discovers that a task has either stalled, or reported an error, then it
|
||||||
|
* prints an error message to the UART, otherwise it prints "Pass.".
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* Standard demo application includes. */
|
||||||
|
#include "dynamic.h"
|
||||||
|
#include "blocktim.h"
|
||||||
|
#include "GenQTest.h"
|
||||||
|
#include "recmutex.h"
|
||||||
|
#include "TimerDemo.h"
|
||||||
|
#include "EventGroupsDemo.h"
|
||||||
|
#include "TaskNotify.h"
|
||||||
|
#include "AbortDelay.h"
|
||||||
|
#include "countsem.h"
|
||||||
|
#include "death.h"
|
||||||
|
#include "MessageBufferDemo.h"
|
||||||
|
#include "StreamBufferDemo.h"
|
||||||
|
#include "StreamBufferInterrupt.h"
|
||||||
|
|
||||||
|
/* Priorities for the demo application tasks. */
|
||||||
|
#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||||
|
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
|
||||||
|
|
||||||
|
/* The period of the check task, in ms, converted to ticks using the
|
||||||
|
pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have
|
||||||
|
been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */
|
||||||
|
#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL )
|
||||||
|
#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 500UL )
|
||||||
|
|
||||||
|
/* Parameters that are passed into the register check tasks solely for the
|
||||||
|
purpose of ensuring parameters are passed into tasks correctly. */
|
||||||
|
#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
|
||||||
|
#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
|
||||||
|
|
||||||
|
/* The base period used by the timer test tasks. */
|
||||||
|
#define mainTIMER_TEST_PERIOD ( 50 )
|
||||||
|
|
||||||
|
/* The size of the stack allocated to the check task (as described in the
|
||||||
|
comments at the top of this file. */
|
||||||
|
#define mainCHECK_TASK_STACK_SIZE_WORDS 160
|
||||||
|
|
||||||
|
/* Size of the stacks to allocated for the register check tasks. */
|
||||||
|
#define mainREG_TEST_STACK_SIZE_WORDS 90
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by main() to run the full demo (as opposed to the blinky demo) when
|
||||||
|
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
|
||||||
|
*/
|
||||||
|
void main_full( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The check task, as described at the top of this file.
|
||||||
|
*/
|
||||||
|
static void prvCheckTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register check tasks as described at the top of this file. The nature of
|
||||||
|
* these files necessitates that they are written in an assembly file, but the
|
||||||
|
* entry points are kept in the C file for the convenience of checking the task
|
||||||
|
* parameter.
|
||||||
|
*/
|
||||||
|
static void prvRegTestTaskEntry1( void *pvParameters );
|
||||||
|
extern void vRegTest1Implementation( void );
|
||||||
|
static void prvRegTestTaskEntry2( void *pvParameters );
|
||||||
|
extern void vRegTest2Implementation( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tick hook used by the full demo, which includes code that interacts with
|
||||||
|
* some of the tests.
|
||||||
|
*/
|
||||||
|
void vFullDemoTickHook( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The following two variables are used to communicate the status of the
|
||||||
|
register check tasks to the check task. If the variables keep incrementing,
|
||||||
|
then the register check tasks have not discovered any errors. If a variable
|
||||||
|
stops incrementing, then an error has been found. */
|
||||||
|
uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
|
||||||
|
volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter;
|
||||||
|
volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void main_full( void )
|
||||||
|
{
|
||||||
|
/* Start all the other standard demo/test tasks. They have no particular
|
||||||
|
functionality, but do demonstrate how to use the FreeRTOS API and test the
|
||||||
|
kernel port. */
|
||||||
|
vCreateBlockTimeTasks();
|
||||||
|
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
|
||||||
|
vStartDynamicPriorityTasks();
|
||||||
|
// vStartMessageBufferTasks( configMINIMAL_STACK_SIZE );
|
||||||
|
vStartTaskNotifyTask();
|
||||||
|
|
||||||
|
/* Create the register check tasks, as described at the top of this file.
|
||||||
|
Use xTaskCreateStatic() to create a task using only statically allocated
|
||||||
|
memory. */
|
||||||
|
xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */
|
||||||
|
"Reg1", /* The name of the task. */
|
||||||
|
mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */
|
||||||
|
mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */
|
||||||
|
tskIDLE_PRIORITY, /* Priority of the task. */
|
||||||
|
NULL ); /* Can be used to pass out a handle to the created task. */
|
||||||
|
xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Create the task that performs the 'check' functionality, as described at
|
||||||
|
the top of this file. */
|
||||||
|
xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Start the scheduler. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/* If all is well, the scheduler will now be running, and the following
|
||||||
|
line will never be reached. If the following line does execute, then
|
||||||
|
there was insufficient FreeRTOS heap memory available for the Idle and/or
|
||||||
|
timer tasks to be created. See the memory management section on the
|
||||||
|
FreeRTOS web site for more details on the FreeRTOS heap
|
||||||
|
http://www.freertos.org/a00111.html. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
volatile uint32_t ulCheckTaskCycles = 0;
|
||||||
|
static volatile TaskStatus_t xTaskStatus[ 15 ];
|
||||||
|
static void prvCheckTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
|
||||||
|
TickType_t xLastExecutionTime;
|
||||||
|
uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
|
||||||
|
char * const pcPassMessage = ".";
|
||||||
|
char * pcStatusMessage = pcPassMessage;
|
||||||
|
extern void vToggleLED( void );
|
||||||
|
|
||||||
|
/* Just to stop compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
|
||||||
|
works correctly. */
|
||||||
|
xLastExecutionTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
/* Cycle for ever, delaying then checking all the other tasks are still
|
||||||
|
operating without error. The onboard LED is toggled on each iteration.
|
||||||
|
If an error is detected then the delay period is decreased from
|
||||||
|
mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
|
||||||
|
effect of increasing the rate at which the onboard LED toggles, and in so
|
||||||
|
doing gives visual feedback of the system status. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Delay until it is time to execute again. */
|
||||||
|
vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
|
||||||
|
|
||||||
|
/* Check all the demo tasks (other than the flash tasks) to ensure
|
||||||
|
that they are all still running, and that none have detected an error. */
|
||||||
|
if( xAreDynamicPriorityTasksStillRunning() == pdFALSE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "ERROR: Dynamic priority demo/tests.\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreBlockTimeTestTasksStillRunning() == pdFALSE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "ERROR: Block time demo/tests.\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "ERROR: Timer demo/tests.\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xAreTaskNotificationTasksStillRunning() == pdFALSE )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "ERROR: Task notification demo/tests.\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// if( xAreMessageBufferTasksStillRunning() == pdFALSE )
|
||||||
|
{
|
||||||
|
// pcStatusMessage = "ERROR: Message buffer.\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the register test 1 task is still running. */
|
||||||
|
if( ulLastRegTest1Value == ulRegTest1LoopCounter )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "ERROR: Register test 1.\r\n";
|
||||||
|
}
|
||||||
|
ulLastRegTest1Value = ulRegTest1LoopCounter;
|
||||||
|
|
||||||
|
/* Check that the register test 2 task is still running. */
|
||||||
|
if( ulLastRegTest2Value == ulRegTest2LoopCounter )
|
||||||
|
{
|
||||||
|
pcStatusMessage = "ERROR: Register test 2.\r\n";
|
||||||
|
}
|
||||||
|
ulLastRegTest2Value = ulRegTest2LoopCounter;
|
||||||
|
|
||||||
|
/* Write the status message to the UART and toggle the LED to show the
|
||||||
|
system status if the UART is not connected. */
|
||||||
|
vToggleLED();
|
||||||
|
|
||||||
|
/* If an error has been found then increase the LED toggle rate by
|
||||||
|
increasing the cycle frequency. */
|
||||||
|
if( pcStatusMessage != pcPassMessage )
|
||||||
|
{
|
||||||
|
xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
|
||||||
|
write( STDOUT_FILENO, pcStatusMessage, strlen( pcStatusMessage ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ulCheckTaskCycles++;
|
||||||
|
|
||||||
|
// uxTaskGetSystemState( xTaskStatus, sizeof( xTaskStatus ) / sizeof( TaskStatus_t ), NULL );
|
||||||
|
__asm volatile( "NOP" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRegTestTaskEntry1( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Although the regtest task is written in assembler, its entry point is
|
||||||
|
written in C for convenience of checking the task parameter is being passed
|
||||||
|
in correctly. */
|
||||||
|
if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
|
||||||
|
{
|
||||||
|
/* Start the part of the test that is written in assembler. */
|
||||||
|
vRegTest1Implementation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following line will only execute if the task parameter is found to
|
||||||
|
be incorrect. The check task will detect that the regtest loop counter is
|
||||||
|
not being incremented and flag an error. */
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvRegTestTaskEntry2( void *pvParameters )
|
||||||
|
{
|
||||||
|
/* Although the regtest task is written in assembler, its entry point is
|
||||||
|
written in C for convenience of checking the task parameter is being passed
|
||||||
|
in correctly. */
|
||||||
|
if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
|
||||||
|
{
|
||||||
|
/* Start the part of the test that is written in assembler. */
|
||||||
|
vRegTest2Implementation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following line will only execute if the task parameter is found to
|
||||||
|
be incorrect. The check task will detect that the regtest loop counter is
|
||||||
|
not being incremented and flag an error. */
|
||||||
|
vTaskDelete( NULL );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vFullDemoTickHook( void )
|
||||||
|
{
|
||||||
|
/* Called from vApplicationTickHook() when the project is configured to
|
||||||
|
build the full test/demo applications. */
|
||||||
|
|
||||||
|
/* The full demo includes a software timer demo/test that requires
|
||||||
|
prodding periodically from the tick interrupt. */
|
||||||
|
// vTimerPeriodicISRTests();
|
||||||
|
|
||||||
|
/* Use task notifications from an interrupt. */
|
||||||
|
xNotifyTaskFromISR();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#if 1
|
|
||||||
/*
|
/*
|
||||||
* FreeRTOS Kernel V10.2.1
|
* FreeRTOS Kernel V10.2.1
|
||||||
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
@ -35,7 +34,6 @@
|
||||||
#include <metal/led.h>
|
#include <metal/led.h>
|
||||||
#include <metal/button.h>
|
#include <metal/button.h>
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* This project provides two demo applications. A simple blinky style project,
|
* This project provides two demo applications. A simple blinky style project,
|
||||||
* and a more comprehensive test and demo application. The
|
* and a more comprehensive test and demo application. The
|
||||||
|
@ -56,12 +54,18 @@
|
||||||
|
|
||||||
#warning Also test in QEMU and add instructions above.
|
#warning Also test in QEMU and add instructions above.
|
||||||
|
|
||||||
|
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
|
||||||
|
or 0 to run the more comprehensive test and demo application. */
|
||||||
|
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
|
||||||
|
|
||||||
/* Index to first HART (there is only one). */
|
/* Index to first HART (there is only one). */
|
||||||
#define mainHART_0 0
|
#define mainHART_0 0
|
||||||
|
|
||||||
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
|
/* Register addresses within the PLIC. */
|
||||||
or 0 to run the more comprehensive test and demo application. */
|
#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) )
|
||||||
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1
|
#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) )
|
||||||
|
#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) )
|
||||||
|
#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||||
|
@ -111,8 +115,8 @@ static void prvSetupHardware( void )
|
||||||
struct metal_cpu *pxCPU;
|
struct metal_cpu *pxCPU;
|
||||||
struct metal_interrupt *pxInterruptController;
|
struct metal_interrupt *pxInterruptController;
|
||||||
|
|
||||||
/* Initialise the red LED. */
|
/* Initialise the blue LED. */
|
||||||
pxLED = metal_led_get_rgb( "LD0", "red" );
|
pxLED = metal_led_get_rgb( "LD0", "blue" );
|
||||||
configASSERT( pxLED );
|
configASSERT( pxLED );
|
||||||
metal_led_enable( pxLED );
|
metal_led_enable( pxLED );
|
||||||
metal_led_off( pxLED );
|
metal_led_off( pxLED );
|
||||||
|
@ -123,6 +127,14 @@ struct metal_interrupt *pxInterruptController;
|
||||||
pxInterruptController = metal_cpu_interrupt_controller( pxCPU );
|
pxInterruptController = metal_cpu_interrupt_controller( pxCPU );
|
||||||
configASSERT( pxInterruptController );
|
configASSERT( pxInterruptController );
|
||||||
metal_interrupt_init( pxInterruptController );
|
metal_interrupt_init( pxInterruptController );
|
||||||
|
|
||||||
|
/* Set all interrupt enable bits to 0. */
|
||||||
|
mainPLIC_ENABLE_0 = 0UL;
|
||||||
|
mainPLIC_ENABLE_1 = 0UL;
|
||||||
|
|
||||||
|
/* Clear all pending interrupts. */
|
||||||
|
mainPLIC_PENDING_0 = 0UL;
|
||||||
|
mainPLIC_PENDING_1 = 0UL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -184,15 +196,41 @@ void vApplicationTickHook( void )
|
||||||
|
|
||||||
void vAssertCalled( void )
|
void vAssertCalled( void )
|
||||||
{
|
{
|
||||||
|
static struct metal_led *pxRedLED = NULL;
|
||||||
|
volatile uint32_t ul;
|
||||||
|
|
||||||
taskDISABLE_INTERRUPTS();
|
taskDISABLE_INTERRUPTS();
|
||||||
for( ;; );
|
|
||||||
|
/* Initialise the red LED. */
|
||||||
|
pxRedLED = metal_led_get_rgb( "LD0", "red" );
|
||||||
|
configASSERT( pxRedLED );
|
||||||
|
metal_led_enable( pxRedLED );
|
||||||
|
metal_led_off( pxRedLED );
|
||||||
|
|
||||||
|
/* Flash the red LED to indicate that assert was hit - interrupts are off
|
||||||
|
here to prevent any further tick interrupts or context switches, so the
|
||||||
|
delay is implemented as a crude loop. */
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
for( ul = 0; ul < 0x1ffff; ul++ )
|
||||||
|
{
|
||||||
|
__asm volatile( "nop" );
|
||||||
|
}
|
||||||
|
metal_led_toggle( pxRedLED );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPending0Register = 0UL, ulPending1Register = 0UL;
|
||||||
|
|
||||||
void handle_trap( void )
|
void handle_trap( void )
|
||||||
{
|
{
|
||||||
#warning Not implemented.
|
#warning Not implemented.
|
||||||
|
|
||||||
|
__asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) );
|
||||||
|
__asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) );
|
||||||
|
ulPending0Register = mainPLIC_PENDING_0;
|
||||||
|
ulPending1Register = mainPLIC_PENDING_1;
|
||||||
configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );
|
configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
@ -201,103 +239,13 @@ void vToggleLED( void )
|
||||||
{
|
{
|
||||||
metal_led_toggle( pxLED );
|
metal_led_toggle( pxLED );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *malloc( size_t xSize )
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static void prvSetupTimerInterrupt( void )
|
|
||||||
{
|
{
|
||||||
int rc, up_cnt, dn_cnt;
|
configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );
|
||||||
|
return NULL;
|
||||||
// Setup Timer and its interrupt so we can toggle LEDs on 1s cadence
|
|
||||||
tmr_intr = metal_cpu_timer_interrupt_controller(pxCPU);
|
|
||||||
if (tmr_intr == NULL) {
|
|
||||||
printf("TIMER interrupt controller is null.\n");
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
metal_interrupt_init(tmr_intr);
|
|
||||||
tmr_id = metal_cpu_timer_get_interrupt_id(pxCPU);
|
|
||||||
rc = metal_interrupt_register_handler(tmr_intr, tmr_id, timer_isr, pxCPU);
|
|
||||||
if (rc < 0) {
|
|
||||||
printf("TIMER interrupt handler registration failed\n");
|
|
||||||
return (rc * -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lastly CPU interrupt
|
|
||||||
if (metal_interrupt_enable(pxInterruptController, 0) == -1) {
|
|
||||||
printf("CPU interrupt enable failed\n");
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Red -> Green -> Blue, repeat
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
// Turn on RED
|
|
||||||
wait_for_timer(pxLED);
|
|
||||||
|
|
||||||
// Turn on Green
|
|
||||||
wait_for_timer(led0_green);
|
|
||||||
|
|
||||||
// Turn on Blue
|
|
||||||
wait_for_timer(led0_blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <metal/cpu.h>
|
|
||||||
#include <metal/led.h>
|
|
||||||
#include <metal/button.h>
|
|
||||||
#include <metal/switch.h>
|
|
||||||
|
|
||||||
#define RTC_FREQ 32768
|
|
||||||
|
|
||||||
struct metal_cpu *pxCPU;
|
|
||||||
struct metal_interrupt *pxInterruptController, *tmr_intr;
|
|
||||||
int tmr_id;
|
|
||||||
volatile uint32_t timer_isr_flag;
|
|
||||||
|
|
||||||
|
|
||||||
void timer_isr (int id, void *data) {
|
|
||||||
|
|
||||||
// Disable Timer interrupt
|
|
||||||
metal_interrupt_disable(tmr_intr, tmr_id);
|
|
||||||
|
|
||||||
// Flag showing we hit timer isr
|
|
||||||
timer_isr_flag = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait_for_timer(struct metal_led *which_led) {
|
|
||||||
|
|
||||||
// clear global timer isr flag
|
|
||||||
timer_isr_flag = 0;
|
|
||||||
|
|
||||||
// Turn on desired LED
|
|
||||||
metal_led_on(which_led);
|
|
||||||
|
|
||||||
// Set timer
|
|
||||||
metal_cpu_set_mtimecmp(pxCPU, metal_cpu_get_mtime(pxCPU) + RTC_FREQ);
|
|
||||||
|
|
||||||
// Enable Timer interrupt
|
|
||||||
metal_interrupt_enable(tmr_intr, tmr_id);
|
|
||||||
|
|
||||||
// wait till timer triggers and isr is hit
|
|
||||||
while (timer_isr_flag == 0){};
|
|
||||||
|
|
||||||
timer_isr_flag = 0;
|
|
||||||
|
|
||||||
// Turn off this LED
|
|
||||||
metal_led_off(which_led);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue