We present a framework for component-based design and scheduling of real-time embedded software. Each component has a clearly specified interface that includes the methods used for sensing, computation, and actuation, along with a requirement given as a regular set of macro-schedules. Each macro-schedule is an infinite sequence that specifies, for every time slot, the set of component methods invoked in that slot. The macro-scheduler composes the specifications of all the components, along with the platform specification that constrains which methods can be executed within a single slot, to generate a feasible macro-schedule. Within a slot, we use logical execution time semantics, and this micro-scheduling is implemented on top of a native priority-based scheduler. With this approach, each component can be specified and analyzed in a platform-independent way, and at the same time, the performance can vary with changing load and changing processing speed. We describe an implementation using Real-Time Java. Scheduling specifications can be given as periodic tasks, or using temporal logic, or as omega-automata. Components can be added dynamically, and non-real-time components are allowed. We demonstrate the benefits of the approach using case studies.