source: rtems/bsps/arm/shared/clock/clock-nxp-lpc.c @ 7ee59313

5
Last change on this file since 7ee59313 was 7ee59313, checked in by Sebastian Huber <sebastian.huber@…>, on 06/01/18 at 05:11:12

Remove Clock_driver_support_shutdown_hardware()

The aim of this clock driver hook was to stop clock tick interrupts at
some late point in the exit() procedure.

The use of atexit() pulls in malloc() which pulls in errno. It is
incompatible with the intention of the
CONFIGURE_DISABLE_NEWLIB_REENTRANCY configuration option.

The exit() function must be called from thread context, so accompanied
clock tick interrupts should cause no harm. On the contrary, someone
may assume a normal operating system operation, e.g. working timeouts.

Remove the Clock_driver_support_shutdown_hardware() clock driver hook.

Close #3436.

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc_clock
5 *
6 * @brief Clock driver configuration.
7 */
8
9/*
10 * Copyright (c) 2009-2015 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <rtems.h>
24#include <rtems/timecounter.h>
25
26#include <bsp/lpc-clock-config.h>
27#include <bsp/lpc-timer.h>
28
29#ifdef ARM_MULTILIB_ARCH_V4
30
31/* This is defined in ../../../shared/dev/clock/clockimpl.h */
32void Clock_isr(rtems_irq_hdl_param arg);
33
34static volatile lpc_timer *const lpc_clock =
35  (volatile lpc_timer *) LPC_CLOCK_TIMER_BASE;
36
37static volatile lpc_timer *const lpc_timecounter =
38  (volatile lpc_timer *) LPC_CLOCK_TIMECOUNTER_BASE;
39
40static struct timecounter lpc_clock_tc;
41
42static uint32_t lpc_clock_tc_get_timecount(struct timecounter *tc)
43{
44  return lpc_timecounter->tc;
45}
46
47static void lpc_clock_at_tick(void)
48{
49  lpc_clock->ir = LPC_TIMER_IR_MR0;
50}
51
52static void lpc_clock_handler_install(void)
53{
54  rtems_status_code sc = RTEMS_SUCCESSFUL;
55
56  sc = rtems_interrupt_handler_install(
57    LPC_CLOCK_INTERRUPT,
58    "Clock",
59    RTEMS_INTERRUPT_UNIQUE,
60    (rtems_interrupt_handler) Clock_isr,
61    NULL
62  );
63  if (sc != RTEMS_SUCCESSFUL) {
64    rtems_fatal_error_occurred(0xdeadbeef);
65  }
66}
67
68static void lpc_clock_initialize(void)
69{
70  uint64_t interval = ((uint64_t) LPC_CLOCK_REFERENCE
71    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
72
73  /* Enable module */
74  LPC_CLOCK_MODULE_ENABLE();
75
76  /* Reset timer */
77  lpc_clock->tcr = LPC_TIMER_TCR_RST;
78
79  /* Clear interrupt flags */
80  lpc_clock->ir = LPC_TIMER_IR_ALL;
81
82  /* Set timer mode */
83  lpc_clock->ccr = 0;
84
85  /* Timer is incremented every PERIPH_CLK tick */
86  lpc_clock->pr = 0;
87
88  /* Set match registers */
89  lpc_clock->mr0 = (uint32_t) interval;
90
91  /* Generate interrupt and reset counter on match with MR0 */
92  lpc_clock->mcr = LPC_TIMER_MCR_MR0_INTR | LPC_TIMER_MCR_MR0_RST;
93
94  /* No external match */
95  lpc_clock->emr = 0x0;
96
97  /* Enable timer */
98  lpc_clock->tcr = LPC_TIMER_TCR_EN;
99
100  /* Install timecounter */
101  lpc_clock_tc.tc_get_timecount = lpc_clock_tc_get_timecount;
102  lpc_clock_tc.tc_counter_mask = 0xffffffff;
103  lpc_clock_tc.tc_frequency = LPC_CLOCK_REFERENCE;
104  lpc_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
105  rtems_timecounter_install(&lpc_clock_tc);
106}
107
108#define Clock_driver_support_at_tick() lpc_clock_at_tick()
109#define Clock_driver_support_initialize_hardware() lpc_clock_initialize()
110#define Clock_driver_support_install_isr(isr) \
111  lpc_clock_handler_install()
112
113/* Include shared source clock driver code */
114#include "../../../shared/dev/clock/clockimpl.h"
115
116#endif /* ARM_MULTILIB_ARCH_V4 */
Note: See TracBrowser for help on using the repository browser.