Skip to content

Commit cd9bc50

Browse files
committed
drivertest: add arm-m signal through isr case
Signed-off-by: buxiasen <[email protected]>
1 parent ce217b8 commit cd9bc50

File tree

3 files changed

+237
-0
lines changed

3 files changed

+237
-0
lines changed

testing/drivertest/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,34 @@ if(CONFIG_TESTING_DRIVER_TEST)
371371
cmocka
372372
SRCS
373373
drivertest_mps2.c)
374+
375+
nuttx_add_application(
376+
NAME
377+
cmocka_driver_mps2_zerointerrupt
378+
PRIORITY
379+
${CONFIG_TESTING_DRIVER_TEST_PRIORITY}
380+
STACKSIZE
381+
${CONFIG_TESTING_DRIVER_TEST_STACKSIZE}
382+
MODULE
383+
${CONFIG_TESTING_DRIVER_TEST}
384+
DEPENDS
385+
cmocka
386+
SRCS
387+
drivertest_mps2_zerointerrupt.c)
388+
389+
nuttx_add_application(
390+
NAME
391+
cmocka_driver_mps2_isr_signal
392+
PRIORITY
393+
${CONFIG_TESTING_DRIVER_TEST_PRIORITY}
394+
STACKSIZE
395+
${CONFIG_TESTING_DRIVER_TEST_STACKSIZE}
396+
MODULE
397+
${CONFIG_TESTING_DRIVER_TEST}
398+
DEPENDS
399+
cmocka
400+
SRCS
401+
drivertest_mps2_isr_signal.c)
374402
endif()
375403

376404
if(CONFIG_PM)

testing/drivertest/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ MAINSRC += drivertest_mps2.c
137137
PROGNAME += cmocka_driver_mps2
138138
MAINSRC += drivertest_mps2_zerointerrupt.c
139139
PROGNAME += cmocka_driver_mps2_zerointerrupt
140+
MAINSRC += drivertest_mps2_isr_signal.c
141+
PROGNAME += cmocka_driver_mps2_isr_signal
140142
endif
141143
endif
142144

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/****************************************************************************
2+
* apps/testing/drivertest/drivertest_mps2_isr_signal.c
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one or more
5+
* contributor license agreements. See the NOTICE file distributed with
6+
* this work for additional information regarding copyright ownership. The
7+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance with the
9+
* License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
* License for the specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
****************************************************************************/
20+
21+
/****************************************************************************
22+
* Included Files
23+
****************************************************************************/
24+
25+
#include <nuttx/nuttx.h>
26+
#include <stdbool.h>
27+
#include <stdint.h>
28+
#include <stdio.h>
29+
#include <stdlib.h>
30+
#include <stdarg.h>
31+
#include <stddef.h>
32+
#include <setjmp.h>
33+
#include <string.h>
34+
#include <cmocka.h>
35+
#include <signal.h>
36+
37+
#include <nuttx/arch.h>
38+
#include <nuttx/irq.h>
39+
#include <nuttx/semaphore.h>
40+
#include <nuttx/serial/uart_cmsdk.h>
41+
42+
#include <pthread.h>
43+
44+
/****************************************************************************
45+
* Pre-processor Definitions
46+
****************************************************************************/
47+
48+
#define CONFIG_TEST_ISR_SIGNAL_US 10000
49+
50+
#define MPS2_ADDR2REG_PTR(base, off) (uint32_t*)((uint32_t*)(base) + (off))
51+
#define MPS2_IRQ_FROMBASE(base, off) ((base) + (off))
52+
53+
/* https://developer.arm.com/documentation/101104/0200/programmers-model/
54+
* base-element/cmsdk-timer
55+
*/
56+
57+
#define MPS_TIMER_CTRL_OFFSET 0
58+
#define MPS_TIMER_VALUE_OFFSET 1
59+
#define MPS_TIMER_RELOAD_OFFSET 2
60+
#define MPS_TIMER_CLEAR_OFFSET 3
61+
62+
#define MPS_TIMER_CTRL_ENABLE (1<<0)
63+
#define MPS_TIMER_CTRL_IE (1<<3)
64+
65+
static_assert(NVIC_SYSH_PRIORITY_DEFAULT == 0x80, "prio");
66+
67+
/****************************************************************************
68+
* Private Types
69+
****************************************************************************/
70+
71+
typedef struct mps2_an500_timer_s
72+
{
73+
volatile uint32_t *reload;
74+
volatile uint32_t *ctrl;
75+
volatile uint32_t *clear;
76+
pid_t pid;
77+
int irq;
78+
} mps2_an500_timer_t;
79+
80+
/****************************************************************************
81+
* Private Functions Prototypes
82+
****************************************************************************/
83+
84+
static int timer_irq_handle(int irq, void *context, void *arg);
85+
86+
/****************************************************************************
87+
* Private Data
88+
****************************************************************************/
89+
90+
static mps2_an500_timer_t timer[2];
91+
92+
static const int armv7m_gpio_base = 16;
93+
94+
/****************************************************************************
95+
* Private Functions
96+
****************************************************************************/
97+
98+
static void mps_timer_init(void)
99+
{
100+
static const uint32_t timerbase[] =
101+
{
102+
0x40000000, 0x40001000
103+
};
104+
105+
static const int timerirq[] =
106+
{
107+
8, 9
108+
};
109+
110+
static const int timer_irq_prio[] =
111+
{
112+
0x80, 0xa0
113+
};
114+
115+
for (int i = 0; i < 2; i++)
116+
{
117+
mps2_an500_timer_t *t = &timer[i];
118+
119+
t->reload = MPS2_ADDR2REG_PTR(timerbase[i], MPS_TIMER_RELOAD_OFFSET);
120+
t->ctrl = MPS2_ADDR2REG_PTR(timerbase[i], MPS_TIMER_CTRL_OFFSET);
121+
t->clear = MPS2_ADDR2REG_PTR(timerbase[i], MPS_TIMER_CLEAR_OFFSET);
122+
t->irq = MPS2_IRQ_FROMBASE(armv7m_gpio_base, timerirq[i]);
123+
124+
irq_attach(t->irq, timer_irq_handle, t);
125+
up_enable_irq(t->irq);
126+
127+
up_prioritize_irq(t->irq, timer_irq_prio[i]);
128+
}
129+
}
130+
131+
static int timer_irq_handle(int irq, void *context, void *arg)
132+
{
133+
mps2_an500_timer_t *t = arg;
134+
*t->clear = 1;
135+
*t->ctrl = 0;
136+
137+
tgkill(t->pid, t->pid, SIGINT);
138+
return 0;
139+
}
140+
141+
static void timer_begin_test(mps2_an500_timer_t *t, uint32_t reload_us)
142+
{
143+
uint32_t reload = reload_us * 25;
144+
*t->reload = reload;
145+
146+
*t->ctrl = MPS_TIMER_CTRL_IE | MPS_TIMER_CTRL_ENABLE;
147+
}
148+
149+
static void timer_end_test(mps2_an500_timer_t *t)
150+
{
151+
*t->ctrl = 0;
152+
*t->clear = 1;
153+
}
154+
155+
static void test_sa_handler(int signo)
156+
{
157+
/* Do nothing, only cause a EINTR */
158+
}
159+
160+
static void test_irq_signal(void **argv)
161+
{
162+
mps2_an500_timer_t *t = &timer[1];
163+
struct timespec ts;
164+
sem_t sem;
165+
int ret;
166+
167+
sem_init(&sem, 0, 0);
168+
169+
signal(SIGINT, test_sa_handler);
170+
171+
clock_gettime(CLOCK_REALTIME, &ts);
172+
ts.tv_sec++;
173+
174+
t->pid = getpid();
175+
timer_begin_test(t, CONFIG_TEST_ISR_SIGNAL_US);
176+
ret = sem_timedwait(&sem, &ts);
177+
printf("sem wait %d %d\n", ret, errno);
178+
assert_int_equal(ret, -1);
179+
assert_int_equal(errno, EINTR);
180+
}
181+
182+
static int setup(void **argv)
183+
{
184+
mps_timer_init();
185+
return 0;
186+
}
187+
188+
static int teardown(void **argv)
189+
{
190+
timer_end_test(&timer[0]);
191+
timer_end_test(&timer[1]);
192+
return 0;
193+
}
194+
195+
/****************************************************************************
196+
* Public Functions
197+
****************************************************************************/
198+
199+
int main(int argc, char *argv[])
200+
{
201+
const struct CMUnitTest tests[] = {
202+
cmocka_unit_test_prestate_setup_teardown(
203+
test_irq_signal, setup, teardown, NULL),
204+
};
205+
206+
return cmocka_run_group_tests(tests, NULL, NULL);
207+
}

0 commit comments

Comments
 (0)