Apostolos Fanakis
5 years ago
253 changed files with 70758 additions and 2 deletions
@ -0,0 +1,30 @@ |
|||||
|
* text=auto |
||||
|
|
||||
|
# These files are text and should be normalized (convert crlf to lf) |
||||
|
*.rb text |
||||
|
*.test text |
||||
|
*.c text |
||||
|
*.cpp text |
||||
|
*.h text |
||||
|
*.txt text |
||||
|
*.yml text |
||||
|
*.s79 text |
||||
|
*.bat text |
||||
|
*.xcl text |
||||
|
*.inc text |
||||
|
*.info text |
||||
|
*.md text |
||||
|
makefile text |
||||
|
rakefile text |
||||
|
|
||||
|
|
||||
|
#These files are binary and should not be normalized |
||||
|
*.doc binary |
||||
|
*.odt binary |
||||
|
*.pdf binary |
||||
|
*.ewd binary |
||||
|
*.eww binary |
||||
|
*.dni binary |
||||
|
*.wsdt binary |
||||
|
*.dbgdt binary |
||||
|
*.mac binary |
@ -0,0 +1,8 @@ |
|||||
|
test/system/build |
||||
|
test/system/generated |
||||
|
*.sublime-project |
||||
|
Gemfile.lock |
||||
|
.rake_t_cache |
||||
|
.DS_Store |
||||
|
*.swp |
||||
|
examples/make_example/build |
@ -0,0 +1,8 @@ |
|||||
|
[submodule "vendor/unity"] |
||||
|
path = vendor/unity |
||||
|
url = https://github.com/throwtheswitch/unity.git |
||||
|
branch = master |
||||
|
[submodule "vendor/c_exception"] |
||||
|
path = vendor/c_exception |
||||
|
url = https://github.com/throwtheswitch/cexception.git |
||||
|
branch = master |
@ -0,0 +1,27 @@ |
|||||
|
language: ruby |
||||
|
|
||||
|
os: |
||||
|
- osx |
||||
|
- linux |
||||
|
|
||||
|
rvm: |
||||
|
- "2.3" |
||||
|
|
||||
|
before_install: |
||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install --assume-yes --quiet gcc-multilib; fi |
||||
|
|
||||
|
install: |
||||
|
- bundle install |
||||
|
- gem install rspec |
||||
|
- gem install rubocop -v 0.57.2 |
||||
|
|
||||
|
script: |
||||
|
- cd test && rake ci |
||||
|
- cd .. |
||||
|
- cd examples && cd make_example |
||||
|
- make clean |
||||
|
- make setup |
||||
|
- make test |
||||
|
- cd .. |
||||
|
- cd temp_sensor |
||||
|
- rake ci |
@ -0,0 +1,9 @@ |
|||||
|
source "http://rubygems.org/" |
||||
|
|
||||
|
gem "bundler", "~> 1.1.rc.7" |
||||
|
gem "rake", ">= 0.9.2.2" |
||||
|
|
||||
|
gem "minitest" |
||||
|
gem "require_all" |
||||
|
gem "constructor" |
||||
|
gem "diy" |
@ -0,0 +1,19 @@ |
|||||
|
Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams |
||||
|
|
||||
|
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. |
@ -0,0 +1,34 @@ |
|||||
|
CMock - Mock/stub generator for C |
||||
|
================================= |
||||
|
|
||||
|
[![CMock Build Status](https://api.travis-ci.org/ThrowTheSwitch/CMock.png?branch=master)](https://travis-ci.org/ThrowTheSwitch/CMock) |
||||
|
|
||||
|
Getting Started |
||||
|
================ |
||||
|
|
||||
|
If you're using Ceedling, there is no need to install CMock. It will handle it for you. |
||||
|
For everyone else, the simplest way is to grab it off github. You can also download it |
||||
|
as a zip if you prefer. The Github method looks something like this: |
||||
|
|
||||
|
> git clone --recursive https://github.com/throwtheswitch/cmock.git |
||||
|
> cd cmock |
||||
|
> bundle install # Ensures you have all RubyGems needed |
||||
|
|
||||
|
If you plan to help with the development of CMock (or just want to verify that it can |
||||
|
perform its self tests on your system) then you can enter the test directory and then |
||||
|
ask it to test: |
||||
|
|
||||
|
> cd test |
||||
|
> rake # Run all CMock self tests |
||||
|
|
||||
|
API Documentation |
||||
|
================= |
||||
|
|
||||
|
* Not sure what you're doing? |
||||
|
* [View docs/CMock_Summary.md](docs/CMock_Summary.md) |
||||
|
* Interested in our MIT-style license? |
||||
|
* [View docs/license.txt](docs/license.txt) |
||||
|
* Are there examples? |
||||
|
* They are all in [/examples](examples/) |
||||
|
* Any other resources to check out? |
||||
|
* Definitely! Check out our developer portal on [ThrowTheSwitch.org](http://throwtheswitch.org) |
@ -0,0 +1,14 @@ |
|||||
|
# ========================================== |
||||
|
# CMock Project - Automatic Mock Generation for C |
||||
|
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams |
||||
|
# [Released under MIT License. Please refer to license.txt for details] |
||||
|
# ========================================== |
||||
|
|
||||
|
# Setup our load path: |
||||
|
[ |
||||
|
'lib', |
||||
|
].each do |dir| |
||||
|
$LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__)) + '/../', dir) ) |
||||
|
end |
||||
|
|
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
# ========================================== |
||||
|
# CMock Project - Automatic Mock Generation for C |
||||
|
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams |
||||
|
# [Released under MIT License. Please refer to license.txt for details] |
||||
|
# ========================================== |
||||
|
|
||||
|
# Setup our load path: |
||||
|
[ |
||||
|
'./lib', |
||||
|
'./vendor/behaviors/lib', |
||||
|
'./vendor/hardmock/lib', |
||||
|
'./vendor/unity/auto/', |
||||
|
'./test/system/' |
||||
|
].each do |dir| |
||||
|
$LOAD_PATH.unshift( File.join( File.expand_path(File.dirname(__FILE__) + "/../"), dir) ) |
||||
|
end |
@ -0,0 +1,628 @@ |
|||||
|
CMock: A Summary |
||||
|
================ |
||||
|
|
||||
|
*[ThrowTheSwitch.org](http://throwtheswitch.org)* |
||||
|
|
||||
|
*This documentation is released under a Creative Commons 3.0 Attribution Share-Alike License* |
||||
|
|
||||
|
|
||||
|
What Exactly Are We Talking About Here? |
||||
|
--------------------------------------- |
||||
|
|
||||
|
CMock is a nice little tool which takes your header files and creates |
||||
|
a Mock interface for it so that you can more easily unit test modules |
||||
|
that touch other modules. For each function prototype in your |
||||
|
header, like this one: |
||||
|
|
||||
|
int DoesSomething(int a, int b); |
||||
|
|
||||
|
|
||||
|
...you get an automatically generated DoesSomething function |
||||
|
that you can link to instead of your real DoesSomething function. |
||||
|
By using this Mocked version, you can then verify that it receives |
||||
|
the data you want, and make it return whatever data you desire, |
||||
|
make it throw errors when you want, and more... Create these for |
||||
|
everything your latest real module touches, and you're suddenly |
||||
|
in a position of power: You can control and verify every detail |
||||
|
of your latest creation. |
||||
|
|
||||
|
To make that easier, CMock also gives you a bunch of functions |
||||
|
like the ones below, so you can tell that generated DoesSomething |
||||
|
function how to behave for each test: |
||||
|
|
||||
|
void DoesSomething_ExpectAndReturn(int a, int b, int toReturn); |
||||
|
void DoesSomething_ExpectAndThrow(int a, int b, EXCEPTION_T error); |
||||
|
void DoesSomething_StubWithCallback(CMOCK_DoesSomething_CALLBACK YourCallback); |
||||
|
void DoesSomething_IgnoreAndReturn(int toReturn); |
||||
|
|
||||
|
|
||||
|
You can pile a bunch of these back to back, and it remembers what |
||||
|
you wanted to pass when, like so: |
||||
|
|
||||
|
test_CallsDoesSomething_ShouldDoJustThat(void) |
||||
|
{ |
||||
|
DoesSomething_ExpectAndReturn(1,2,3); |
||||
|
DoesSomething_ExpectAndReturn(4,5,6); |
||||
|
DoesSomething_ExpectAndThrow(7,8, STATUS_ERROR_OOPS); |
||||
|
|
||||
|
CallsDoesSomething( ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
This test will call CallsDoesSomething, which is the function |
||||
|
we are testing. We are expecting that function to call DoesSomething |
||||
|
three times. The first time, we check to make sure it's called |
||||
|
as DoesSomething(1, 2) and we'll magically return a 3. The second |
||||
|
time we check for DoesSomething(4, 5) and we'll return a 6. The |
||||
|
third time we verify DoesSomething(7, 8) and we'll throw an error |
||||
|
instead of returning anything. If CallsDoesSomething gets |
||||
|
any of this wrong, it fails the test. It will fail if you didn't |
||||
|
call DoesSomething enough, or too much, or with the wrong arguments, |
||||
|
or in the wrong order. |
||||
|
|
||||
|
CMock is based on Unity, which it uses for all internal testing. |
||||
|
It uses Ruby to do all the main work (versions 2.0.0 and above). |
||||
|
|
||||
|
|
||||
|
Installing |
||||
|
========== |
||||
|
|
||||
|
The first thing you need to do to install CMock is to get yourself |
||||
|
a copy of Ruby. If you're on linux or osx, you probably already |
||||
|
have it. You can prove it by typing the following: |
||||
|
|
||||
|
ruby --version |
||||
|
|
||||
|
|
||||
|
If it replied in a way that implies ignorance, then you're going to |
||||
|
need to install it. You can go to [ruby-lang](https://ruby-lang.org) |
||||
|
to get the latest version. You're also going to need to do that if it |
||||
|
replied with a version that is older than 2.0.0. Go ahead. We'll wait. |
||||
|
|
||||
|
Once you have Ruby, you have three options: |
||||
|
|
||||
|
* Clone the latest [CMock repo on github](https://github.com/ThrowTheSwitch/CMock/) |
||||
|
* Download the latest [CMock zip from github](https://github.com/ThrowTheSwitch/CMock/) |
||||
|
* Install Ceedling (which has it built in!) through your commandline using `gem install ceedling`. |
||||
|
|
||||
|
|
||||
|
Generated Mock Module Summary |
||||
|
============================= |
||||
|
|
||||
|
In addition to the mocks themselves, CMock will generate the |
||||
|
following functions for use in your tests. The expect functions |
||||
|
are always generated. The other functions are only generated |
||||
|
if those plugins are enabled: |
||||
|
|
||||
|
|
||||
|
Expect: |
||||
|
------- |
||||
|
|
||||
|
Your basic staple Expects which will be used for most of your day |
||||
|
to day CMock work. By calling this, you are telling CMock that you |
||||
|
expect that function to be called during your test. It also specifies |
||||
|
which arguments you expect it to be called with, and what return |
||||
|
value you want returned when that happens. You can call this function |
||||
|
multiple times back to back in order to queue up multiple calls. |
||||
|
|
||||
|
* `void func(void)` => `void func_Expect(void)` |
||||
|
* `void func(params)` => `void func_Expect(expected_params)` |
||||
|
* `retval func(void)` => `void func_ExpectAndReturn(retval_to_return)` |
||||
|
* `retval func(params)` => `void func_ExpectAndReturn(expected_params, retval_to_return)` |
||||
|
|
||||
|
|
||||
|
ExpectAnyArgs: |
||||
|
-------------- |
||||
|
|
||||
|
This behaves just like the Expects calls, except that it doesn't really |
||||
|
care what the arguments are that the mock gets called with. It still counts |
||||
|
the number of times the mock is called and it still handles return values |
||||
|
if there are some. |
||||
|
|
||||
|
* `void func(void)` => `void func_ExpectAnyArgs(void)` |
||||
|
* `void func(params)` => `void func_ExpectAnyArgs(void)` |
||||
|
* `retval func(void)` => `void func_ExpectAnyArgsAndReturn(retval_to_return)` |
||||
|
* `retval func(params)` => `void func_ExpectAnyArgsAndReturn(retval_to_return)` |
||||
|
|
||||
|
|
||||
|
Array: |
||||
|
------ |
||||
|
|
||||
|
An ExpectWithArray is another variant of Expect. Like expect, it cares about |
||||
|
the number of times a mock is called, the arguments it is called with, and the |
||||
|
values it is to return. This variant has another feature, though. For anything |
||||
|
that resembles a pointer or array, it breaks the argument into TWO arguments. |
||||
|
The first is the original pointer. The second specify the number of elements |
||||
|
it is to verify of that array. If you specify 1, it'll check one object. If 2, |
||||
|
it'll assume your pointer is pointing at the first of two elements in an array. |
||||
|
If you specify zero elements, it will check just the pointer if |
||||
|
`:smart` mode is configured or fail if `:compare_data` is set. |
||||
|
|
||||
|
* `void func(void)` => (nothing. In fact, an additional function is only generated if the params list contains pointers) |
||||
|
* `void func(ptr * param, other)` => `void func_ExpectWithArray(ptr* param, int param_depth, other)` |
||||
|
* `retval func(void)` => (nothing. In fact, an additional function is only generated if the params list contains pointers) |
||||
|
* `retval func(other, ptr* param)` => `void func_ExpectWithArrayAndReturn(other, ptr* param, int param_depth, retval_to_return)` |
||||
|
|
||||
|
|
||||
|
Ignore: |
||||
|
------- |
||||
|
|
||||
|
Maybe you don't care about the number of times a particular function is called or |
||||
|
the actual arguments it is called with. In that case, you want to use Ignore. Ignore |
||||
|
only needs to be called once per test. It will then ignore any further calls to that |
||||
|
particular mock. The IgnoreAndReturn works similarly, except that it has the added |
||||
|
benefit of knowing what to return when that call happens. If the mock is called more |
||||
|
times than IgnoreAndReturn was called, it will keep returning the last value without |
||||
|
complaint. If it's called fewer times, it will also ignore that. You SAID you didn't |
||||
|
care how many times it was called, right? |
||||
|
|
||||
|
* `void func(void)` => `void func_Ignore(void)` |
||||
|
* `void func(params)` => `void func_Ignore(void)` |
||||
|
* `retval func(void)` => `void func_IgnoreAndReturn(retval_to_return)` |
||||
|
* `retval func(params)` => `void func_IgnoreAndReturn(retval_to_return)` |
||||
|
|
||||
|
|
||||
|
Ignore Arg: |
||||
|
------------ |
||||
|
|
||||
|
Maybe you overall want to use Expect and its similar variations, but you don't care |
||||
|
what is passed to a particular argument. This is particularly useful when that argument |
||||
|
is a pointer to a value that is supposed to be filled in by the function. You don't want |
||||
|
to use ExpectAnyArgs, because you still care about the other arguments. Instead, after |
||||
|
an Expect call is made, you can call this function. It tells CMock to ignore |
||||
|
a particular argument for the rest of this test, for this mock function. You may call |
||||
|
multiple instances of this to ignore multiple arguments after each expectation if |
||||
|
desired. |
||||
|
|
||||
|
* `void func(params)` => `void func_IgnoreArg_paramName(void)` |
||||
|
|
||||
|
|
||||
|
ReturnThruPtr: |
||||
|
-------------- |
||||
|
|
||||
|
Another option which operates on a particular argument of a function is the ReturnThruPtr |
||||
|
plugin. For every argument that resembles a pointer or reference, CMock generates an |
||||
|
instance of this function. Just as the AndReturn functions support injecting one or more |
||||
|
return values into a queue, this function lets you specify one or more return values which |
||||
|
are queued up and copied into the space being pointed at each time the mock is called. |
||||
|
|
||||
|
* `void func(param1)` => `void func_ReturnThruPtr_paramName(val_to_return)` |
||||
|
* => `void func_ReturnArrayThruPtr_paramName(cal_to_return, len)` |
||||
|
* => `void func_ReturnMemThruPtr_paramName(val_to_return, size)` |
||||
|
|
||||
|
|
||||
|
Callback: |
||||
|
--------- |
||||
|
|
||||
|
If all those other options don't work, and you really need to do something custom, you |
||||
|
still have a choice. As soon as you stub a callback in a test, it will call the callback |
||||
|
whenever the mock is encountered and return the retval returned from the callback (if any). |
||||
|
|
||||
|
* `void func(void)` => `void func_[Check,Ignore]WithCallback(CMOCK_func_CALLBACK callback)` |
||||
|
where `CMOCK_func_CALLBACK` looks like: `void func(int NumCalls)` |
||||
|
* `void func(params)` => `void func_[Check,Ignore]WithCallback(CMOCK_func_CALLBACK callback)` |
||||
|
where `CMOCK_func_CALLBACK` looks like: `void func(params, int NumCalls)` |
||||
|
* `retval func(void)` => `void func_[Check,Ignore]WithCallback(CMOCK_func_CALLBACK callback)` |
||||
|
where `CMOCK_func_CALLBACK` looks like: `retval func(int NumCalls)` |
||||
|
* `retval func(params)` => `void func_[Check,Ignore]WithCallback(CMOCK_func_CALLBACK callback)` |
||||
|
where `CMOCK_func_CALLBACK` looks like: `retval func(params, int NumCalls)` |
||||
|
|
||||
|
You can choose from two options: |
||||
|
|
||||
|
* `func_AddCallback` tells the mock to check its arguments and calling |
||||
|
order (based on any Expects you've set up) before calling the callback. |
||||
|
* `func_Stub` tells the mock to skip all the normal checks and jump directly |
||||
|
to the callback instead. In this case, you are replacing the normal mock calls |
||||
|
with your own custom stub function. |
||||
|
|
||||
|
There is also an older name, `func_StubWithCallback`, which is just an alias for |
||||
|
either `func_CheckWithCallback` or `func_IgnoreWithCallback` depending on |
||||
|
setting of the `:callback_after_arg_check` toggle. This is deprecated and we |
||||
|
recommend using the two options above. |
||||
|
|
||||
|
|
||||
|
Cexception: |
||||
|
----------- |
||||
|
|
||||
|
Finally, if you are using Cexception for error handling, you can use this to throw errors |
||||
|
from inside mocks. Like Expects, it remembers which call was supposed to throw the error, |
||||
|
and it still checks parameters first. |
||||
|
|
||||
|
* `void func(void)` => `void func_ExpectAndThrow(value_to_throw)` |
||||
|
* `void func(params)` => `void func_ExpectAndThrow(expected_params, value_to_throw)` |
||||
|
* `retval func(void)` => `void func_ExpectAndThrow(value_to_throw)` |
||||
|
* `retval func(params)` => `void func_ExpectAndThrow(expected_params, value_to_throw)` |
||||
|
|
||||
|
|
||||
|
|
||||
|
Running CMock |
||||
|
============= |
||||
|
|
||||
|
CMock is a Ruby script and class. You can therefore use it directly |
||||
|
from the command line, or include it in your own scripts or rakefiles. |
||||
|
|
||||
|
|
||||
|
Mocking from the Command Line |
||||
|
----------------------------- |
||||
|
|
||||
|
After unpacking CMock, you will find cmock.rb in the 'lib' directory. |
||||
|
This is the file that you want to run. It takes a list of header files |
||||
|
to be mocked, as well as an optional yaml file for a more detailed |
||||
|
configuration (see config options below). |
||||
|
|
||||
|
For example, this will create three mocks using the configuration |
||||
|
specified in MyConfig.yml: |
||||
|
|
||||
|
ruby cmock.rb -oMyConfig.yml super.h duper.h awesome.h |
||||
|
|
||||
|
And this will create two mocks using the default configuration: |
||||
|
|
||||
|
ruby cmock.rb ../mocking/stuff/is/fun.h ../try/it/yourself.h |
||||
|
|
||||
|
|
||||
|
Mocking From Scripts or Rake |
||||
|
---------------------------- |
||||
|
|
||||
|
CMock can be used directly from your own scripts or from a rakefile. |
||||
|
Start by including cmock.rb, then create an instance of CMock. |
||||
|
When you create your instance, you may initialize it in one of |
||||
|
three ways. |
||||
|
|
||||
|
You may specify nothing, allowing it to run with default settings: |
||||
|
|
||||
|
require 'cmock.rb' |
||||
|
cmock = CMock.new |
||||
|
|
||||
|
You may specify a YAML file containing the configuration options |
||||
|
you desire: |
||||
|
|
||||
|
cmock = CMock.new('../MyConfig.yml') |
||||
|
|
||||
|
You may specify the options explicitly: |
||||
|
|
||||
|
cmock = Cmock.new(:plugins => [:cexception, :ignore], :mock_path => 'my/mocks/') |
||||
|
|
||||
|
|
||||
|
Config Options: |
||||
|
--------------- |
||||
|
|
||||
|
The following configuration options can be specified in the |
||||
|
yaml file or directly when instantiating. |
||||
|
|
||||
|
Passed as Ruby, they look like this: |
||||
|
|
||||
|
{ :attributes => [“__funky”, “__intrinsic”], :when_ptr => :compare } |
||||
|
|
||||
|
Defined in the yaml file, they look more like this: |
||||
|
|
||||
|
:cmock: |
||||
|
:attributes: |
||||
|
- __funky |
||||
|
- __intrinsic |
||||
|
:when_ptr: :compare |
||||
|
|
||||
|
In all cases, you can just include the things that you want to override |
||||
|
from the defaults. We've tried to specify what the defaults are below. |
||||
|
|
||||
|
* `:attributes`: |
||||
|
These are attributes that CMock should ignore for you for testing |
||||
|
purposes. Custom compiler extensions and externs are handy things to |
||||
|
put here. If your compiler is choking on some extended syntax, this |
||||
|
is often a good place to look. |
||||
|
|
||||
|
* defaults: ['__ramfunc', '__irq', '__fiq', 'register', 'extern'] |
||||
|
* **note:** this option will reinsert these attributes onto the mock's calls. |
||||
|
If that isn't what you are looking for, check out :strippables. |
||||
|
|
||||
|
* `:c_calling_conventions`: |
||||
|
Similarly, CMock may need to understand which C calling conventions |
||||
|
might show up in your codebase. If it encounters something it doesn't |
||||
|
recognize, it's not going to mock it. We have the most common covered, |
||||
|
but there are many compilers out there, and therefore many other options. |
||||
|
|
||||
|
* defaults: ['__stdcall', '__cdecl', '__fastcall'] |
||||
|
* **note:** this option will reinsert these attributes onto the mock's calls. |
||||
|
If that isn't what you are looking for, check out :strippables. |
||||
|
|
||||
|
* `:callback_after_arg_check`: |
||||
|
Tell `:callback` plugin to do the normal argument checking **before** it |
||||
|
calls the callback function by setting this to true. When false, the |
||||
|
callback function is called **instead** of the argument verification. |
||||
|
|
||||
|
* default: false |
||||
|
|
||||
|
* `:callback_include_count`: |
||||
|
Tell `:callback` plugin to include an extra parameter to specify the |
||||
|
number of times the callback has been called. If set to false, the |
||||
|
callback has the same interface as the mocked function. This can be |
||||
|
handy when you're wanting to use callback as a stub. |
||||
|
|
||||
|
* default: true |
||||
|
|
||||
|
* `:cexception_include`: |
||||
|
Tell `:cexception` plugin where to find CException.h... You only need to |
||||
|
define this if it's not in your build path already... which it usually |
||||
|
will be for the purpose of your builds. |
||||
|
|
||||
|
* default: *nil* |
||||
|
|
||||
|
* `:enforce_strict_ordering`: |
||||
|
CMock always enforces the order that you call a particular function, |
||||
|
so if you expect GrabNabber(int size) to be called three times, it |
||||
|
will verify that the sizes are in the order you specified. You might |
||||
|
*also* want to make sure that all different functions are called in a |
||||
|
particular order. If so, set this to true. |
||||
|
|
||||
|
* default: false |
||||
|
|
||||
|
* `:framework`: |
||||
|
Currently the only option is `:unity.` Eventually if we support other |
||||
|
unity test frameworks (or if you write one for us), they'll get added |
||||
|
here. |
||||
|
|
||||
|
: default: :unity |
||||
|
|
||||
|
* `:includes`: |
||||
|
An array of additional include files which should be added to the |
||||
|
mocks. Useful for global types and definitions used in your project. |
||||
|
There are more specific versions if you care WHERE in the mock files |
||||
|
the includes get placed. You can define any or all of these options. |
||||
|
|
||||
|
* `:includes` |
||||
|
* `:includes_h_pre_orig_header` |
||||
|
* `:includes_h_post_orig_header` |
||||
|
* `:includes_c_pre_header` |
||||
|
* `:includes_c_post_header` |
||||
|
* default: nil #for all 5 options |
||||
|
|
||||
|
* `:memcmp_if_unknown`: |
||||
|
C developers create a lot of types, either through typedef or preprocessor |
||||
|
macros. CMock isn't going to automatically know what you were thinking all |
||||
|
the time (though it tries its best). If it comes across a type it doesn't |
||||
|
recognize, you have a choice on how you want it to handle it. It can either |
||||
|
perform a raw memory comparison and report any differences, or it can fail |
||||
|
with a meaningful message. Either way, this feature will only happen after |
||||
|
all other mechanisms have failed (The thing encountered isn't a standard |
||||
|
type. It isn't in the :treat_as list. It isn't in a custom unity_helper). |
||||
|
|
||||
|
* default: true |
||||
|
|
||||
|
* `:mock_path`: |
||||
|
The directory where you would like the mock files generated to be |
||||
|
placed. |
||||
|
|
||||
|
* default: mocks |
||||
|
|
||||
|
* `:mock_prefix`: |
||||
|
The prefix to prepend to your mock files. For example, if it's “Mock”, a file |
||||
|
“USART.h” will get a mock called “MockUSART.c”. This CAN be used with a suffix |
||||
|
at the same time. |
||||
|
|
||||
|
* default: Mock |
||||
|
|
||||
|
* `:mock_suffix`: |
||||
|
The suffix to append to your mock files. For example, it it's "_Mock", a file |
||||
|
"USART.h" will get a mock called "USART_Mock.h". This CAN be used with a prefix |
||||
|
at the same time. |
||||
|
|
||||
|
* default: "" |
||||
|
|
||||
|
* `:plugins`: |
||||
|
An array of which plugins to enable. ':expect' is always active. Also |
||||
|
available currently: |
||||
|
|
||||
|
* `:ignore` |
||||
|
* `:ignore_arg` |
||||
|
* `:expect_any_args` |
||||
|
* `:array` |
||||
|
* `:cexception` |
||||
|
* `:callback` |
||||
|
* `:return_thru_ptr` |
||||
|
|
||||
|
* `:strippables`: |
||||
|
An array containing a list of items to remove from the header |
||||
|
before deciding what should be mocked. This can be something simple |
||||
|
like a compiler extension CMock wouldn't recognize, or could be a |
||||
|
regex to reject certain function name patterns. This is a great way to |
||||
|
get rid of compiler extensions when your test compiler doesn't support |
||||
|
them. For example, use `:strippables: ['(?:functionName\s*\(+.*?\)+)']` |
||||
|
to prevent a function `functionName` from being mocked. By default, it |
||||
|
is ignoring all gcc attribute extensions. |
||||
|
|
||||
|
* default: ['(?:__attribute__\s*\(+.*?\)+)'] |
||||
|
|
||||
|
* `:subdir`: |
||||
|
This is a relative subdirectory for your mocks. Set this to e.g. "sys" in |
||||
|
order to create a mock for `sys/types.h` in `(:mock_path)/sys/`. |
||||
|
|
||||
|
* default: "" |
||||
|
|
||||
|
* `:treat_as`: |
||||
|
The `:treat_as` list is a shortcut for when you have created typedefs |
||||
|
of standard types. Why create a custom unity helper for UINT16 when |
||||
|
the unity function TEST_ASSERT_EQUAL_HEX16 will work just perfectly? |
||||
|
Just add 'UINT16' => 'HEX16' to your list (actually, don't. We already |
||||
|
did that one for you). Maybe you have a type that is a pointer to an |
||||
|
array of unsigned characters? No problem, just add 'UINT8_T*' => |
||||
|
'HEX8*' |
||||
|
|
||||
|
* NOTE: unlike the other options, your specifications MERGE with the |
||||
|
default list. Therefore, if you want to override something, you must |
||||
|
reassign it to something else (or to *nil* if you don't want it) |
||||
|
|
||||
|
* default: |
||||
|
* 'int': 'INT' |
||||
|
* 'char': 'INT8' |
||||
|
* 'short': 'INT16' |
||||
|
* 'long': 'INT' |
||||
|
* 'int8': 'INT8' |
||||
|
* 'int16': 'INT16' |
||||
|
* 'int32': 'INT' |
||||
|
* 'int8_t': 'INT8' |
||||
|
* 'int16_t': 'INT16' |
||||
|
* 'int32_t': 'INT' |
||||
|
* 'INT8_T': 'INT8' |
||||
|
* 'INT16_T': 'INT16' |
||||
|
* 'INT32_T': 'INT' |
||||
|
* 'bool': 'INT' |
||||
|
* 'bool_t': 'INT' |
||||
|
* 'BOOL': 'INT' |
||||
|
* 'BOOL_T': 'INT' |
||||
|
* 'unsigned int': 'HEX32' |
||||
|
* 'unsigned long': 'HEX32' |
||||
|
* 'uint32': 'HEX32' |
||||
|
* 'uint32_t': 'HEX32' |
||||
|
* 'UINT32': 'HEX32' |
||||
|
* 'UINT32_T': 'HEX32' |
||||
|
* 'void*': 'HEX8_ARRAY' |
||||
|
* 'unsigned short': 'HEX16' |
||||
|
* 'uint16': 'HEX16' |
||||
|
* 'uint16_t': 'HEX16' |
||||
|
* 'UINT16': 'HEX16' |
||||
|
* 'UINT16_T': 'HEX16' |
||||
|
* 'unsigned char': 'HEX8' |
||||
|
* 'uint8': 'HEX8' |
||||
|
* 'uint8_t': 'HEX8' |
||||
|
* 'UINT8': 'HEX8' |
||||
|
* 'UINT8_T': 'HEX8' |
||||
|
* 'char*': 'STRING' |
||||
|
* 'pCHAR': 'STRING' |
||||
|
* 'cstring': 'STRING' |
||||
|
* 'CSTRING': 'STRING' |
||||
|
* 'float': 'FLOAT' |
||||
|
* 'double': 'FLOAT' |
||||
|
|
||||
|
* `:treat_as_array`: |
||||
|
A specialized sort of `:treat_as` to be used when you've created a |
||||
|
typedef of an array type, such as `typedef int TenIntegers[10];`. This |
||||
|
is a hash of typedef name to element type. For example: |
||||
|
|
||||
|
{ "TenIntegers" => "int", |
||||
|
"ArrayOfFloat" => "float" } |
||||
|
|
||||
|
Telling CMock about these typedefs allows it to be more intelligent |
||||
|
about parameters of such types, so that you can use features like |
||||
|
ExpectWithArray and ReturnArrayThruPtr with them. |
||||
|
|
||||
|
* `:treat_as_void`: |
||||
|
We've seen "fun" legacy systems typedef 'void' with a custom type, |
||||
|
like MY_VOID. Add any instances of those to this list to help CMock |
||||
|
understand how to deal with your code. |
||||
|
|
||||
|
* default: [] |
||||
|
|
||||
|
* `:treat_externs`: |
||||
|
This specifies how you want CMock to handle functions that have been |
||||
|
marked as extern in the header file. Should it mock them? |
||||
|
|
||||
|
* `:include` will mock externed functions |
||||
|
* `:exclude` will ignore externed functions (default). |
||||
|
|
||||
|
* `:unity_helper_path`: |
||||
|
If you have created a header with your own extensions to unity to |
||||
|
handle your own types, you can set this argument to that path. CMock |
||||
|
will then automagically pull in your helpers and use them. The only |
||||
|
trick is that you make sure you follow the naming convention: |
||||
|
`UNITY_TEST_ASSERT_EQUAL_YourType`. If it finds macros of the right |
||||
|
shape that match that pattern, it'll use them. |
||||
|
|
||||
|
* default: [] |
||||
|
|
||||
|
* `:verbosity`: |
||||
|
How loud should CMock be? |
||||
|
|
||||
|
* 0 for errors only |
||||
|
* 1 for errors and warnings |
||||
|
* 2 for normal (default) |
||||
|
* 3 for verbose |
||||
|
|
||||
|
* `:weak`: |
||||
|
When set this to some value, the generated mocks are defined as weak |
||||
|
symbols using the configured format. This allows them to be overridden |
||||
|
in particular tests. |
||||
|
|
||||
|
* Set to '__attribute ((weak))' for weak mocks when using GCC. |
||||
|
* Set to any non-empty string for weak mocks when using IAR. |
||||
|
* default: "" |
||||
|
|
||||
|
* `:when_no_prototypes`: |
||||
|
When you give CMock a header file and ask it to create a mock out of |
||||
|
it, it usually contains function prototypes (otherwise what was the |
||||
|
point?). You can control what happens when this isn't true. You can |
||||
|
set this to `:warn,` `:ignore,` or `:error` |
||||
|
|
||||
|
* default: :warn |
||||
|
|
||||
|
* `:when_ptr`: |
||||
|
You can customize how CMock deals with pointers (c strings result in |
||||
|
string comparisons... we're talking about **other** pointers here). Your |
||||
|
options are `:compare_ptr` to just verify the pointers are the same, |
||||
|
`:compare_data` or `:smart` to verify that the data is the same. |
||||
|
`:compare_data` and `:smart` behaviors will change slightly based on |
||||
|
if you have the array plugin enabled. By default, they compare a |
||||
|
single element of what is being pointed to. So if you have a pointer |
||||
|
to a struct called ORGAN_T, it will compare one ORGAN_T (whatever that |
||||
|
is). |
||||
|
|
||||
|
* default: :smart |
||||
|
|
||||
|
* `:fail_on_unexpected_calls`: |
||||
|
By default, CMock will fail a test if a mock is called without _Expect and _Ignore |
||||
|
called first. While this forces test writers to be more explicit in their expectations, |
||||
|
it can clutter tests with _Expect or _Ignore calls for functions which are not the focus |
||||
|
of the test. While this is a good indicator that this module should be refactored, some |
||||
|
users are not fans of the additional noise. |
||||
|
|
||||
|
Therefore, :fail_on_unexpected_calls can be set to false to force all mocks to start with |
||||
|
the assumption that they are operating as _Ignore unless otherwise specified. |
||||
|
|
||||
|
* default: true |
||||
|
* **note:** |
||||
|
If this option is disabled, the mocked functions will return |
||||
|
a default value (0) when called (and only if they have to return something of course). |
||||
|
|
||||
|
|
||||
|
Compiled Options: |
||||
|
----------------- |
||||
|
|
||||
|
A number of #defines also exist for customizing the cmock experience. |
||||
|
Feel free to pass these into your compiler or whatever is most |
||||
|
convenient. CMock will otherwise do its best to guess what you want |
||||
|
based on other settings, particularly Unity's settings. |
||||
|
|
||||
|
* `CMOCK_MEM_STATIC` or `CMOCK_MEM_DYNAMIC` |
||||
|
Define one of these to determine if you want to dynamically add |
||||
|
memory during tests as required from the heap. If static, you |
||||
|
can control the total footprint of Cmock. If dynamic, you will |
||||
|
need to make sure you make some heap space available for Cmock. |
||||
|
|
||||
|
* `CMOCK_MEM_SIZE` |
||||
|
In static mode this is the total amount of memory you are allocating |
||||
|
to Cmock. In Dynamic mode this is the size of each chunk allocated |
||||
|
at once (larger numbers grab more memory but require fewer mallocs). |
||||
|
|
||||
|
* `CMOCK_MEM_ALIGN` |
||||
|
The way to align your data to. Not everything is as flexible as |
||||
|
a PC, as most embedded designers know. This defaults to 2, meaning |
||||
|
align to the closest 2^2 -> 4 bytes (32 bits). You can turn off alignment |
||||
|
by setting 0, force alignment to the closest uint16 with 1 or even |
||||
|
to the closest uint64 with 3. |
||||
|
|
||||
|
* `CMOCK_MEM_PTR_AS_INT` |
||||
|
This is used internally to hold pointers... it needs to be big |
||||
|
enough. On most processors a pointer is the same as an unsigned |
||||
|
long... but maybe that's not true for yours? |
||||
|
|
||||
|
* `CMOCK_MEM_INDEX_TYPE` |
||||
|
This needs to be something big enough to point anywhere in Cmock's |
||||
|
memory space... usually it's an unsigned int. |
||||
|
|
||||
|
Examples |
||||
|
======== |
||||
|
|
||||
|
You can look in the [examples directory](/examples/) for a couple of examples on how |
||||
|
you might tool CMock into your build process. You may also want to consider |
||||
|
using [Ceedling](https://throwtheswitch.org/ceedling). Please note that |
||||
|
these examples are meant to show how the build process works. They have |
||||
|
failing tests ON PURPOSE to show what that would look like. Don't be alarmed. ;) |
||||
|
|
@ -0,0 +1,207 @@ |
|||||
|
# ThrowTheSwitch.org Coding Standard |
||||
|
|
||||
|
Hi. Welcome to the coding standard for ThrowTheSwitch.org. For the most part, |
||||
|
we try to follow these standards to unify our contributors' code into a cohesive |
||||
|
unit (puns intended). You might find places where these standards aren't |
||||
|
followed. We're not perfect. Please be polite where you notice these discrepancies |
||||
|
and we'll try to be polite when we notice yours. |
||||
|
|
||||
|
;) |
||||
|
|
||||
|
|
||||
|
## Why Have A Coding Standard? |
||||
|
|
||||
|
Being consistent makes code easier to understand. We've made an attempt to keep |
||||
|
our standard simple because we also believe that we can only expect someone to |
||||
|
follow something that is understandable. Please do your best. |
||||
|
|
||||
|
|
||||
|
## Our Philosophy |
||||
|
|
||||
|
Before we get into details on syntax, let's take a moment to talk about our |
||||
|
vision for these tools. We're C developers and embedded software developers. |
||||
|
These tools are great to test any C code, but catering to embedded software has |
||||
|
made us more tolerant of compiler quirks. There are a LOT of quirky compilers |
||||
|
out there. By quirky I mean "doesn't follow standards because they feel like |
||||
|
they have a license to do as they wish." |
||||
|
|
||||
|
Our philosophy is "support every compiler we can". Most often, this means that |
||||
|
we aim for writing C code that is standards compliant (often C89... that seems |
||||
|
to be a sweet spot that is almost always compatible). But it also means these |
||||
|
tools are tolerant of things that aren't common. Some that aren't even |
||||
|
compliant. There are configuration options to override the size of standard |
||||
|
types. There are configuration options to force Unity to not use certain |
||||
|
standard library functions. A lot of Unity is configurable and we have worked |
||||
|
hard to make it not TOO ugly in the process. |
||||
|
|
||||
|
Similarly, our tools that parse C do their best. They aren't full C parsers |
||||
|
(yet) and, even if they were, they would still have to accept non-standard |
||||
|
additions like gcc extensions or specifying `@0x1000` to force a variable to |
||||
|
compile to a particular location. It's just what we do, because we like |
||||
|
everything to Just Work™. |
||||
|
|
||||
|
Speaking of having things Just Work™, that's our second philosophy. By that, we |
||||
|
mean that we do our best to have EVERY configuration option have a logical |
||||
|
default. We believe that if you're working with a simple compiler and target, |
||||
|
you shouldn't need to configure very much... we try to make the tools guess as |
||||
|
much as they can, but give the user the power to override it when it's wrong. |
||||
|
|
||||
|
|
||||
|
## Naming Things |
||||
|
|
||||
|
Let's talk about naming things. Programming is all about naming things. We name |
||||
|
files, functions, variables, and so much more. While we're not always going to |
||||
|
find the best name for something, we actually put quite a bit of effort into |
||||
|
finding *What Something WANTS to be Called*™. |
||||
|
|
||||
|
When naming things, we more or less follow this hierarchy, the first being the |
||||
|
most important to us (but we do all four whenever possible): |
||||
|
1. Readable |
||||
|
2. Descriptive |
||||
|
3. Consistent |
||||
|
4. Memorable |
||||
|
|
||||
|
|
||||
|
#### Readable |
||||
|
|
||||
|
We want to read our code. This means we like names and flow that are more |
||||
|
naturally read. We try to avoid double negatives. We try to avoid cryptic |
||||
|
abbreviations (sticking to ones we feel are common). |
||||
|
|
||||
|
|
||||
|
#### Descriptive |
||||
|
|
||||
|
We like descriptive names for things, especially functions and variables. |
||||
|
Finding the right name for something is an important endeavor. You might notice |
||||
|
from poking around our code that this often results in names that are a little |
||||
|
longer than the average. Guilty. We're okay with a tiny bit more typing if it |
||||
|
means our code is easier to understand. |
||||
|
|
||||
|
There are two exceptions to this rule that we also stick to as religiously as |
||||
|
possible: |
||||
|
|
||||
|
First, while we realize hungarian notation (and similar systems for encoding |
||||
|
type information into variable names) is providing a more descriptive name, we |
||||
|
feel that (for the average developer) it takes away from readability and |
||||
|
therefore is to be avoided. |
||||
|
|
||||
|
Second, loop counters and other local throw-away variables often have a purpose |
||||
|
which is obvious. There's no need, therefore, to get carried away with complex |
||||
|
naming. We find i, j, and k are better loop counters than loopCounterVar or |
||||
|
whatnot. We only break this rule when we see that more description could improve |
||||
|
understanding of an algorithm. |
||||
|
|
||||
|
|
||||
|
#### Consistent |
||||
|
|
||||
|
We like consistency, but we're not really obsessed with it. We try to name our |
||||
|
configuration macros in a consistent fashion... you'll notice a repeated use of |
||||
|
UNITY_EXCLUDE_BLAH or UNITY_USES_BLAH macros. This helps users avoid having to |
||||
|
remember each macro's details. |
||||
|
|
||||
|
|
||||
|
#### Memorable |
||||
|
|
||||
|
Where ever it doesn't violate the above principles, we try to apply memorable |
||||
|
names. Sometimes this means using something that is simply descriptive, but |
||||
|
often we strive for descriptive AND unique... we like quirky names that stand |
||||
|
out in our memory and are easier to search for. Take a look through the file |
||||
|
names in Ceedling and you'll get a good idea of what we are talking about here. |
||||
|
Why use preprocess when you can use preprocessinator? Or what better describes a |
||||
|
module in charge of invoking tasks during releases than release_invoker? Don't |
||||
|
get carried away. The names are still descriptive and fulfill the above |
||||
|
requirements, but they don't feel stale. |
||||
|
|
||||
|
|
||||
|
## C and C++ Details |
||||
|
|
||||
|
We don't really want to add to the style battles out there. Tabs or spaces? |
||||
|
How many spaces? Where do the braces go? These are age-old questions that will |
||||
|
never be answered... or at least not answered in a way that will make everyone |
||||
|
happy. |
||||
|
|
||||
|
We've decided on our own style preferences. If you'd like to contribute to these |
||||
|
projects (and we hope that you do), then we ask if you do your best to follow |
||||
|
the same. It will only hurt a little. We promise. |
||||
|
|
||||
|
|
||||
|
#### Whitespace |
||||
|
|
||||
|
Our C-style is to use spaces and to use 4 of them per indent level. It's a nice |
||||
|
power-of-2 number that looks decent on a wide screen. We have no more reason |
||||
|
than that. We break that rule when we have lines that wrap (macros or function |
||||
|
arguments or whatnot). When that happens, we like to indent further to line |
||||
|
things up in nice tidy columns. |
||||
|
|
||||
|
```C |
||||
|
if (stuff_happened) |
||||
|
{ |
||||
|
do_something(); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
#### Case |
||||
|
|
||||
|
- Files - all lower case with underscores. |
||||
|
- Variables - all lower case with underscores |
||||
|
- Macros - all caps with underscores. |
||||
|
- Typedefs - all caps with underscores. (also ends with _T). |
||||
|
- Functions - camel cased. Usually named ModuleName_FuncName |
||||
|
- Constants and Globals - camel cased. |
||||
|
|
||||
|
|
||||
|
#### Braces |
||||
|
|
||||
|
The left brace is on the next line after the declaration. The right brace is |
||||
|
directly below that. Everything in between in indented one level. If you're |
||||
|
catching an error and you have a one-line, go ahead and to it on the same line. |
||||
|
|
||||
|
```C |
||||
|
while (blah) |
||||
|
{ |
||||
|
//Like so. Even if only one line, we use braces. |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
#### Comments |
||||
|
|
||||
|
Do you know what we hate? Old-school C block comments. BUT, we're using them |
||||
|
anyway. As we mentioned, our goal is to support every compiler we can, |
||||
|
especially embedded compilers. There are STILL C compilers out there that only |
||||
|
support old-school block comments. So that is what we're using. We apologize. We |
||||
|
think they are ugly too. |
||||
|
|
||||
|
|
||||
|
## Ruby Details |
||||
|
|
||||
|
Is there really such thing as a Ruby coding standard? Ruby is such a free form |
||||
|
language, it seems almost sacrilegious to suggest that people should comply to |
||||
|
one method! We'll keep it really brief! |
||||
|
|
||||
|
|
||||
|
#### Whitespace |
||||
|
|
||||
|
Our Ruby style is to use spaces and to use 2 of them per indent level. It's a |
||||
|
nice power-of-2 number that really grooves with Ruby's compact style. We have no |
||||
|
more reason than that. We break that rule when we have lines that wrap. When |
||||
|
that happens, we like to indent further to line things up in nice tidy columns. |
||||
|
|
||||
|
|
||||
|
#### Case |
||||
|
|
||||
|
- Files - all lower case with underscores. |
||||
|
- Variables - all lower case with underscores |
||||
|
- Classes, Modules, etc - Camel cased. |
||||
|
- Functions - all lower case with underscores |
||||
|
- Constants - all upper case with underscores |
||||
|
|
||||
|
|
||||
|
## Documentation |
||||
|
|
||||
|
Egad. Really? We use markdown and we like pdf files because they can be made to |
||||
|
look nice while still being portable. Good enough? |
||||
|
|
||||
|
|
||||
|
*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* |
@ -0,0 +1,30 @@ |
|||||
|
CC ?= gcc |
||||
|
export BUILD_DIR ?= ./build |
||||
|
export SRC_DIR ?= ./src |
||||
|
export TEST_DIR ?= ./test |
||||
|
export TEST_BUILD_DIR ?= ${BUILD_DIR}/test |
||||
|
TEST_MAKEFILE = ${TEST_BUILD_DIR}/MakefileTestSupport |
||||
|
OBJ ?= ${BUILD_DIR}/obj |
||||
|
OBJ_DIR = ${OBJ} |
||||
|
|
||||
|
default: all |
||||
|
|
||||
|
all: setup test ${BUILD_DIR}/main run |
||||
|
|
||||
|
setup: |
||||
|
mkdir -p ${BUILD_DIR} |
||||
|
mkdir -p ${OBJ} |
||||
|
ruby ../../scripts/create_makefile.rb --silent |
||||
|
|
||||
|
clean: |
||||
|
rm -rf ${BUILD_DIR} |
||||
|
|
||||
|
${BUILD_DIR}/main: ${SRC_DIR}/main.c ${SRC_DIR}/foo.c |
||||
|
${CC} $< -o $@ |
||||
|
|
||||
|
run: |
||||
|
./build/main || true |
||||
|
|
||||
|
test: setup |
||||
|
|
||||
|
-include ${TEST_MAKEFILE} |
@ -0,0 +1,5 @@ |
|||||
|
#include "foo.h" |
||||
|
|
||||
|
void foo_init(void) |
||||
|
{ |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
#ifndef _foo_h |
||||
|
|
||||
|
void foo_init(void); |
||||
|
|
||||
|
#endif |
@ -0,0 +1,15 @@ |
|||||
|
#include <stdio.h> |
||||
|
#include "foo.h" |
||||
|
|
||||
|
int real_main(int argc, char ** argv) |
||||
|
{ |
||||
|
printf("Hello world!\n"); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
#ifndef TEST |
||||
|
int main(int argc, char ** argv) |
||||
|
{ |
||||
|
return real_main(argc, argv); |
||||
|
} |
||||
|
#endif |
@ -0,0 +1,17 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "foo.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void test_foo_init_should_initialize_multiplier() |
||||
|
{ |
||||
|
foo_init(); |
||||
|
|
||||
|
TEST_ASSERT_FALSE(1); |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "mock_foo.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void test_main_should_initialize_foo(void) |
||||
|
{ |
||||
|
TEST_IGNORE_MESSAGE("TODO: Implement main!"); |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
compiler: |
||||
|
path: gcc |
||||
|
source_path: 'src/' |
||||
|
unit_tests_path: &unit_tests_path 'test/' |
||||
|
build_path: &build_path 'build/' |
||||
|
options: |
||||
|
- -c |
||||
|
includes: |
||||
|
prefix: '-I' |
||||
|
items: |
||||
|
- 'src/' |
||||
|
- '../../src/' |
||||
|
- '../../vendor/unity/src/' |
||||
|
- '../../vendor/unity/examples/example_3/helper/' |
||||
|
- './build/mocks/' |
||||
|
- *unit_tests_path |
||||
|
defines: |
||||
|
prefix: '-D' |
||||
|
items: |
||||
|
- __monitor |
||||
|
object_files: |
||||
|
prefix: '-o' |
||||
|
extension: '.o' |
||||
|
destination: *build_path |
||||
|
linker: |
||||
|
path: gcc |
||||
|
options: |
||||
|
- -lm |
||||
|
includes: |
||||
|
prefix: '-I' |
||||
|
object_files: |
||||
|
path: *build_path |
||||
|
extension: '.o' |
||||
|
bin_files: |
||||
|
prefix: '-o' |
||||
|
extension: '.exe' |
||||
|
destination: *build_path |
||||
|
:cmock: |
||||
|
:plugins: [] |
||||
|
:includes: |
||||
|
- Types.h |
||||
|
:mock_path: ./build/mocks |
||||
|
|
||||
|
colour: true |
@ -0,0 +1,92 @@ |
|||||
|
tools_root: &tools_root 'C:\Program Files\IAR Systems\Embedded Workbench 4.0 Kickstart\' |
||||
|
compiler: |
||||
|
path: [*tools_root, 'arm\bin\iccarm.exe'] |
||||
|
source_path: 'src\' |
||||
|
unit_tests_path: &unit_tests_path 'test\' |
||||
|
build_path: &build_path 'build\' |
||||
|
options: |
||||
|
- --dlib_config |
||||
|
- [*tools_root, 'arm\lib\dl4tptinl8n.h'] |
||||
|
- -z3 |
||||
|
- --no_cse |
||||
|
- --no_unroll |
||||
|
- --no_inline |
||||
|
- --no_code_motion |
||||
|
- --no_tbaa |
||||
|
- --no_clustering |
||||
|
- --no_scheduling |
||||
|
- --debug |
||||
|
- --cpu_mode thumb |
||||
|
- --endian little |
||||
|
- --cpu ARM7TDMI |
||||
|
- --stack_align 4 |
||||
|
- --interwork |
||||
|
- -e |
||||
|
- --silent |
||||
|
- --warnings_are_errors |
||||
|
- --fpu None |
||||
|
- --diag_suppress Pa050 |
||||
|
includes: |
||||
|
prefix: '-I' |
||||
|
items: |
||||
|
- 'src/' |
||||
|
- '../../src/' |
||||
|
- '../../vendor/unity/src/' |
||||
|
- '../../vendor/unity/examples/example_3/helper/' |
||||
|
- './build/mocks/' |
||||
|
- [*tools_root, 'arm\inc\'] |
||||
|
- *unit_tests_path |
||||
|
defines: |
||||
|
prefix: '-D' |
||||
|
items: |
||||
|
object_files: |
||||
|
prefix: '-o' |
||||
|
extension: '.r79' |
||||
|
destination: *build_path |
||||
|
linker: |
||||
|
path: [*tools_root, 'common\bin\xlink.exe'] |
||||
|
options: |
||||
|
- -rt |
||||
|
- [*tools_root, 'arm\lib\dl4tptinl8n.r79'] |
||||
|
- -D_L_EXTMEM_START=0 |
||||
|
- -D_L_EXTMEM_SIZE=0 |
||||
|
- -D_L_HEAP_SIZE=120 |
||||
|
- -D_L_STACK_SIZE=32 |
||||
|
- -e_small_write=_formatted_write |
||||
|
- -s |
||||
|
- __program_start |
||||
|
- -f |
||||
|
- [*tools_root, '\arm\config\lnkarm.xcl'] |
||||
|
includes: |
||||
|
prefix: '-I' |
||||
|
items: |
||||
|
- [*tools_root, 'arm\config\'] |
||||
|
- [*tools_root, 'arm\lib\'] |
||||
|
object_files: |
||||
|
path: *build_path |
||||
|
extension: '.r79' |
||||
|
bin_files: |
||||
|
prefix: '-o' |
||||
|
extension: '.d79' |
||||
|
destination: *build_path |
||||
|
simulator: |
||||
|
path: [*tools_root, 'common\bin\CSpyBat.exe'] |
||||
|
pre_support: |
||||
|
- --silent |
||||
|
- [*tools_root, 'arm\bin\armproc.dll'] |
||||
|
- [*tools_root, 'arm\bin\armsim.dll'] |
||||
|
post_support: |
||||
|
- --plugin |
||||
|
- [*tools_root, 'arm\bin\armbat.dll'] |
||||
|
- --backend |
||||
|
- -B |
||||
|
- -p |
||||
|
- [*tools_root, 'arm\config\ioat91sam7X256.ddf'] |
||||
|
- -d |
||||
|
- sim |
||||
|
:cmock: |
||||
|
:plugins: [] |
||||
|
:includes: |
||||
|
- Types.h |
||||
|
:mock_path: ./build/mocks |
||||
|
|
@ -0,0 +1,81 @@ |
|||||
|
tools_root: &tools_root 'C:\Program Files\IAR Systems\Embedded Workbench 5.3\' |
||||
|
compiler: |
||||
|
path: [*tools_root, 'arm\bin\iccarm.exe'] |
||||
|
source_path: 'src\' |
||||
|
unit_tests_path: &unit_tests_path 'test\' |
||||
|
build_path: &build_path 'build\' |
||||
|
options: |
||||
|
- --dlib_config |
||||
|
- [*tools_root, 'arm\inc\DLib_Config_Normal.h'] |
||||
|
- --no_cse |
||||
|
- --no_unroll |
||||
|
- --no_inline |
||||
|
- --no_code_motion |
||||
|
- --no_tbaa |
||||
|
- --no_clustering |
||||
|
- --no_scheduling |
||||
|
- --debug |
||||
|
- --cpu_mode thumb |
||||
|
- --endian=little |
||||
|
- --cpu=ARM7TDMI |
||||
|
- --interwork |
||||
|
- --warnings_are_errors |
||||
|
- --fpu=None |
||||
|
- --diag_suppress=Pa050 |
||||
|
- --diag_suppress=Pe111 |
||||
|
- -e |
||||
|
- -On |
||||
|
includes: |
||||
|
prefix: '-I' |
||||
|
items: |
||||
|
- 'src/' |
||||
|
- '../../src/' |
||||
|
- '../../vendor/unity/src/' |
||||
|
- '../../vendor/unity/examples/example_3/helper/' |
||||
|
- './build/mocks/' |
||||
|
- [*tools_root, 'arm\inc\'] |
||||
|
- *unit_tests_path |
||||
|
defines: |
||||
|
prefix: '-D' |
||||
|
items: |
||||
|
object_files: |
||||
|
prefix: '-o' |
||||
|
extension: '.r79' |
||||
|
destination: *build_path |
||||
|
linker: |
||||
|
path: [*tools_root, 'arm\bin\ilinkarm.exe'] |
||||
|
options: |
||||
|
- --redirect _Printf=_PrintfLarge |
||||
|
- --redirect _Scanf=_ScanfSmall |
||||
|
- --semihosting |
||||
|
- --entry __iar_program_start |
||||
|
- --config |
||||
|
- [*tools_root, 'arm\config\generic.icf'] |
||||
|
object_files: |
||||
|
path: *build_path |
||||
|
extension: '.o' |
||||
|
bin_files: |
||||
|
prefix: '-o' |
||||
|
extension: '.out' |
||||
|
destination: *build_path |
||||
|
simulator: |
||||
|
path: [*tools_root, 'common\bin\CSpyBat.exe'] |
||||
|
pre_support: |
||||
|
- --silent |
||||
|
- [*tools_root, 'arm\bin\armproc.dll'] |
||||
|
- [*tools_root, 'arm\bin\armsim.dll'] |
||||
|
post_support: |
||||
|
- --plugin |
||||
|
- [*tools_root, 'arm\bin\armbat.dll'] |
||||
|
- --backend |
||||
|
- -B |
||||
|
- -p |
||||
|
- [*tools_root, 'arm\config\debugger\atmel\ioat91sam7X256.ddf'] |
||||
|
- -d |
||||
|
- sim |
||||
|
:cmock: |
||||
|
:plugins: [] |
||||
|
:includes: |
||||
|
- Types.h |
||||
|
:mock_path: ./build/mocks |
||||
|
|
@ -0,0 +1,42 @@ |
|||||
|
HERE = File.expand_path(File.dirname(__FILE__)) + '/' |
||||
|
|
||||
|
require 'rake' |
||||
|
require 'rake/clean' |
||||
|
require 'rake/testtask' |
||||
|
require './rakefile_helper' |
||||
|
|
||||
|
include RakefileHelpers |
||||
|
|
||||
|
REQUIRED_DIRS = [ './build', './build/mocks' ] |
||||
|
REQUIRED_DIRS.each do |v| |
||||
|
directory v |
||||
|
end |
||||
|
|
||||
|
# Load default configuration, for now |
||||
|
DEFAULT_CONFIG_FILE = 'gcc.yml' |
||||
|
configure_toolchain(DEFAULT_CONFIG_FILE) |
||||
|
|
||||
|
task :unit do |
||||
|
run_tests(get_unit_test_files) |
||||
|
end |
||||
|
|
||||
|
desc "Generate test summary" |
||||
|
task :summary do |
||||
|
report_summary |
||||
|
end |
||||
|
|
||||
|
desc "Build and test Unity" |
||||
|
task :all => [:clean, :unit, :summary] |
||||
|
task :default => REQUIRED_DIRS + [:clobber, :all] |
||||
|
task :ci => [:default] |
||||
|
task :cruise => [:default] |
||||
|
|
||||
|
desc "Load configuration" |
||||
|
task :config, :config_file do |t, args| |
||||
|
configure_toolchain(args[:config_file]) |
||||
|
end |
||||
|
|
||||
|
desc "Return error on Failures" |
||||
|
task :strict do |
||||
|
$return_error_on_failures = true |
||||
|
end |
@ -0,0 +1,272 @@ |
|||||
|
require 'yaml' |
||||
|
require 'fileutils' |
||||
|
require '../../vendor/unity/auto/unity_test_summary' |
||||
|
require '../../vendor/unity/auto/generate_test_runner' |
||||
|
require '../../vendor/unity/auto/colour_reporter' |
||||
|
|
||||
|
module RakefileHelpers |
||||
|
|
||||
|
$return_error_on_failures = false |
||||
|
|
||||
|
C_EXTENSION = '.c' |
||||
|
|
||||
|
def load_configuration(config_file) |
||||
|
$cfg_file = config_file |
||||
|
$cfg = YAML.load(File.read($cfg_file)) |
||||
|
$colour_output = false unless $cfg['colour'] |
||||
|
end |
||||
|
|
||||
|
def configure_clean |
||||
|
CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil? |
||||
|
end |
||||
|
|
||||
|
def configure_toolchain(config_file=DEFAULT_CONFIG_FILE) |
||||
|
config_file += '.yml' unless config_file =~ /\.yml$/ |
||||
|
load_configuration(config_file) |
||||
|
configure_clean |
||||
|
end |
||||
|
|
||||
|
def get_unit_test_files |
||||
|
path = $cfg['compiler']['unit_tests_path'] + 'Test*' + C_EXTENSION |
||||
|
path.gsub!(/\\/, '/') |
||||
|
FileList.new(path) |
||||
|
end |
||||
|
|
||||
|
def get_local_include_dirs |
||||
|
include_dirs = $cfg['compiler']['includes']['items'].dup |
||||
|
include_dirs.delete_if {|dir| dir.is_a?(Array)} |
||||
|
return include_dirs |
||||
|
end |
||||
|
|
||||
|
def extract_headers(filename) |
||||
|
includes = [] |
||||
|
lines = File.readlines(filename) |
||||
|
lines.each do |line| |
||||
|
m = line.match(/^\s*#include\s+\"\s*(.+\.[hH])\s*\"/) |
||||
|
if not m.nil? |
||||
|
includes << m[1] |
||||
|
end |
||||
|
end |
||||
|
return includes |
||||
|
end |
||||
|
|
||||
|
def find_source_file(header, paths) |
||||
|
paths.each do |dir| |
||||
|
src_file = dir + header.ext(C_EXTENSION) |
||||
|
if (File.exists?(src_file)) |
||||
|
return src_file |
||||
|
end |
||||
|
end |
||||
|
return nil |
||||
|
end |
||||
|
|
||||
|
def tackit(strings) |
||||
|
case(strings) |
||||
|
when Array |
||||
|
"\"#{strings.join}\"" |
||||
|
when /^-/ |
||||
|
strings |
||||
|
when /\s/ |
||||
|
"\"#{strings}\"" |
||||
|
else |
||||
|
strings |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def squash(prefix, items) |
||||
|
result = '' |
||||
|
items.each { |item| result += " #{prefix}#{tackit(item)}" } |
||||
|
return result |
||||
|
end |
||||
|
|
||||
|
def build_compiler_fields |
||||
|
command = tackit($cfg['compiler']['path']) |
||||
|
if $cfg['compiler']['defines']['items'].nil? |
||||
|
defines = '' |
||||
|
else |
||||
|
defines = squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items']) |
||||
|
end |
||||
|
options = squash('', $cfg['compiler']['options']) |
||||
|
includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items']) |
||||
|
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) |
||||
|
return {:command => command, :defines => defines, :options => options, :includes => includes} |
||||
|
end |
||||
|
|
||||
|
def compile(file, defines=[]) |
||||
|
compiler = build_compiler_fields |
||||
|
cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{file} " + |
||||
|
"#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" |
||||
|
obj_file = "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}" |
||||
|
execute(cmd_str + obj_file) |
||||
|
return obj_file |
||||
|
end |
||||
|
|
||||
|
def build_linker_fields |
||||
|
command = tackit($cfg['linker']['path']) |
||||
|
if $cfg['linker']['options'].nil? |
||||
|
options = '' |
||||
|
else |
||||
|
options = squash('', $cfg['linker']['options']) |
||||
|
end |
||||
|
if ($cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil?) |
||||
|
includes = '' |
||||
|
else |
||||
|
includes = squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items']) |
||||
|
end |
||||
|
includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) |
||||
|
return {:command => command, :options => options, :includes => includes} |
||||
|
end |
||||
|
|
||||
|
def link_it(exe_name, obj_list) |
||||
|
linker = build_linker_fields |
||||
|
cmd_str = "#{linker[:command]}#{linker[:includes]} " + |
||||
|
(obj_list.map{|obj|"#{$cfg['linker']['object_files']['path']}#{obj} "}).join + |
||||
|
$cfg['linker']['bin_files']['prefix'] + ' ' + |
||||
|
$cfg['linker']['bin_files']['destination'] + |
||||
|
exe_name + $cfg['linker']['bin_files']['extension'] + " #{linker[:options]}" |
||||
|
execute(cmd_str) |
||||
|
end |
||||
|
|
||||
|
def build_simulator_fields |
||||
|
return nil if $cfg['simulator'].nil? |
||||
|
if $cfg['simulator']['path'].nil? |
||||
|
command = '' |
||||
|
else |
||||
|
command = (tackit($cfg['simulator']['path']) + ' ') |
||||
|
end |
||||
|
if $cfg['simulator']['pre_support'].nil? |
||||
|
pre_support = '' |
||||
|
else |
||||
|
pre_support = squash('', $cfg['simulator']['pre_support']) |
||||
|
end |
||||
|
if $cfg['simulator']['post_support'].nil? |
||||
|
post_support = '' |
||||
|
else |
||||
|
post_support = squash('', $cfg['simulator']['post_support']) |
||||
|
end |
||||
|
return {:command => command, :pre_support => pre_support, :post_support => post_support} |
||||
|
end |
||||
|
|
||||
|
def execute(command_string, verbose=true, ok_to_fail=false) |
||||
|
report command_string |
||||
|
output = `#{command_string}`.chomp |
||||
|
report(output) if (verbose && !output.nil? && (output.length > 0)) |
||||
|
unless (!$?.nil? && $?.exitstatus.zero?) || ok_to_fail |
||||
|
raise "Command failed. (Returned #{$?.exitstatus})" |
||||
|
end |
||||
|
return output |
||||
|
end |
||||
|
|
||||
|
def report_summary |
||||
|
summary = UnityTestSummary.new |
||||
|
summary.root = HERE |
||||
|
results_glob = "#{$cfg['compiler']['build_path']}*.test*" |
||||
|
results_glob.gsub!(/\\/, '/') |
||||
|
results = Dir[results_glob] |
||||
|
summary.targets = results |
||||
|
report summary.run |
||||
|
raise "There were failures" if (summary.failures > 0) && $return_error_on_failures |
||||
|
end |
||||
|
|
||||
|
def run_tests(test_files) |
||||
|
|
||||
|
report 'Running system tests...' |
||||
|
|
||||
|
# Tack on TEST define for compiling unit tests |
||||
|
load_configuration($cfg_file) |
||||
|
test_defines = ['TEST'] |
||||
|
$cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil? |
||||
|
$cfg['compiler']['defines']['items'] << 'TEST' |
||||
|
|
||||
|
include_dirs = get_local_include_dirs |
||||
|
|
||||
|
# Build and execute each unit test |
||||
|
test_files.each do |test| |
||||
|
obj_list = [] |
||||
|
|
||||
|
# Detect dependencies and build required required modules |
||||
|
header_list = (extract_headers(test) + ['cmock.h'] + [ $cfg[:cmock][:unity_helper_path] ]).compact.uniq |
||||
|
header_list.each do |header| |
||||
|
|
||||
|
#create mocks if needed |
||||
|
if (header =~ /Mock/) |
||||
|
require "../../lib/cmock.rb" |
||||
|
@cmock ||= CMock.new($cfg_file) |
||||
|
@cmock.setup_mocks([$cfg['compiler']['source_path']+header.gsub('Mock','')]) |
||||
|
end |
||||
|
|
||||
|
end |
||||
|
|
||||
|
#compile all mocks |
||||
|
header_list.each do |header| |
||||
|
#compile source file header if it exists |
||||
|
src_file = find_source_file(header, include_dirs) |
||||
|
if !src_file.nil? |
||||
|
obj_list << compile(src_file, test_defines) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
# Build the test runner (generate if configured to do so) |
||||
|
test_base = File.basename(test, C_EXTENSION) |
||||
|
runner_name = test_base + '_Runner.c' |
||||
|
if $cfg['compiler']['runner_path'].nil? |
||||
|
runner_path = $cfg['compiler']['build_path'] + runner_name |
||||
|
test_gen = UnityTestRunnerGenerator.new($cfg_file) |
||||
|
test_gen.run(test, runner_path) |
||||
|
else |
||||
|
runner_path = $cfg['compiler']['runner_path'] + runner_name |
||||
|
end |
||||
|
|
||||
|
obj_list << compile(runner_path, test_defines) |
||||
|
|
||||
|
# Build the test module |
||||
|
obj_list << compile(test, test_defines) |
||||
|
|
||||
|
# Link the test executable |
||||
|
link_it(test_base, obj_list) |
||||
|
|
||||
|
# Execute unit test and generate results file |
||||
|
simulator = build_simulator_fields |
||||
|
executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] |
||||
|
if simulator.nil? |
||||
|
cmd_str = executable |
||||
|
else |
||||
|
cmd_str = "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}" |
||||
|
end |
||||
|
output = execute(cmd_str, true, true) |
||||
|
test_results = $cfg['compiler']['build_path'] + test_base |
||||
|
if output.match(/OK$/m).nil? |
||||
|
test_results += '.testfail' |
||||
|
else |
||||
|
test_results += '.testpass' |
||||
|
end |
||||
|
File.open(test_results, 'w') { |f| f.print output } |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def build_application(main) |
||||
|
|
||||
|
report "Building application..." |
||||
|
|
||||
|
obj_list = [] |
||||
|
load_configuration($cfg_file) |
||||
|
main_path = $cfg['compiler']['source_path'] + main + C_EXTENSION |
||||
|
|
||||
|
# Detect dependencies and build required required modules |
||||
|
include_dirs = get_local_include_dirs |
||||
|
extract_headers(main_path).each do |header| |
||||
|
src_file = find_source_file(header, include_dirs) |
||||
|
if !src_file.nil? |
||||
|
obj_list << compile(src_file) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
# Build the main source file |
||||
|
main_base = File.basename(main_path, C_EXTENSION) |
||||
|
obj_list << compile(main_path) |
||||
|
|
||||
|
# Create the executable |
||||
|
link_it(main_base, obj_list) |
||||
|
end |
||||
|
|
||||
|
end |
File diff suppressed because it is too large
@ -0,0 +1,42 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "AdcConductor.h" |
||||
|
#include "AdcModel.h" |
||||
|
#include "AdcHardware.h" |
||||
|
|
||||
|
void AdcConductor_Init(void) |
||||
|
{ |
||||
|
AdcHardware_Init(); |
||||
|
} |
||||
|
|
||||
|
void AdcConductor_Run(void) |
||||
|
{ |
||||
|
if (AdcModel_DoGetSample() && AdcHardware_GetSampleComplete()) |
||||
|
{ |
||||
|
AdcModel_ProcessInput(AdcHardware_GetSample()); |
||||
|
AdcHardware_StartConversion(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool AdcConductor_JustHereToTest(void) |
||||
|
{ |
||||
|
EXAMPLE_STRUCT_T ExampleStruct; |
||||
|
ExampleStruct.x = 5; |
||||
|
ExampleStruct.y = 7; |
||||
|
|
||||
|
return AdcModel_DoNothingExceptTestASpecialType(ExampleStruct); |
||||
|
} |
||||
|
|
||||
|
bool AdcConductor_AlsoHereToTest(void) |
||||
|
{ |
||||
|
EXAMPLE_STRUCT_T example = AdcModel_DoNothingExceptReturnASpecialType(); |
||||
|
|
||||
|
return ((example.x == 99) && (example.y == 1)); |
||||
|
} |
||||
|
|
||||
|
bool AdcConductor_YetAnotherTest(void) |
||||
|
{ |
||||
|
uint32 example = 3; |
||||
|
|
||||
|
return AdModel_DoNothingExceptTestPointers(&example); |
||||
|
} |
||||
|
|
@ -0,0 +1,11 @@ |
|||||
|
#ifndef _ADCCONDUCTOR_H |
||||
|
#define _ADCCONDUCTOR_H |
||||
|
|
||||
|
void AdcConductor_Init(void); |
||||
|
void AdcConductor_Run(void); |
||||
|
|
||||
|
bool AdcConductor_JustHereToTest(void); |
||||
|
bool AdcConductor_AlsoHereToTest(void); |
||||
|
bool AdcConductor_YetAnotherTest(void); |
||||
|
|
||||
|
#endif // _ADCCONDUCTOR_H
|
@ -0,0 +1,27 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "AdcHardware.h" |
||||
|
#include "AdcHardwareConfigurator.h" |
||||
|
#include "AdcTemperatureSensor.h" |
||||
|
|
||||
|
void AdcHardware_Init(void) |
||||
|
{ |
||||
|
Adc_Reset(); |
||||
|
Adc_ConfigureMode(); |
||||
|
Adc_EnableTemperatureChannel(); |
||||
|
Adc_StartTemperatureSensorConversion(); |
||||
|
} |
||||
|
|
||||
|
void AdcHardware_StartConversion(void) |
||||
|
{ |
||||
|
Adc_StartTemperatureSensorConversion(); |
||||
|
} |
||||
|
|
||||
|
bool AdcHardware_GetSampleComplete(void) |
||||
|
{ |
||||
|
return Adc_TemperatureSensorSampleReady(); |
||||
|
} |
||||
|
|
||||
|
uint16 AdcHardware_GetSample(void) |
||||
|
{ |
||||
|
return Adc_ReadTemperatureSensor(); |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#ifndef _ADCHARDWARE_H |
||||
|
#define _ADCHARDWARE_H |
||||
|
|
||||
|
void AdcHardware_Init(void); |
||||
|
void AdcHardware_StartConversion(void); |
||||
|
bool AdcHardware_GetSampleComplete(void); |
||||
|
uint16 AdcHardware_GetSample(void); |
||||
|
|
||||
|
#endif // _ADCHARDWARE_H
|
@ -0,0 +1,18 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "AdcHardwareConfigurator.h" |
||||
|
#include "ModelConfig.h" |
||||
|
|
||||
|
void Adc_Reset(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; |
||||
|
} |
||||
|
|
||||
|
void Adc_ConfigureMode(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_MR = (((uint32)11) << 8) | (((uint32)4) << 16); |
||||
|
} |
||||
|
|
||||
|
void Adc_EnableTemperatureChannel(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_CHER = 0x10; |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
#ifndef _ADCHARDWARECONFIGURATOR_H |
||||
|
#define _ADCHARDWARECONFIGURATOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Adc_Reset(void); |
||||
|
void Adc_ConfigureMode(void); |
||||
|
void Adc_EnableTemperatureChannel(void); |
||||
|
|
||||
|
#endif // _ADCHARDWARECONFIGURATOR_H
|
@ -0,0 +1,33 @@ |
|||||
|
#include "AdcModel.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
#include "TemperatureCalculator.h" |
||||
|
#include "TemperatureFilter.h" |
||||
|
|
||||
|
bool AdcModel_DoGetSample(void) |
||||
|
{ |
||||
|
return TaskScheduler_DoAdc(); |
||||
|
} |
||||
|
|
||||
|
void AdcModel_ProcessInput(uint16 millivolts) |
||||
|
{ |
||||
|
TemperatureFilter_ProcessInput(TemperatureCalculator_Calculate(millivolts)); |
||||
|
} |
||||
|
|
||||
|
bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct) |
||||
|
{ |
||||
|
//This doesn't really do anything. it's only here to make sure I can compare a struct.
|
||||
|
return FALSE; |
||||
|
} |
||||
|
bool AdModel_DoNothingExceptTestPointers(uint32* pExample) |
||||
|
{ |
||||
|
//This doesn't really do anything. it's only here to make sure I can compare a pointer value.
|
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
EXAMPLE_STRUCT_T AdcModel_DoNothingExceptReturnASpecialType(void) |
||||
|
{ |
||||
|
EXAMPLE_STRUCT_T example; //again, this just is here to test that I can return a struct
|
||||
|
example.x = 99; |
||||
|
example.y = 1; |
||||
|
return example; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
#ifndef _ADCMODEL_H |
||||
|
#define _ADCMODEL_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
bool AdcModel_DoGetSample(void); |
||||
|
void AdcModel_ProcessInput(uint16 millivolts); |
||||
|
|
||||
|
bool AdcModel_DoNothingExceptTestASpecialType(EXAMPLE_STRUCT_T ExampleStruct); |
||||
|
bool AdModel_DoNothingExceptTestPointers(uint32* pExample); |
||||
|
EXAMPLE_STRUCT_T AdcModel_DoNothingExceptReturnASpecialType(void); |
||||
|
|
||||
|
#endif // _ADCMODEL_H
|
@ -0,0 +1,51 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "AdcTemperatureSensor.h" |
||||
|
|
||||
|
static inline uint32 ConvertAdcCountsToPicovolts(uint32 counts); |
||||
|
static inline uint16 ConvertPicovoltsToMillivolts(uint32 picovolts); |
||||
|
|
||||
|
//
|
||||
|
// PUBLIC METHODS
|
||||
|
//
|
||||
|
|
||||
|
void Adc_StartTemperatureSensorConversion(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; |
||||
|
} |
||||
|
|
||||
|
bool Adc_TemperatureSensorSampleReady(void) |
||||
|
{ |
||||
|
return ((AT91C_BASE_ADC->ADC_SR & AT91C_ADC_EOC4) == AT91C_ADC_EOC4); |
||||
|
} |
||||
|
|
||||
|
uint16 Adc_ReadTemperatureSensor(void) |
||||
|
{ |
||||
|
uint32 picovolts = ConvertAdcCountsToPicovolts(AT91C_BASE_ADC->ADC_CDR4); |
||||
|
return ConvertPicovoltsToMillivolts(picovolts); |
||||
|
} |
||||
|
|
||||
|
//
|
||||
|
// PRIVATE HELPERS
|
||||
|
//
|
||||
|
|
||||
|
static inline uint32 ConvertAdcCountsToPicovolts(uint32 counts) |
||||
|
{ |
||||
|
// ADC bit weight at 10-bit resolution with 3.0V reference = 2.9296875 mV/LSB
|
||||
|
uint32 picovoltsPerAdcCount = 2929688; |
||||
|
|
||||
|
// Shift decimal point by 6 places to preserve accuracy in fixed-point math
|
||||
|
return counts * picovoltsPerAdcCount; |
||||
|
} |
||||
|
|
||||
|
static inline uint16 ConvertPicovoltsToMillivolts(uint32 picovolts) |
||||
|
{ |
||||
|
const uint32 halfMillivoltInPicovolts = 500000; |
||||
|
const uint32 picovoltsPerMillivolt = 1000000; |
||||
|
|
||||
|
// Add 0.5 mV to result so that truncation yields properly rounded result
|
||||
|
picovolts += halfMillivoltInPicovolts; |
||||
|
|
||||
|
// Divide appropriately to convert to millivolts
|
||||
|
return (uint16)(picovolts / picovoltsPerMillivolt); |
||||
|
} |
||||
|
|
@ -0,0 +1,10 @@ |
|||||
|
#ifndef _ADCTEMPERATURESENSOR_H |
||||
|
#define _ADCTEMPERATURESENSOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Adc_StartTemperatureSensorConversion(void); |
||||
|
bool Adc_TemperatureSensorSampleReady(void); |
||||
|
uint16 Adc_ReadTemperatureSensor(void); |
||||
|
|
||||
|
#endif // _ADCTEMPERATURESENSOR_H
|
@ -0,0 +1,25 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "Executor.h" |
||||
|
#include "Model.h" |
||||
|
#include "UsartConductor.h" |
||||
|
#include "TimerConductor.h" |
||||
|
#include "AdcConductor.h" |
||||
|
#include "IntrinsicsWrapper.h" |
||||
|
|
||||
|
|
||||
|
void Executor_Init(void) |
||||
|
{ |
||||
|
Model_Init(); |
||||
|
UsartConductor_Init(); |
||||
|
AdcConductor_Init(); |
||||
|
TimerConductor_Init(); |
||||
|
Interrupt_Enable(); |
||||
|
} |
||||
|
|
||||
|
bool Executor_Run(void) |
||||
|
{ |
||||
|
UsartConductor_Run(); |
||||
|
TimerConductor_Run(); |
||||
|
AdcConductor_Run(); |
||||
|
return TRUE; |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#ifndef _EXECUTOR_H |
||||
|
#define _EXECUTOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Executor_Init(void); |
||||
|
bool Executor_Run(void); |
||||
|
|
||||
|
#endif // _EXECUTOR_H
|
@ -0,0 +1,18 @@ |
|||||
|
#include "IntrinsicsWrapper.h" |
||||
|
#ifdef __ICCARM__ |
||||
|
#include <intrinsics.h> |
||||
|
#endif |
||||
|
|
||||
|
void Interrupt_Enable(void) |
||||
|
{ |
||||
|
#ifdef __ICCARM__ |
||||
|
__enable_interrupt(); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
void Interrupt_Disable(void) |
||||
|
{ |
||||
|
#ifdef __ICCARM__ |
||||
|
__disable_interrupt(); |
||||
|
#endif |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
#ifndef _INTRINSICS_WRAPPER_H |
||||
|
#define _INTRINSICS_WRAPPER_H |
||||
|
|
||||
|
void Interrupt_Enable(void); |
||||
|
void Interrupt_Disable(void); |
||||
|
|
||||
|
#endif // _INTRINSICS_WRAPPER_H
|
@ -0,0 +1,46 @@ |
|||||
|
#include "Types.h" |
||||
|
|
||||
|
#include "IntrinsicsWrapper.h" |
||||
|
#include "Executor.h" |
||||
|
|
||||
|
#include "Model.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
#include "TemperatureCalculator.h" |
||||
|
#include "TemperatureFilter.h" |
||||
|
|
||||
|
#include "UsartConductor.h" |
||||
|
#include "UsartHardware.h" |
||||
|
#include "UsartConfigurator.h" |
||||
|
#include "UsartPutChar.h" |
||||
|
#include "UsartModel.h" |
||||
|
#include "UsartBaudRateRegisterCalculator.h" |
||||
|
#include "UsartTransmitBufferStatus.h" |
||||
|
|
||||
|
#include "TimerConductor.h" |
||||
|
#include "TimerHardware.h" |
||||
|
#include "TimerConfigurator.h" |
||||
|
#include "TimerInterruptConfigurator.h" |
||||
|
#include "TimerInterruptHandler.h" |
||||
|
#include "TimerModel.h" |
||||
|
|
||||
|
#include "AdcConductor.h" |
||||
|
#include "AdcHardware.h" |
||||
|
#include "AdcHardwareConfigurator.h" |
||||
|
#include "AdcTemperatureSensor.h" |
||||
|
#include "AdcModel.h" |
||||
|
|
||||
|
int AppMain(void) |
||||
|
{ |
||||
|
Executor_Init(); |
||||
|
|
||||
|
while(Executor_Run()); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
#ifndef TEST |
||||
|
int main(void) |
||||
|
{ |
||||
|
return AppMain(); |
||||
|
} |
||||
|
#endif // TEST
|
@ -0,0 +1,7 @@ |
|||||
|
#ifndef _MAIN_H_ |
||||
|
#define _MAIN_H_ |
||||
|
|
||||
|
int AppMain(void); |
||||
|
int main(void); |
||||
|
|
||||
|
#endif // _MAIN_H_
|
@ -0,0 +1,10 @@ |
|||||
|
#include "Model.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
#include "TemperatureFilter.h" |
||||
|
|
||||
|
void Model_Init(void) |
||||
|
{ |
||||
|
TaskScheduler_Init(); |
||||
|
TemperatureFilter_Init(); |
||||
|
} |
||||
|
|
@ -0,0 +1,8 @@ |
|||||
|
#ifndef _MODEL_H |
||||
|
#define _MODEL_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Model_Init(void); |
||||
|
|
||||
|
#endif // _MODEL_H
|
@ -0,0 +1,7 @@ |
|||||
|
#ifndef _MODELCONFIG_H |
||||
|
#define _MODELCONFIG_H |
||||
|
|
||||
|
#define MASTER_CLOCK 48054857 // Master Clock
|
||||
|
#define USART0_BAUDRATE 115200 // USART Baudrate
|
||||
|
|
||||
|
#endif // _MODELCONFIG_H
|
@ -0,0 +1,72 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
|
||||
|
typedef struct _Task |
||||
|
{ |
||||
|
bool doIt; |
||||
|
uint32 period; |
||||
|
uint32 startTime; |
||||
|
} Task; |
||||
|
|
||||
|
typedef struct _TaskSchedulerInstance |
||||
|
{ |
||||
|
Task usart; |
||||
|
Task adc; |
||||
|
} TaskSchedulerInstance; |
||||
|
|
||||
|
static TaskSchedulerInstance this; |
||||
|
|
||||
|
void TaskScheduler_Init(void) |
||||
|
{ |
||||
|
this.usart.doIt = FALSE; |
||||
|
this.usart.startTime = 0; |
||||
|
|
||||
|
//The correct period
|
||||
|
this.usart.period = 1000; |
||||
|
|
||||
|
this.adc.doIt = FALSE; |
||||
|
this.adc.startTime = 0; |
||||
|
this.adc.period = 100; |
||||
|
} |
||||
|
|
||||
|
void TaskScheduler_Update(uint32 time) |
||||
|
{ |
||||
|
if ((time - this.usart.startTime) >= this.usart.period) |
||||
|
{ |
||||
|
this.usart.doIt = TRUE; |
||||
|
this.usart.startTime = time - (time % this.usart.period); |
||||
|
} |
||||
|
|
||||
|
if ((time - this.adc.startTime) >= this.adc.period) |
||||
|
{ |
||||
|
this.adc.doIt = TRUE; |
||||
|
this.adc.startTime = time - (time % this.adc.period); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool TaskScheduler_DoUsart(void) |
||||
|
{ |
||||
|
bool doIt = FALSE; |
||||
|
|
||||
|
if (this.usart.doIt) |
||||
|
{ |
||||
|
doIt = TRUE; |
||||
|
this.usart.doIt = FALSE; |
||||
|
} |
||||
|
|
||||
|
return doIt; |
||||
|
} |
||||
|
|
||||
|
bool TaskScheduler_DoAdc(void) |
||||
|
{ |
||||
|
bool doIt = FALSE; |
||||
|
|
||||
|
if (this.adc.doIt) |
||||
|
{ |
||||
|
doIt = TRUE; |
||||
|
this.adc.doIt = FALSE; |
||||
|
} |
||||
|
|
||||
|
return doIt; |
||||
|
} |
||||
|
|
@ -0,0 +1,11 @@ |
|||||
|
#ifndef _TASKSCHEDULER_H |
||||
|
#define _TASKSCHEDULER_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void TaskScheduler_Init(void); |
||||
|
void TaskScheduler_Update(uint32 time); |
||||
|
bool TaskScheduler_DoUsart(void); |
||||
|
bool TaskScheduler_DoAdc(void); |
||||
|
|
||||
|
#endif // _TASKSCHEDULER_H
|
@ -0,0 +1,27 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TemperatureCalculator.h" |
||||
|
#include <math.h> |
||||
|
|
||||
|
#ifndef logl |
||||
|
#define logl log |
||||
|
#endif |
||||
|
|
||||
|
float TemperatureCalculator_Calculate(uint16 millivolts) |
||||
|
{ |
||||
|
const double supply_voltage = 3.0; |
||||
|
const double series_resistance = 5000; |
||||
|
const double coefficient_A = 316589.698; |
||||
|
const double coefficient_B = -0.1382009; |
||||
|
double sensor_voltage = ((double)millivolts / 1000); |
||||
|
double resistance; |
||||
|
|
||||
|
if (millivolts == 0) |
||||
|
{ |
||||
|
return -INFINITY; |
||||
|
} |
||||
|
|
||||
|
// Series resistor is 5k Ohms; Reference voltage is 3.0V
|
||||
|
// R(t) = A * e^(B*t); R is resistance of thermisor; t is temperature in C
|
||||
|
resistance = ((supply_voltage * series_resistance) / sensor_voltage) - series_resistance; |
||||
|
return (float)(logl(resistance / coefficient_A) / coefficient_B); |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
#ifndef _TEMPERATURECALCULATOR_H |
||||
|
#define _TEMPERATURECALCULATOR_H |
||||
|
|
||||
|
float TemperatureCalculator_Calculate(uint16 millivolts); |
||||
|
|
||||
|
#endif // _TEMPERATURECALCULATOR_H
|
@ -0,0 +1,39 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TemperatureFilter.h" |
||||
|
#include <math.h> |
||||
|
|
||||
|
static bool initialized; |
||||
|
static float temperatureInCelcius; |
||||
|
|
||||
|
void TemperatureFilter_Init(void) |
||||
|
{ |
||||
|
initialized = FALSE; |
||||
|
temperatureInCelcius = -INFINITY; |
||||
|
} |
||||
|
|
||||
|
float TemperatureFilter_GetTemperatureInCelcius(void) |
||||
|
{ |
||||
|
return temperatureInCelcius; |
||||
|
} |
||||
|
|
||||
|
void TemperatureFilter_ProcessInput(float temperature) |
||||
|
{ |
||||
|
if (!initialized) |
||||
|
{ |
||||
|
temperatureInCelcius = temperature; |
||||
|
initialized = TRUE; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (temperature == +INFINITY || |
||||
|
temperature == -INFINITY || |
||||
|
temperature == +NAN || |
||||
|
temperature == -NAN) |
||||
|
{ |
||||
|
initialized = FALSE; |
||||
|
temperature = -INFINITY; |
||||
|
} |
||||
|
|
||||
|
temperatureInCelcius = (temperatureInCelcius * 0.75f) + (temperature * 0.25); |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
#ifndef _TEMPERATUREFILTER_H |
||||
|
#define _TEMPERATUREFILTER_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void TemperatureFilter_Init(void); |
||||
|
float TemperatureFilter_GetTemperatureInCelcius(void); |
||||
|
void TemperatureFilter_ProcessInput(float temperature); |
||||
|
|
||||
|
#endif // _TEMPERATUREFILTER_H
|
@ -0,0 +1,15 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TimerConductor.h" |
||||
|
#include "TimerModel.h" |
||||
|
#include "TimerHardware.h" |
||||
|
#include "TimerInterruptHandler.h" |
||||
|
|
||||
|
void TimerConductor_Init(void) |
||||
|
{ |
||||
|
TimerHardware_Init(); |
||||
|
} |
||||
|
|
||||
|
void TimerConductor_Run(void) |
||||
|
{ |
||||
|
TimerModel_UpdateTime(Timer_GetSystemTime()); |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#ifndef _TIMERCONDUCTOR_H |
||||
|
#define _TIMERCONDUCTOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void TimerConductor_Init(void); |
||||
|
void TimerConductor_Run(void); |
||||
|
|
||||
|
#endif // _TIMERCONDUCTOR_H
|
@ -0,0 +1,51 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TimerConfigurator.h" |
||||
|
#include "TimerInterruptConfigurator.h" |
||||
|
|
||||
|
void Timer_EnablePeripheralClocks(void) |
||||
|
{ |
||||
|
AT91C_BASE_PMC->PMC_PCER = TIMER0_CLOCK_ENABLE | PIOB_CLOCK_ENABLE; |
||||
|
} |
||||
|
|
||||
|
void Timer_Reset(void) |
||||
|
{ |
||||
|
uint32 dummy; |
||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; |
||||
|
AT91C_BASE_TC0->TC_IDR = 0xffffffff; |
||||
|
dummy = AT91C_BASE_TC0->TC_SR; |
||||
|
dummy = dummy; |
||||
|
} |
||||
|
|
||||
|
void Timer_ConfigureMode(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CMR = 0x000CC004; // ACPC=toggle TIOA on RC compare; mode=WAVE; WAVE_SEL=UP w/auto-trigger on RC compare; clock=MCK/1024
|
||||
|
} |
||||
|
|
||||
|
void Timer_ConfigurePeriod(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_RC = 469; // 10ms period for timer clock source of MCK/1024 with MCK=48054857
|
||||
|
} |
||||
|
|
||||
|
void Timer_EnableOutputPin(void) |
||||
|
{ |
||||
|
AT91C_BASE_PIOB->PIO_PDR = TIOA0_PIN_MASK; |
||||
|
} |
||||
|
|
||||
|
void Timer_Enable(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN; |
||||
|
} |
||||
|
|
||||
|
void Timer_ConfigureInterruptHandler(void) |
||||
|
{ |
||||
|
Timer_DisableInterrupt(); |
||||
|
Timer_ResetSystemTime(); |
||||
|
Timer_ConfigureInterrupt(); |
||||
|
Timer_EnableInterrupt(); |
||||
|
} |
||||
|
|
||||
|
void Timer_Start(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; |
||||
|
} |
||||
|
|
@ -0,0 +1,15 @@ |
|||||
|
#ifndef _TIMERCONFIGURATOR_H |
||||
|
#define _TIMERCONFIGURATOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Timer_EnablePeripheralClocks(void); |
||||
|
void Timer_Reset(void); |
||||
|
void Timer_ConfigureMode(void); |
||||
|
void Timer_ConfigurePeriod(void); |
||||
|
void Timer_EnableOutputPin(void); |
||||
|
void Timer_Enable(void); |
||||
|
void Timer_ConfigureInterruptHandler(void); |
||||
|
void Timer_Start(void); |
||||
|
|
||||
|
#endif // _TIMERCONFIGURATOR_H
|
@ -0,0 +1,15 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TimerHardware.h" |
||||
|
#include "TimerConfigurator.h" |
||||
|
|
||||
|
void TimerHardware_Init(void) |
||||
|
{ |
||||
|
Timer_EnablePeripheralClocks(); |
||||
|
Timer_Reset(); |
||||
|
Timer_ConfigureMode(); |
||||
|
Timer_ConfigurePeriod(); |
||||
|
Timer_EnableOutputPin(); |
||||
|
Timer_Enable(); |
||||
|
Timer_ConfigureInterruptHandler(); |
||||
|
Timer_Start(); |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
#ifndef _TIMERHARDWARE_H |
||||
|
#define _TIMERHARDWARE_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void TimerHardware_Init(void); |
||||
|
|
||||
|
#endif // _TIMERHARDWARE_H
|
@ -0,0 +1,55 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TimerInterruptConfigurator.h" |
||||
|
#include "TimerInterruptHandler.h" |
||||
|
|
||||
|
static inline void SetInterruptHandler(void); |
||||
|
static inline void ConfigureInterruptSourceModeRegister(void); |
||||
|
static inline void ClearInterrupt(void); |
||||
|
static inline void EnableCompareInterruptForRegisterC(void); |
||||
|
|
||||
|
void Timer_DisableInterrupt(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_IDCR = TIMER0_ID_MASK; |
||||
|
} |
||||
|
|
||||
|
void Timer_ResetSystemTime(void) |
||||
|
{ |
||||
|
Timer_SetSystemTime(0); |
||||
|
} |
||||
|
|
||||
|
void Timer_ConfigureInterrupt(void) |
||||
|
{ |
||||
|
SetInterruptHandler(); |
||||
|
ConfigureInterruptSourceModeRegister(); |
||||
|
ClearInterrupt(); |
||||
|
EnableCompareInterruptForRegisterC(); |
||||
|
} |
||||
|
|
||||
|
void Timer_EnableInterrupt(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_IECR = TIMER0_ID_MASK; |
||||
|
} |
||||
|
|
||||
|
//
|
||||
|
// Helpers
|
||||
|
//
|
||||
|
|
||||
|
static inline void SetInterruptHandler(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (uint32)Timer_InterruptHandler; |
||||
|
} |
||||
|
|
||||
|
static inline void ConfigureInterruptSourceModeRegister(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 1; |
||||
|
} |
||||
|
|
||||
|
static inline void ClearInterrupt(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_ICCR = TIMER0_ID_MASK; |
||||
|
} |
||||
|
|
||||
|
static inline void EnableCompareInterruptForRegisterC(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
#ifndef _TIMERINTERRUPTCONFIGURATOR_H |
||||
|
#define _TIMERINTERRUPTCONFIGURATOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
#define TIMER0_ID_MASK (((uint32)0x1) << AT91C_ID_TC0) |
||||
|
|
||||
|
void Timer_DisableInterrupt(void); |
||||
|
void Timer_ResetSystemTime(void); |
||||
|
void Timer_ConfigureInterrupt(void); |
||||
|
void Timer_EnableInterrupt(void); |
||||
|
|
||||
|
#endif // _TIMERINTERRUPTCONFIGURATOR_H
|
@ -0,0 +1,25 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TimerInterruptHandler.h" |
||||
|
#include "TimerInterruptConfigurator.h" |
||||
|
|
||||
|
static uint32 systemTime; |
||||
|
|
||||
|
void Timer_SetSystemTime(uint32 time) |
||||
|
{ |
||||
|
systemTime = time; |
||||
|
} |
||||
|
|
||||
|
uint32 Timer_GetSystemTime(void) |
||||
|
{ |
||||
|
return systemTime; |
||||
|
} |
||||
|
|
||||
|
void Timer_InterruptHandler(void) |
||||
|
{ |
||||
|
uint32 status = AT91C_BASE_TC0->TC_SR; |
||||
|
if (status & AT91C_TC_CPCS) |
||||
|
{ |
||||
|
systemTime += 10; |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,10 @@ |
|||||
|
#ifndef _TIMERINTERRUPTHANDLER_H |
||||
|
#define _TIMERINTERRUPTHANDLER_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Timer_SetSystemTime(uint32 time); |
||||
|
uint32 Timer_GetSystemTime(void); |
||||
|
void Timer_InterruptHandler(void); |
||||
|
|
||||
|
#endif // _TIMERINTERRUPTHANDLER_H
|
@ -0,0 +1,9 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "TimerModel.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
|
||||
|
void TimerModel_UpdateTime(uint32 systemTime) |
||||
|
{ |
||||
|
TaskScheduler_Update(systemTime); |
||||
|
} |
||||
|
|
@ -0,0 +1,8 @@ |
|||||
|
#ifndef _TIMERMODEL_H |
||||
|
#define _TIMERMODEL_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void TimerModel_UpdateTime(uint32 systemTime); |
||||
|
|
||||
|
#endif // _TIMERMODEL_H
|
@ -0,0 +1,103 @@ |
|||||
|
#ifndef _MYTYPES_H_ |
||||
|
#define _MYTYPES_H_ |
||||
|
|
||||
|
#include "AT91SAM7X256.h" |
||||
|
#include <math.h> |
||||
|
|
||||
|
#ifndef __monitor |
||||
|
#define __monitor |
||||
|
#endif |
||||
|
|
||||
|
// Peripheral Helper Definitions
|
||||
|
#define USART0_CLOCK_ENABLE (AT91C_ID_US0) |
||||
|
#define USART0_TX_PIN (AT91C_PA1_TXD0) |
||||
|
#define TIMER0_CLOCK_ENABLE (((uint32)0x1) << AT91C_ID_TC0) |
||||
|
#define PIOA_CLOCK_ENABLE (((uint32)0x1) << AT91C_ID_PIOA) |
||||
|
#define PIOB_CLOCK_ENABLE (((uint32)0x1) << AT91C_ID_PIOB) |
||||
|
#define TIOA0_PIN_MASK (((uint32)0x1) << 23) // Timer/Counter Output Pin
|
||||
|
|
||||
|
// Application Type Definitions
|
||||
|
typedef unsigned int uint32; |
||||
|
typedef int int32; |
||||
|
typedef unsigned short uint16; |
||||
|
typedef short int16; |
||||
|
typedef unsigned char uint8; |
||||
|
typedef char int8; |
||||
|
typedef char bool; |
||||
|
|
||||
|
// Application Special Value Definitions
|
||||
|
#ifndef TRUE |
||||
|
#define TRUE (1) |
||||
|
#endif |
||||
|
#ifndef FALSE |
||||
|
#define FALSE (0) |
||||
|
#endif |
||||
|
#ifndef NULL |
||||
|
#define NULL (0) |
||||
|
#endif // NULL
|
||||
|
#define DONT_CARE (0) |
||||
|
|
||||
|
#ifndef INFINITY |
||||
|
#define INFINITY (1.0 / 0.0) |
||||
|
#endif |
||||
|
|
||||
|
#ifndef NAN |
||||
|
#define NAN (0.0 / 0.0) |
||||
|
#endif |
||||
|
|
||||
|
// MIN/MAX Definitions for Standard Types
|
||||
|
#ifndef INT8_MAX |
||||
|
#define INT8_MAX 127 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef INT8_MIN |
||||
|
#define INT8_MIN (-128) |
||||
|
#endif |
||||
|
|
||||
|
#ifndef UINT8_MAX |
||||
|
#define UINT8_MAX 0xFFU |
||||
|
#endif |
||||
|
|
||||
|
#ifndef UINT8_MIN |
||||
|
#define UINT8_MIN 0x00U |
||||
|
#endif |
||||
|
|
||||
|
#ifndef INT16_MAX |
||||
|
#define INT16_MAX 32767 |
||||
|
#endif |
||||
|
|
||||
|
#ifndef INT16_MIN |
||||
|
#define INT16_MIN (-32768) |
||||
|
#endif |
||||
|
|
||||
|
#ifndef UINT16_MAX |
||||
|
#define UINT16_MAX 0xFFFFU |
||||
|
#endif |
||||
|
|
||||
|
#ifndef UINT16_MIN |
||||
|
#define UINT16_MIN 0x0000U |
||||
|
#endif |
||||
|
|
||||
|
#ifndef INT32_MAX |
||||
|
#define INT32_MAX 0x7FFFFFFF |
||||
|
#endif |
||||
|
|
||||
|
#ifndef INT32_MIN |
||||
|
#define INT32_MIN (-INT32_MAX - 1) |
||||
|
#endif |
||||
|
|
||||
|
#ifndef UINT32_MAX |
||||
|
#define UINT32_MAX 0xFFFFFFFFU |
||||
|
#endif |
||||
|
|
||||
|
#ifndef UINT32_MIN |
||||
|
#define UINT32_MIN 0x00000000U |
||||
|
#endif |
||||
|
|
||||
|
typedef struct _EXAMPLE_STRUCT_T |
||||
|
{ |
||||
|
int x; |
||||
|
int y; |
||||
|
} EXAMPLE_STRUCT_T; |
||||
|
|
||||
|
#endif // _MYTYPES_H_
|
@ -0,0 +1,18 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartBaudRateRegisterCalculator.h" |
||||
|
|
||||
|
uint8 UsartModel_CalculateBaudRateRegisterSetting(uint32 masterClock, uint32 baudRate) |
||||
|
{ |
||||
|
uint32 registerSetting = ((masterClock * 10) / (baudRate * 16)); |
||||
|
|
||||
|
if ((registerSetting % 10) >= 5) |
||||
|
{ |
||||
|
registerSetting = (registerSetting / 10) + 1; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
registerSetting /= 10; |
||||
|
} |
||||
|
|
||||
|
return (uint8)registerSetting; |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
#ifndef _USARTBAUDRATEREGISTERCALCULATOR_H |
||||
|
#define _USARTBAUDRATEREGISTERCALCULATOR_H |
||||
|
|
||||
|
uint8 UsartModel_CalculateBaudRateRegisterSetting(uint32 masterClock, uint32 baudRate); |
||||
|
|
||||
|
#endif // _USARTBAUDRATEREGISTERCALCULATOR_H
|
@ -0,0 +1,21 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartConductor.h" |
||||
|
#include "UsartHardware.h" |
||||
|
#include "UsartModel.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
|
||||
|
void UsartConductor_Init(void) |
||||
|
{ |
||||
|
UsartHardware_Init(UsartModel_GetBaudRateRegisterSetting()); |
||||
|
UsartHardware_TransmitString(UsartModel_GetWakeupMessage()); |
||||
|
} |
||||
|
|
||||
|
void UsartConductor_Run(void) |
||||
|
{ |
||||
|
char* temp; |
||||
|
if (TaskScheduler_DoUsart()) |
||||
|
{ |
||||
|
temp = UsartModel_GetFormattedTemperature(); |
||||
|
UsartHardware_TransmitString(temp); |
||||
|
} |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
#ifndef _USARTCONDUCTOR_H |
||||
|
#define _USARTCONDUCTOR_H |
||||
|
|
||||
|
void UsartConductor_Init(void); |
||||
|
void UsartConductor_Run(void); |
||||
|
|
||||
|
#endif // _USARTCONDUCTOR_H
|
@ -0,0 +1,39 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartConfigurator.h" |
||||
|
|
||||
|
void Usart_ConfigureUsartIO(void) |
||||
|
{ |
||||
|
AT91C_BASE_PIOA->PIO_ASR = USART0_TX_PIN; |
||||
|
AT91C_BASE_PIOA->PIO_BSR = 0; |
||||
|
AT91C_BASE_PIOA->PIO_PDR = USART0_TX_PIN; |
||||
|
} |
||||
|
|
||||
|
void Usart_EnablePeripheralClock(void) |
||||
|
{ |
||||
|
AT91C_BASE_PMC->PMC_PCER = ((uint32)1) << USART0_CLOCK_ENABLE; |
||||
|
} |
||||
|
|
||||
|
void Usart_Reset(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_IDR = 0xffffffff; |
||||
|
AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; |
||||
|
} |
||||
|
|
||||
|
void Usart_ConfigureMode(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL | |
||||
|
AT91C_US_NBSTOP_1_BIT | |
||||
|
AT91C_US_PAR_NONE | |
||||
|
AT91C_US_CHRL_8_BITS | |
||||
|
AT91C_US_CLKS_CLOCK; |
||||
|
} |
||||
|
|
||||
|
void Usart_SetBaudRateRegister(uint8 baudRateRegisterSetting) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_BRGR = baudRateRegisterSetting; |
||||
|
} |
||||
|
|
||||
|
void Usart_Enable(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_CR = AT91C_US_TXEN; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
#ifndef _USARTCONFIGURATOR_H |
||||
|
#define _USARTCONFIGURATOR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Usart_ConfigureUsartIO(void); |
||||
|
void Usart_EnablePeripheralClock(void); |
||||
|
void Usart_Reset(void); |
||||
|
void Usart_ConfigureMode(void); |
||||
|
void Usart_SetBaudRateRegister(uint8 baudRateRegisterSetting); |
||||
|
void Usart_Enable(void); |
||||
|
|
||||
|
#endif // _USARTCONFIGURATOR_H
|
@ -0,0 +1,22 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartHardware.h" |
||||
|
#include "UsartConfigurator.h" |
||||
|
#include "UsartPutChar.h" |
||||
|
|
||||
|
void UsartHardware_Init(uint8 baudRateRegisterSetting) |
||||
|
{ |
||||
|
Usart_ConfigureUsartIO(); |
||||
|
Usart_EnablePeripheralClock(); |
||||
|
Usart_Reset(); |
||||
|
Usart_ConfigureMode(); |
||||
|
Usart_SetBaudRateRegister(baudRateRegisterSetting); |
||||
|
Usart_Enable(); |
||||
|
} |
||||
|
|
||||
|
void UsartHardware_TransmitString(char* data) |
||||
|
{ |
||||
|
while(*data != NULL) |
||||
|
{ |
||||
|
Usart_PutChar(*data++); |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#ifndef _USARTHARDWARE_H |
||||
|
#define _USARTHARDWARE_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void UsartHardware_Init(uint8 baudRateRegisterSetting); |
||||
|
void UsartHardware_TransmitString(char* data); |
||||
|
|
||||
|
#endif // _USARTHARDWARE_H
|
@ -0,0 +1,34 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartModel.h" |
||||
|
#include "ModelConfig.h" |
||||
|
#include "UsartBaudRateRegisterCalculator.h" |
||||
|
#include "TemperatureFilter.h" |
||||
|
#include <stdio.h> |
||||
|
#include <math.h> |
||||
|
|
||||
|
char formattedTemperature[32]; |
||||
|
char* wakeup = "It's Awesome Time!\n"; |
||||
|
|
||||
|
uint8 UsartModel_GetBaudRateRegisterSetting(void) |
||||
|
{ |
||||
|
return UsartModel_CalculateBaudRateRegisterSetting(MASTER_CLOCK, USART0_BAUDRATE); |
||||
|
} |
||||
|
|
||||
|
char* UsartModel_GetFormattedTemperature(void) |
||||
|
{ |
||||
|
float temperature = TemperatureFilter_GetTemperatureInCelcius(); |
||||
|
if (temperature == -INFINITY) |
||||
|
{ |
||||
|
sprintf(formattedTemperature, "%s", "Temperature sensor failure!\n"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
sprintf(formattedTemperature, "%.1f C\n", temperature); |
||||
|
} |
||||
|
return formattedTemperature; |
||||
|
} |
||||
|
|
||||
|
char* UsartModel_GetWakeupMessage(void) |
||||
|
{ |
||||
|
return wakeup; |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
#ifndef _USARTMODEL_H |
||||
|
#define _USARTMODEL_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
uint8 UsartModel_GetBaudRateRegisterSetting(void); |
||||
|
char* UsartModel_GetFormattedTemperature(void); |
||||
|
char* UsartModel_GetWakeupMessage(void); |
||||
|
|
||||
|
#endif // _USARTMODEL_H
|
@ -0,0 +1,16 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartPutChar.h" |
||||
|
#include "UsartTransmitBufferStatus.h" |
||||
|
#ifdef SIMULATE |
||||
|
#include <stdio.h> |
||||
|
#endif |
||||
|
|
||||
|
void Usart_PutChar(char data) |
||||
|
{ |
||||
|
while(!Usart_ReadyToTransmit()); |
||||
|
#ifdef SIMULATE |
||||
|
printf("%c", data); |
||||
|
#else |
||||
|
AT91C_BASE_US0->US_THR = data; |
||||
|
#endif |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
#ifndef _USARTPUT_HAR_H |
||||
|
#define _USARTPUT_HAR_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
void Usart_PutChar(char data); |
||||
|
|
||||
|
#endif // _USARTPUT_HAR_H
|
@ -0,0 +1,7 @@ |
|||||
|
#include "Types.h" |
||||
|
#include "UsartTransmitBufferStatus.h" |
||||
|
|
||||
|
bool Usart_ReadyToTransmit(void) |
||||
|
{ |
||||
|
return (AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY) > 0; |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
#ifndef _USARTTRANSMITBUFFERSTATUS_H |
||||
|
#define _USARTTRANSMITBUFFERSTATUS_H |
||||
|
|
||||
|
#include "Types.h" |
||||
|
|
||||
|
bool Usart_ReadyToTransmit(void); |
||||
|
|
||||
|
#endif // _USARTTRANSMITBUFFERSTATUS_H
|
@ -0,0 +1,121 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "UnityHelper.h" |
||||
|
#include "Types.h" |
||||
|
#include "Types.h" |
||||
|
#include "AdcConductor.h" |
||||
|
#include "MockAdcModel.h" |
||||
|
#include "MockAdcHardware.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldCallHardwareInit(void) |
||||
|
{ |
||||
|
AdcHardware_Init_Expect(); |
||||
|
AdcConductor_Init(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldNotDoAnythingIfItIsNotTime(void) |
||||
|
{ |
||||
|
AdcModel_DoGetSample_ExpectAndReturn(FALSE); |
||||
|
|
||||
|
AdcConductor_Run(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldNotPassAdcResultToModelIfSampleIsNotComplete(void) |
||||
|
{ |
||||
|
AdcModel_DoGetSample_ExpectAndReturn(TRUE); |
||||
|
AdcHardware_GetSampleComplete_ExpectAndReturn(FALSE); |
||||
|
|
||||
|
AdcConductor_Run(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldGetLatestSampleFromAdcAndPassItToModelAndStartNewConversionWhenItIsTime(void) |
||||
|
{ |
||||
|
AdcModel_DoGetSample_ExpectAndReturn(TRUE); |
||||
|
AdcHardware_GetSampleComplete_ExpectAndReturn(TRUE); |
||||
|
AdcHardware_GetSample_ExpectAndReturn(293U); |
||||
|
AdcModel_ProcessInput_Expect(293U); |
||||
|
AdcHardware_StartConversion_Expect(); |
||||
|
|
||||
|
AdcConductor_Run(); |
||||
|
} |
||||
|
|
||||
|
void testJustHereToTest_Should_ProperlyPassAStructAndVerifyIt(void) |
||||
|
{ |
||||
|
EXAMPLE_STRUCT_T TestStruct; |
||||
|
TestStruct.x = 5; |
||||
|
TestStruct.y = 7; |
||||
|
|
||||
|
AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE); |
||||
|
|
||||
|
TEST_ASSERT_TRUE(AdcConductor_JustHereToTest()); |
||||
|
} |
||||
|
|
||||
|
//void testJustHereToTest_Should_FailThisTestIfYouUncommentXIsBecauseItsWrong(void)
|
||||
|
//{
|
||||
|
// EXAMPLE_STRUCT_T TestStruct;
|
||||
|
// TestStruct.x = 6;
|
||||
|
// TestStruct.y = 7;
|
||||
|
//
|
||||
|
// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE);
|
||||
|
//
|
||||
|
// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest());
|
||||
|
//}
|
||||
|
//
|
||||
|
//void testJustHereToTest_Should_FailThisTestIfYouUncommentYIsBecauseItsWrong(void)
|
||||
|
//{
|
||||
|
// EXAMPLE_STRUCT_T TestStruct;
|
||||
|
// TestStruct.x = 5;
|
||||
|
// TestStruct.y = 8;
|
||||
|
//
|
||||
|
// AdcModel_DoNothingExceptTestASpecialType_ExpectAndReturn(TestStruct, TRUE);
|
||||
|
//
|
||||
|
// TEST_ASSERT_TRUE(AdcConductor_JustHereToTest());
|
||||
|
//}
|
||||
|
|
||||
|
void test_AdcConductor_AlsoHereToTest_Should_ProperlyReturnAStructAsExpected1(void) |
||||
|
{ |
||||
|
EXAMPLE_STRUCT_T TestStruct; |
||||
|
TestStruct.x = 99; |
||||
|
TestStruct.y = 1; |
||||
|
|
||||
|
AdcModel_DoNothingExceptReturnASpecialType_ExpectAndReturn(TestStruct); |
||||
|
|
||||
|
TEST_ASSERT_TRUE(AdcConductor_AlsoHereToTest()); |
||||
|
} |
||||
|
|
||||
|
void test_AdcConductor_AlsoHereToTest_Should_ProperlyReturnAStructAsExpected2(void) |
||||
|
{ |
||||
|
EXAMPLE_STRUCT_T TestStruct; |
||||
|
TestStruct.x = 98; |
||||
|
TestStruct.y = 1; |
||||
|
|
||||
|
AdcModel_DoNothingExceptReturnASpecialType_ExpectAndReturn(TestStruct); |
||||
|
|
||||
|
TEST_ASSERT_FALSE(AdcConductor_AlsoHereToTest()); |
||||
|
} |
||||
|
|
||||
|
void test_AdcConductor_YetAnotherTest_Should_VerifyThatPointersToStructsAreTestable(void) |
||||
|
{ |
||||
|
uint32 TestNum = 3; |
||||
|
|
||||
|
AdModel_DoNothingExceptTestPointers_ExpectAndReturn(&TestNum, TRUE); |
||||
|
|
||||
|
TEST_ASSERT_TRUE(AdcConductor_YetAnotherTest()); |
||||
|
} |
||||
|
|
||||
|
//void test_AdcConductor_YetAnotherTest_Should_FailIfYouUncommentThisTestBecauseTheValuePointedToIsWrong(void)
|
||||
|
//{
|
||||
|
// uint32 TestNum = 7;
|
||||
|
//
|
||||
|
// AdModel_DoNothingExceptTestPointers_ExpectAndReturn(&TestNum, FALSE);
|
||||
|
//
|
||||
|
// TEST_ASSERT_FALSE(AdcConductor_YetAnotherTest());
|
||||
|
//}
|
||||
|
|
@ -0,0 +1,44 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "AdcHardware.h" |
||||
|
#include "MockAdcHardwareConfigurator.h" |
||||
|
#include "MockAdcTemperatureSensor.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldDelegateToConfiguratorAndTemperatureSensor(void) |
||||
|
{ |
||||
|
Adc_Reset_Expect(); |
||||
|
Adc_ConfigureMode_Expect(); |
||||
|
Adc_EnableTemperatureChannel_Expect(); |
||||
|
Adc_StartTemperatureSensorConversion_Expect(); |
||||
|
|
||||
|
AdcHardware_Init(); |
||||
|
} |
||||
|
|
||||
|
void testGetSampleCompleteShouldReturn_FALSE_WhenTemperatureSensorSampleReadyReturns_FALSE(void) |
||||
|
{ |
||||
|
Adc_TemperatureSensorSampleReady_ExpectAndReturn(FALSE); |
||||
|
TEST_ASSERT(!AdcHardware_GetSampleComplete()); |
||||
|
} |
||||
|
|
||||
|
void testGetSampleCompleteShouldReturn_TRUE_WhenTemperatureSensorSampleReadyReturns_TRUE(void) |
||||
|
{ |
||||
|
Adc_TemperatureSensorSampleReady_ExpectAndReturn(TRUE); |
||||
|
TEST_ASSERT(AdcHardware_GetSampleComplete()); |
||||
|
} |
||||
|
|
||||
|
void testGetSampleShouldDelegateToAdcTemperatureSensor(void) |
||||
|
{ |
||||
|
uint16 sample; |
||||
|
Adc_ReadTemperatureSensor_ExpectAndReturn(847); |
||||
|
|
||||
|
sample = AdcHardware_GetSample(); |
||||
|
TEST_ASSERT_EQUAL(847, sample); |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "AdcHardwareConfigurator.h" |
||||
|
#include "AT91SAM7X256.h" |
||||
|
#include "ModelConfig.h" |
||||
|
|
||||
|
AT91S_ADC AdcPeripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testResetShouldResetTheAdcConverterPeripheral(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_CR = 0; |
||||
|
Adc_Reset(); |
||||
|
TEST_ASSERT_EQUAL(AT91C_ADC_SWRST, AT91C_BASE_ADC->ADC_CR); |
||||
|
} |
||||
|
|
||||
|
void testConfigureModeShouldSetAdcModeRegisterAppropriately(void) |
||||
|
{ |
||||
|
uint32 prescaler = (MASTER_CLOCK / (2 * 2000000)) - 1; // 5MHz ADC clock
|
||||
|
|
||||
|
AT91C_BASE_ADC->ADC_MR = 0; |
||||
|
|
||||
|
Adc_ConfigureMode(); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL(prescaler, (AT91C_BASE_ADC->ADC_MR & AT91C_ADC_PRESCAL) >> 8); |
||||
|
} |
||||
|
|
||||
|
void testEnableTemperatureChannelShouldEnableTheAppropriateAdcInput(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_CHER = 0; |
||||
|
|
||||
|
Adc_EnableTemperatureChannel(); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL(0x1 << 4, AT91C_BASE_ADC->ADC_CHER); |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "AdcModel.h" |
||||
|
#include "MockTaskScheduler.h" |
||||
|
#include "MockTemperatureCalculator.h" |
||||
|
#include "MockTemperatureFilter.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testDoGetSampleShouldReturn_FALSE_WhenTaskSchedulerReturns_FALSE(void) |
||||
|
{ |
||||
|
TaskScheduler_DoAdc_ExpectAndReturn(FALSE); |
||||
|
TEST_ASSERT_EQUAL(FALSE, AdcModel_DoGetSample()); |
||||
|
} |
||||
|
|
||||
|
void testDoGetSampleShouldReturn_TRUE_WhenTaskSchedulerReturns_TRUE(void) |
||||
|
{ |
||||
|
TaskScheduler_DoAdc_ExpectAndReturn(TRUE); |
||||
|
TEST_ASSERT_EQUAL(TRUE, AdcModel_DoGetSample()); |
||||
|
} |
||||
|
|
||||
|
void testProcessInputShouldDelegateToTemperatureCalculatorAndPassResultToFilter(void) |
||||
|
{ |
||||
|
TemperatureCalculator_Calculate_ExpectAndReturn(21473, 23.5f); |
||||
|
TemperatureFilter_ProcessInput_Expect(23.5f); |
||||
|
AdcModel_ProcessInput(21473); |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "AdcTemperatureSensor.h" |
||||
|
#include "AT91SAM7X256.h" |
||||
|
|
||||
|
AT91S_ADC AdcPeripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testShouldStartTemperatureSensorConversionWhenTriggered(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_CR = 0; |
||||
|
Adc_StartTemperatureSensorConversion(); |
||||
|
TEST_ASSERT_EQUAL(AT91C_ADC_START, AT91C_BASE_ADC->ADC_CR); |
||||
|
} |
||||
|
|
||||
|
void testTemperatureSensorSampleReadyShouldReturnChannelConversionCompletionStatus(void) |
||||
|
{ |
||||
|
AT91C_BASE_ADC->ADC_SR = 0; |
||||
|
TEST_ASSERT_EQUAL(FALSE, Adc_TemperatureSensorSampleReady()); |
||||
|
AT91C_BASE_ADC->ADC_SR = ~AT91C_ADC_EOC4; |
||||
|
TEST_ASSERT_EQUAL(FALSE, Adc_TemperatureSensorSampleReady()); |
||||
|
AT91C_BASE_ADC->ADC_SR = AT91C_ADC_EOC4; |
||||
|
TEST_ASSERT_EQUAL(TRUE, Adc_TemperatureSensorSampleReady()); |
||||
|
AT91C_BASE_ADC->ADC_SR = 0xffffffff; |
||||
|
TEST_ASSERT_EQUAL(TRUE, Adc_TemperatureSensorSampleReady()); |
||||
|
} |
||||
|
|
||||
|
void testReadTemperatureSensorShouldFetchAndTranslateLatestReadingToMillivolts(void) |
||||
|
{ |
||||
|
uint16 result; |
||||
|
|
||||
|
// ADC bit weight at 10-bit resolution with 3.0V reference = 2.9296875 mV/LSB
|
||||
|
AT91C_BASE_ADC->ADC_CDR4 = 138; |
||||
|
result = Adc_ReadTemperatureSensor(); |
||||
|
TEST_ASSERT_EQUAL(404, result); |
||||
|
|
||||
|
AT91C_BASE_ADC->ADC_CDR4 = 854; |
||||
|
result = Adc_ReadTemperatureSensor(); |
||||
|
TEST_ASSERT_EQUAL(2502, result); |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "Executor.h" |
||||
|
#include "MockModel.h" |
||||
|
#include "MockUsartConductor.h" |
||||
|
#include "MockAdcConductor.h" |
||||
|
#include "MockTimerConductor.h" |
||||
|
#include "MockIntrinsicsWrapper.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldCallInitOfAllConductorsAndTheModel(void) |
||||
|
{ |
||||
|
Model_Init_Expect(); |
||||
|
UsartConductor_Init_Expect(); |
||||
|
AdcConductor_Init_Expect(); |
||||
|
TimerConductor_Init_Expect(); |
||||
|
Interrupt_Enable_Expect(); |
||||
|
|
||||
|
Executor_Init(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldCallRunForEachConductorAndReturnTrueAlways(void) |
||||
|
{ |
||||
|
UsartConductor_Run_Expect(); |
||||
|
TimerConductor_Run_Expect(); |
||||
|
AdcConductor_Run_Expect(); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL(TRUE, Executor_Run()); |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "MockExecutor.h" |
||||
|
#include "Main.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testMainShouldCallExecutorInitAndContinueToCallExecutorRunUntilHalted(void) |
||||
|
{ |
||||
|
Executor_Init_Expect(); |
||||
|
Executor_Run_ExpectAndReturn(TRUE); |
||||
|
Executor_Run_ExpectAndReturn(TRUE); |
||||
|
Executor_Run_ExpectAndReturn(TRUE); |
||||
|
Executor_Run_ExpectAndReturn(TRUE); |
||||
|
Executor_Run_ExpectAndReturn(FALSE); |
||||
|
|
||||
|
AppMain(); |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "Model.h" |
||||
|
#include "MockTaskScheduler.h" |
||||
|
#include "MockTemperatureFilter.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldCallSchedulerAndTemperatureFilterInit(void) |
||||
|
{ |
||||
|
TaskScheduler_Init_Expect(); |
||||
|
TemperatureFilter_Init_Expect(); |
||||
|
Model_Init(); |
||||
|
} |
@ -0,0 +1,104 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TaskScheduler.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
TaskScheduler_Init(); |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testShouldScheduleUsartTaskAfter1000ms(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
|
||||
|
TaskScheduler_Update(999); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
|
||||
|
TaskScheduler_Update(1000); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
} |
||||
|
|
||||
|
void testShouldClearUsartDoFlagAfterReported(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
TaskScheduler_Update(1000); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
} |
||||
|
|
||||
|
void testShouldScheduleUsartTaskEvery1000ms(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
|
||||
|
TaskScheduler_Update(1300); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
|
||||
|
TaskScheduler_Update(2000); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
|
||||
|
TaskScheduler_Update(3100); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
} |
||||
|
|
||||
|
void testShouldScheduleUsartTaskOnlyOncePerPeriod(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
TaskScheduler_Update(1000); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
TaskScheduler_Update(1001); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
TaskScheduler_Update(1999); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoUsart()); |
||||
|
TaskScheduler_Update(2000); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoUsart()); |
||||
|
} |
||||
|
|
||||
|
void testShouldScheduleAdcTaskAfter100ms(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
|
||||
|
TaskScheduler_Update(99); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
|
||||
|
TaskScheduler_Update(100); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
} |
||||
|
|
||||
|
void testShouldClearAdcDoFlagAfterReported(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
TaskScheduler_Update(100); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
} |
||||
|
|
||||
|
void testShouldScheduleAdcTaskEvery100ms(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
|
||||
|
TaskScheduler_Update(121); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
|
||||
|
TaskScheduler_Update(200); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
|
||||
|
TaskScheduler_Update(356); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
} |
||||
|
|
||||
|
void testShouldScheduleAdcTaskOnlyOncePerPeriod(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
TaskScheduler_Update(100); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
TaskScheduler_Update(101); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
TaskScheduler_Update(199); |
||||
|
TEST_ASSERT_EQUAL(FALSE, TaskScheduler_DoAdc()); |
||||
|
TaskScheduler_Update(200); |
||||
|
TEST_ASSERT_EQUAL(TRUE, TaskScheduler_DoAdc()); |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TemperatureCalculator.h" |
||||
|
#include <math.h> |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testTemperatureCalculatorShouldCalculateTemperatureFromMillivolts(void) |
||||
|
{ |
||||
|
float result; |
||||
|
|
||||
|
// Series resistor is 5k Ohms; Reference voltage is 3.0V
|
||||
|
// R(t) = A * e^(B*t); R is resistance of thermisor; t is temperature in C
|
||||
|
result = TemperatureCalculator_Calculate(1000); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.01f, 25.0f, result); |
||||
|
|
||||
|
result = TemperatureCalculator_Calculate(2985); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.01f, 68.317f, result); |
||||
|
|
||||
|
result = TemperatureCalculator_Calculate(3); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.01f, -19.96f, result); |
||||
|
} |
||||
|
|
||||
|
void testShouldReturnNegativeInfinityWhen_0_millivoltsInput(void) |
||||
|
{ |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.0000001f, -INFINITY, TemperatureCalculator_Calculate(0)); |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TemperatureFilter.h" |
||||
|
#include <math.h> |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
TemperatureFilter_Init(); |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testShouldInitializeTemeratureToInvalidValue(void) |
||||
|
{ |
||||
|
TemperatureFilter_Init(); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.0001f, -INFINITY, TemperatureFilter_GetTemperatureInCelcius()); |
||||
|
} |
||||
|
|
||||
|
void testShouldInitializeTemperatureAfterCallToInit(void) |
||||
|
{ |
||||
|
TemperatureFilter_Init(); |
||||
|
TemperatureFilter_ProcessInput(17.8f); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.0001f, 17.8f, TemperatureFilter_GetTemperatureInCelcius()); |
||||
|
|
||||
|
TemperatureFilter_Init(); |
||||
|
TemperatureFilter_ProcessInput(32.6f); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.0001f, 32.6f, TemperatureFilter_GetTemperatureInCelcius()); |
||||
|
} |
||||
|
|
||||
|
void setValueAndVerifyResponse(float input, float response) |
||||
|
{ |
||||
|
float actual; |
||||
|
TemperatureFilter_ProcessInput(input); |
||||
|
actual = TemperatureFilter_GetTemperatureInCelcius(); |
||||
|
TEST_ASSERT_FLOAT_WITHIN(0.0001f, response, actual); |
||||
|
} |
||||
|
|
||||
|
void testShouldWeightEachSubsequentValueBy25PercentAfterInitialValue(void) |
||||
|
{ |
||||
|
TemperatureFilter_Init(); |
||||
|
setValueAndVerifyResponse(0.0f, 0.0f); |
||||
|
setValueAndVerifyResponse(10.0f, 2.5f); |
||||
|
setValueAndVerifyResponse(10.0f, 4.375f); |
||||
|
setValueAndVerifyResponse(10.0f, 5.78125f); |
||||
|
|
||||
|
TemperatureFilter_Init(); |
||||
|
setValueAndVerifyResponse(100.0f, 100.0f); |
||||
|
setValueAndVerifyResponse(0.0f, 75.0f); |
||||
|
setValueAndVerifyResponse(0.0f, 56.25f); |
||||
|
setValueAndVerifyResponse(0.0f, 42.1875f); |
||||
|
} |
||||
|
|
||||
|
void setInvalidTemperatureAndVerifyReinitialized(float invalidTemperature) |
||||
|
{ |
||||
|
TemperatureFilter_Init(); |
||||
|
setValueAndVerifyResponse(100.0f, 100.0f); |
||||
|
setValueAndVerifyResponse(invalidTemperature, -INFINITY); |
||||
|
setValueAndVerifyResponse(14.3f, 14.3f); |
||||
|
} |
||||
|
|
||||
|
void testShouldResetAverageIfPassedInfinityOrInvalidValue(void) |
||||
|
{ |
||||
|
setInvalidTemperatureAndVerifyReinitialized(-INFINITY); |
||||
|
setInvalidTemperatureAndVerifyReinitialized(+INFINITY); |
||||
|
setInvalidTemperatureAndVerifyReinitialized(+NAN); |
||||
|
setInvalidTemperatureAndVerifyReinitialized(-NAN); |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TimerConductor.h" |
||||
|
#include "MockTimerHardware.h" |
||||
|
#include "MockTimerModel.h" |
||||
|
#include "MockTimerInterruptHandler.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldCallHardwareInit(void) |
||||
|
{ |
||||
|
TimerHardware_Init_Expect(); |
||||
|
|
||||
|
TimerConductor_Init(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldGetSystemTimeAndPassOnToModelForEventScheduling(void) |
||||
|
{ |
||||
|
Timer_GetSystemTime_ExpectAndReturn(1230); |
||||
|
TimerModel_UpdateTime_Expect(1230); |
||||
|
TimerConductor_Run(); |
||||
|
|
||||
|
Timer_GetSystemTime_ExpectAndReturn(837460); |
||||
|
TimerModel_UpdateTime_Expect(837460); |
||||
|
TimerConductor_Run(); |
||||
|
} |
@ -0,0 +1,112 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TimerConfigurator.h" |
||||
|
#include "AT91SAM7X256.h" |
||||
|
#include "MockTimerInterruptConfigurator.h" |
||||
|
|
||||
|
AT91S_PMC PmcPeripheral; |
||||
|
AT91S_TC TimerCounter0Peripheral; |
||||
|
AT91S_PIO PioBPeripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testEnablePeripheralClocksShouldEnableClockToTimer0Peripheral(void) |
||||
|
{ |
||||
|
AT91C_BASE_PMC->PMC_PCER = 0; |
||||
|
Timer_EnablePeripheralClocks(); |
||||
|
TEST_ASSERT_EQUAL( |
||||
|
TIMER0_CLOCK_ENABLE, |
||||
|
AT91C_BASE_PMC->PMC_PCER & TIMER0_CLOCK_ENABLE); |
||||
|
} |
||||
|
|
||||
|
void testEnablePeripheralClocksShouldEnableClockToPIOBPeripheral(void) |
||||
|
{ |
||||
|
AT91C_BASE_PMC->PMC_PCER = 0; |
||||
|
Timer_EnablePeripheralClocks(); |
||||
|
TEST_ASSERT_EQUAL( |
||||
|
PIOB_CLOCK_ENABLE, |
||||
|
AT91C_BASE_PMC->PMC_PCER & PIOB_CLOCK_ENABLE); |
||||
|
} |
||||
|
|
||||
|
void testResetShouldSetTimer0ClockDisableBit_DisableTimer0Interrupts_ClearStatusRegister(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CCR = 0; |
||||
|
AT91C_BASE_TC0->TC_IDR = 0; |
||||
|
AT91C_BASE_TC0->TC_SR = 0xFFFFFFFF; |
||||
|
Timer_Reset(); |
||||
|
TEST_ASSERT_EQUAL(0x00000002, AT91C_BASE_TC0->TC_CCR); |
||||
|
TEST_ASSERT_EQUAL(0xffffffff, AT91C_BASE_TC0->TC_IDR); |
||||
|
// CANNOT BE VERIFIED!! TEST_ASSERT_EQUAL(0X00000000, AT91C_BASE_TC0->TC_SR);
|
||||
|
} |
||||
|
|
||||
|
void testEnableOutputPinShouldEnable_TIOA0_DigitalOutput(void) |
||||
|
{ |
||||
|
AT91C_BASE_PIOB->PIO_PDR = 0; |
||||
|
Timer_EnableOutputPin(); |
||||
|
TEST_ASSERT_EQUAL(TIOA0_PIN_MASK, AT91C_BASE_PIOB->PIO_PDR); |
||||
|
} |
||||
|
|
||||
|
void testConfigureModeShouldConfigureTimer0ClockSourceForMasterClockDividedBy1024(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CMR = 0; |
||||
|
Timer_ConfigureMode(); |
||||
|
TEST_ASSERT_EQUAL(0x00000004, AT91C_BASE_TC0->TC_CMR & 0x00000007); |
||||
|
} |
||||
|
|
||||
|
void testConfigureModeShouldConfigureTimer0ForWaveGeneration(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CMR = 0; |
||||
|
Timer_ConfigureMode(); |
||||
|
TEST_ASSERT_EQUAL(0x00008000, AT91C_BASE_TC0->TC_CMR & 0x00008000); |
||||
|
} |
||||
|
|
||||
|
void testConfigureModeShouldConfigureTimer0ForUpModeWithAutomaticTriggerOnRCCompare(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CMR = 0; |
||||
|
Timer_ConfigureMode(); |
||||
|
TEST_ASSERT_EQUAL(0x00004000, AT91C_BASE_TC0->TC_CMR & 0x00006000); |
||||
|
} |
||||
|
|
||||
|
void testConfigureModeShouldConfigureTimer0ToToggleTIOAOnRCCompare(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CMR = 0; |
||||
|
Timer_ConfigureMode(); |
||||
|
TEST_ASSERT_EQUAL(0x000C0000, AT91C_BASE_TC0->TC_CMR & 0x000C0000); |
||||
|
} |
||||
|
|
||||
|
void testConfigurePeriodShouldConfigureRegisterCFor10msInterval(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_RC = 0; |
||||
|
Timer_ConfigurePeriod(); |
||||
|
TEST_ASSERT_EQUAL(469, AT91C_BASE_TC0->TC_RC); |
||||
|
} |
||||
|
|
||||
|
void testEnableShouldSetEnableFlagForTimer0(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CCR = 0; |
||||
|
Timer_Enable(); |
||||
|
TEST_ASSERT_EQUAL_INT(1, AT91C_BASE_TC0->TC_CCR); |
||||
|
} |
||||
|
|
||||
|
void testConfigureInterruptHandler(void) |
||||
|
{ |
||||
|
Timer_DisableInterrupt_Expect(); |
||||
|
Timer_ResetSystemTime_Expect(); |
||||
|
Timer_ConfigureInterrupt_Expect(); |
||||
|
Timer_EnableInterrupt_Expect(); |
||||
|
|
||||
|
Timer_ConfigureInterruptHandler(); |
||||
|
} |
||||
|
|
||||
|
void testStartShouldSetSoftwareTriggerFlag(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_CCR = 0; |
||||
|
Timer_Start(); |
||||
|
TEST_ASSERT_EQUAL(0x04, AT91C_BASE_TC0->TC_CCR); |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TimerHardware.h" |
||||
|
#include "MockTimerConfigurator.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldDelegateAppropriatelyToConfigurator(void) |
||||
|
{ |
||||
|
Timer_EnablePeripheralClocks_Expect(); |
||||
|
Timer_Reset_Expect(); |
||||
|
Timer_ConfigureMode_Expect(); |
||||
|
Timer_ConfigurePeriod_Expect(); |
||||
|
Timer_EnableOutputPin_Expect(); |
||||
|
Timer_Enable_Expect(); |
||||
|
Timer_ConfigureInterruptHandler_Expect(); |
||||
|
Timer_Start_Expect(); |
||||
|
|
||||
|
TimerHardware_Init(); |
||||
|
} |
@ -0,0 +1,78 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TimerInterruptConfigurator.h" |
||||
|
#include "MockTimerInterruptHandler.h" |
||||
|
#include "AT91SAM7X256.h" |
||||
|
|
||||
|
AT91S_AIC AicPeripheral; |
||||
|
AT91S_TC TimerCounter0Peripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void test_TIMER0_ID_MASK_ShouldBeCorrect(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL(((uint32)0x1) << AT91C_ID_TC0, TIMER0_ID_MASK); |
||||
|
} |
||||
|
|
||||
|
void testDisableInterruptDisablesTimer0InterruptInTheInterruptController(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_IDCR = 0; |
||||
|
Timer_DisableInterrupt(); |
||||
|
TEST_ASSERT_EQUAL(TIMER0_ID_MASK, AT91C_BASE_AIC->AIC_IDCR); |
||||
|
} |
||||
|
|
||||
|
void testResetSystemTimeDelegatesTo_Timer_SetSystemTime_Appropriately(void) |
||||
|
{ |
||||
|
Timer_SetSystemTime_Expect(0); |
||||
|
Timer_ResetSystemTime(); |
||||
|
} |
||||
|
|
||||
|
void testConfigureInterruptShouldSetInterruptHandlerAppropriately(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (uint32)NULL; |
||||
|
Timer_ConfigureInterrupt(); |
||||
|
TEST_ASSERT_EQUAL((uint32)Timer_InterruptHandler, AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0]); |
||||
|
} |
||||
|
|
||||
|
void testConfigureInterruptShouldSetInterruptLevelInSourceModeRegisterAppropriately(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 0; |
||||
|
Timer_ConfigureInterrupt(); |
||||
|
TEST_ASSERT_EQUAL( |
||||
|
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, |
||||
|
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] & 0x00000060); |
||||
|
} |
||||
|
|
||||
|
void testConfigureInterruptShouldSetInterruptPriorityInSourceModeRegisterAppropriately(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 0; |
||||
|
Timer_ConfigureInterrupt(); |
||||
|
TEST_ASSERT_EQUAL(1, AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] & 0x00000007); |
||||
|
} |
||||
|
|
||||
|
void testConfigureInterruptShouldClearTimer0InterruptOnTheInterruptController(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_ICCR = 0; |
||||
|
Timer_ConfigureInterrupt(); |
||||
|
TEST_ASSERT_EQUAL(TIMER0_ID_MASK, AT91C_BASE_AIC->AIC_ICCR); |
||||
|
} |
||||
|
|
||||
|
void testConfigureInterruptShouldEnableCompareInterruptForRegisterC(void) |
||||
|
{ |
||||
|
AT91C_BASE_TC0->TC_IER = 0; |
||||
|
Timer_ConfigureInterrupt(); |
||||
|
TEST_ASSERT_EQUAL(AT91C_TC_CPCS, AT91C_BASE_TC0->TC_IER); |
||||
|
} |
||||
|
|
||||
|
void testEnableInterruptShouldEnableTimer0InterruptsInInterruptCotroller(void) |
||||
|
{ |
||||
|
AT91C_BASE_AIC->AIC_IECR = 0; |
||||
|
Timer_EnableInterrupt(); |
||||
|
TEST_ASSERT_EQUAL(TIMER0_ID_MASK, AT91C_BASE_AIC->AIC_IECR); |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TimerInterruptHandler.h" |
||||
|
#include "AT91SAM7X256.h" |
||||
|
|
||||
|
AT91S_TC TimerCounter0Peripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testSetAndGetSystemTime(void) |
||||
|
{ |
||||
|
Timer_SetSystemTime(0); |
||||
|
TEST_ASSERT_EQUAL(0, Timer_GetSystemTime()); |
||||
|
|
||||
|
Timer_SetSystemTime(129837); |
||||
|
TEST_ASSERT_EQUAL(129837, Timer_GetSystemTime()); |
||||
|
|
||||
|
Timer_SetSystemTime(UINT32_MAX); |
||||
|
TEST_ASSERT_EQUAL(UINT32_MAX, Timer_GetSystemTime()); |
||||
|
} |
||||
|
|
||||
|
void testInterruptHandlerShouldIncrementSystemTimeOnlyIfStatusHasCompareRegisterCOverflowBitSet(void) |
||||
|
{ |
||||
|
Timer_SetSystemTime(0); |
||||
|
AT91C_BASE_TC0->TC_SR = 0; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT_EQUAL(0, Timer_GetSystemTime()); |
||||
|
|
||||
|
Timer_SetSystemTime(0); |
||||
|
AT91C_BASE_TC0->TC_SR = ~AT91C_TC_CPCS; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT_EQUAL(0, Timer_GetSystemTime()); |
||||
|
|
||||
|
Timer_SetSystemTime(0); |
||||
|
AT91C_BASE_TC0->TC_SR = AT91C_TC_CPCS; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT(Timer_GetSystemTime() > 0); |
||||
|
|
||||
|
Timer_SetSystemTime(0); |
||||
|
AT91C_BASE_TC0->TC_SR = 0xffffffff; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT(Timer_GetSystemTime() > 0); |
||||
|
} |
||||
|
|
||||
|
void testInterruptHandlerShouldIncrementSystemTimerBy_10(void) |
||||
|
{ |
||||
|
Timer_SetSystemTime(0); |
||||
|
AT91C_BASE_TC0->TC_SR = AT91C_TC_CPCS; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT_EQUAL(10, Timer_GetSystemTime()); |
||||
|
|
||||
|
AT91C_BASE_TC0->TC_SR = AT91C_TC_CPCS; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT_EQUAL(20, Timer_GetSystemTime()); |
||||
|
|
||||
|
Timer_SetSystemTime(39426857); |
||||
|
AT91C_BASE_TC0->TC_SR = AT91C_TC_CPCS; |
||||
|
Timer_InterruptHandler(); |
||||
|
TEST_ASSERT_EQUAL(39426867, Timer_GetSystemTime()); |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "TimerModel.h" |
||||
|
#include "MockTaskScheduler.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testUpdateTimeShouldDelegateToTaskScheduler(void) |
||||
|
{ |
||||
|
TaskScheduler_Update_Expect(19387L); |
||||
|
TimerModel_UpdateTime(19387L); |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartBaudRateRegisterCalculator.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testCalculateBaudRateRegisterSettingShouldCalculateRegisterSettingAppropriately(void) |
||||
|
{ |
||||
|
// BaudRate = MCK / (CD x 16) - per datasheet section 30.6.1.2 "Baud Rate Calculation Example"
|
||||
|
TEST_ASSERT_EQUAL(26, UsartModel_CalculateBaudRateRegisterSetting(48000000, 115200)); |
||||
|
TEST_ASSERT_EQUAL(6, UsartModel_CalculateBaudRateRegisterSetting(3686400, 38400)); |
||||
|
TEST_ASSERT_EQUAL(23, UsartModel_CalculateBaudRateRegisterSetting(14318180, 38400)); |
||||
|
TEST_ASSERT_EQUAL(20, UsartModel_CalculateBaudRateRegisterSetting(12000000, 38400)); |
||||
|
TEST_ASSERT_EQUAL(13, UsartModel_CalculateBaudRateRegisterSetting(12000000, 56800)); |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartConductor.h" |
||||
|
#include "MockUsartModel.h" |
||||
|
#include "MockUsartHardware.h" |
||||
|
#include "MockTaskScheduler.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testShouldInitializeHardwareWhenInitCalled(void) |
||||
|
{ |
||||
|
UsartModel_GetBaudRateRegisterSetting_ExpectAndReturn(4); |
||||
|
UsartModel_GetWakeupMessage_ExpectAndReturn("Hey there!"); |
||||
|
UsartHardware_TransmitString_Expect("Hey there!"); |
||||
|
UsartHardware_Init_Expect(4); |
||||
|
|
||||
|
UsartConductor_Init(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldNotDoAnythingIfSchedulerSaysItIsNotTimeYet(void) |
||||
|
{ |
||||
|
TaskScheduler_DoUsart_ExpectAndReturn(FALSE); |
||||
|
|
||||
|
UsartConductor_Run(); |
||||
|
} |
||||
|
|
||||
|
void testRunShouldGetCurrentTemperatureAndTransmitIfSchedulerSaysItIsTime(void) |
||||
|
{ |
||||
|
TaskScheduler_DoUsart_ExpectAndReturn(TRUE); |
||||
|
UsartModel_GetFormattedTemperature_ExpectAndReturn("hey there"); |
||||
|
UsartHardware_TransmitString_Expect("hey there"); |
||||
|
|
||||
|
UsartConductor_Run(); |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartConfigurator.h" |
||||
|
|
||||
|
AT91S_PIO PioAPeripheral; |
||||
|
AT91S_PMC PmcPeripheral; |
||||
|
AT91S_USART Usart0Peripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testConfigureUsartIOShouldConfigureUsartTxPinfForPeripheralIO(void) |
||||
|
{ |
||||
|
AT91C_BASE_PIOA->PIO_ASR = 0; |
||||
|
AT91C_BASE_PIOA->PIO_BSR = 0xffffffff; |
||||
|
AT91C_BASE_PIOA->PIO_PDR = 0; |
||||
|
Usart_ConfigureUsartIO(); |
||||
|
TEST_ASSERT_EQUAL(USART0_TX_PIN, AT91C_BASE_PIOA->PIO_ASR); |
||||
|
TEST_ASSERT_EQUAL(0, AT91C_BASE_PIOA->PIO_BSR); |
||||
|
TEST_ASSERT_EQUAL(USART0_TX_PIN, AT91C_BASE_PIOA->PIO_PDR); |
||||
|
} |
||||
|
|
||||
|
void testEnablePeripheralClockShouldEnableClockToUsartPeripheral(void) |
||||
|
{ |
||||
|
AT91C_BASE_PMC->PMC_PCER = 0; |
||||
|
Usart_EnablePeripheralClock(); |
||||
|
TEST_ASSERT_EQUAL(((uint32)1) << USART0_CLOCK_ENABLE, AT91C_BASE_PMC->PMC_PCER); |
||||
|
} |
||||
|
|
||||
|
void testResetShouldDisableAllUsartInterrupts(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_IDR = 0; |
||||
|
Usart_Reset(); |
||||
|
TEST_ASSERT_EQUAL(0xffffffff, AT91C_BASE_US0->US_IDR); |
||||
|
} |
||||
|
|
||||
|
void testResetShouldResetUsartTransmitterAndReceiver(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_CR = 0; |
||||
|
Usart_Reset(); |
||||
|
TEST_ASSERT_EQUAL(AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS, AT91C_BASE_US0->US_CR); |
||||
|
} |
||||
|
|
||||
|
void testConfigureModeShouldSetUsartModeToAsynchronous(void) |
||||
|
{ |
||||
|
uint32 asyncMode = (AT91C_US_USMODE_NORMAL | |
||||
|
AT91C_US_NBSTOP_1_BIT | |
||||
|
AT91C_US_PAR_NONE | |
||||
|
AT91C_US_CHRL_8_BITS | |
||||
|
AT91C_US_CLKS_CLOCK); |
||||
|
|
||||
|
AT91C_BASE_US0->US_MR = ~asyncMode; |
||||
|
Usart_ConfigureMode(); |
||||
|
TEST_ASSERT_EQUAL(asyncMode, AT91C_BASE_US0->US_MR); |
||||
|
} |
||||
|
|
||||
|
void testSetBaudRateRegisterShouldSetUsartBaudRateRegisterToValuePassedAsParameter(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_BRGR = 0; |
||||
|
Usart_SetBaudRateRegister(3); |
||||
|
TEST_ASSERT_EQUAL(3, AT91C_BASE_US0->US_BRGR); |
||||
|
Usart_SetBaudRateRegister(251); |
||||
|
TEST_ASSERT_EQUAL(251, AT91C_BASE_US0->US_BRGR); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void testEnableShouldEnableUsart0Transmitter(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_CR = 0; |
||||
|
Usart_Enable(); |
||||
|
TEST_ASSERT_EQUAL(AT91C_US_TXEN, AT91C_BASE_US0->US_CR); |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartHardware.h" |
||||
|
#include "AT91SAM7X256.h" |
||||
|
#include "MockUsartConfigurator.h" |
||||
|
#include "MockUsartPutChar.h" |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testInitShouldConfigureUsartPeripheralByCallingConfiguratorAppropriately(void) |
||||
|
{ |
||||
|
Usart_ConfigureUsartIO_Expect(); |
||||
|
Usart_EnablePeripheralClock_Expect(); |
||||
|
Usart_Reset_Expect(); |
||||
|
Usart_ConfigureMode_Expect(); |
||||
|
Usart_SetBaudRateRegister_Expect(73); |
||||
|
Usart_Enable_Expect(); |
||||
|
|
||||
|
UsartHardware_Init(73); |
||||
|
} |
||||
|
|
||||
|
void testTransmitStringShouldSendDesiredStringOutUsingUsart(void) |
||||
|
{ |
||||
|
Usart_PutChar_Expect('h'); |
||||
|
Usart_PutChar_Expect('e'); |
||||
|
Usart_PutChar_Expect('l'); |
||||
|
Usart_PutChar_Expect('l'); |
||||
|
Usart_PutChar_Expect('o'); |
||||
|
|
||||
|
UsartHardware_TransmitString("hello"); |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartModel.h" |
||||
|
#include "ModelConfig.h" |
||||
|
#include "MockTemperatureFilter.h" |
||||
|
#include "MockUsartBaudRateRegisterCalculator.h" |
||||
|
#include <math.h> |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testGetBaudRateRegisterSettingShouldReturnAppropriateBaudRateRegisterSetting(void) |
||||
|
{ |
||||
|
uint8 dummyRegisterSetting = 17; |
||||
|
UsartModel_CalculateBaudRateRegisterSetting_ExpectAndReturn(MASTER_CLOCK, USART0_BAUDRATE, dummyRegisterSetting); |
||||
|
|
||||
|
TEST_ASSERT_EQUAL(dummyRegisterSetting, UsartModel_GetBaudRateRegisterSetting()); |
||||
|
} |
||||
|
|
||||
|
void testGetFormattedTemperatureFormatsTemperatureFromCalculatorAppropriately(void) |
||||
|
{ |
||||
|
TemperatureFilter_GetTemperatureInCelcius_ExpectAndReturn(25.0f); |
||||
|
TEST_ASSERT_EQUAL_STRING("25.0 C\n", UsartModel_GetFormattedTemperature()); |
||||
|
} |
||||
|
|
||||
|
void testShouldReturnErrorMessageUponInvalidTemperatureValue(void) |
||||
|
{ |
||||
|
TemperatureFilter_GetTemperatureInCelcius_ExpectAndReturn(-INFINITY); |
||||
|
TEST_ASSERT_EQUAL_STRING("Temperature sensor failure!\n", UsartModel_GetFormattedTemperature()); |
||||
|
} |
||||
|
|
||||
|
void testShouldReturnWakeupMessage(void) |
||||
|
{ |
||||
|
TEST_ASSERT_EQUAL_STRING("It's Awesome Time!\n", UsartModel_GetWakeupMessage()); |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartPutChar.h" |
||||
|
#include "MockUsartTransmitBufferStatus.h" |
||||
|
|
||||
|
AT91S_USART Usart0Peripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testPutCharShouldWriteDesiredCharacterToUsartTransmitBuffer(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_THR = 0; |
||||
|
|
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(TRUE); |
||||
|
Usart_PutChar('x'); |
||||
|
TEST_ASSERT_EQUAL('x', AT91C_BASE_US0->US_THR); |
||||
|
|
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(TRUE); |
||||
|
Usart_PutChar('1'); |
||||
|
TEST_ASSERT_EQUAL('1', AT91C_BASE_US0->US_THR); |
||||
|
|
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(TRUE); |
||||
|
Usart_PutChar(':'); |
||||
|
TEST_ASSERT_EQUAL(':', AT91C_BASE_US0->US_THR); |
||||
|
} |
||||
|
|
||||
|
void testPutCharShouldWaitUntilReadyToTransmitBeforeLoadingTransmitBufffer(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_THR = 0; |
||||
|
|
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(FALSE); |
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(FALSE); |
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(FALSE); |
||||
|
Usart_ReadyToTransmit_ExpectAndReturn(TRUE); |
||||
|
Usart_PutChar('x'); |
||||
|
TEST_ASSERT_EQUAL('x', AT91C_BASE_US0->US_THR); |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
#include "unity.h" |
||||
|
#include "Types.h" |
||||
|
#include "UsartTransmitBufferStatus.h" |
||||
|
|
||||
|
AT91S_USART Usart0Peripheral; |
||||
|
|
||||
|
void setUp(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void tearDown(void) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void testReadyToTransmitShouldReturnStatusPerTransmitBufferReadyStatus(void) |
||||
|
{ |
||||
|
AT91C_BASE_US0->US_CSR = 0; |
||||
|
TEST_ASSERT(!Usart_ReadyToTransmit()); |
||||
|
|
||||
|
AT91C_BASE_US0->US_CSR = AT91C_US_TXRDY; |
||||
|
TEST_ASSERT(Usart_ReadyToTransmit()); |
||||
|
} |
@ -0,0 +1,86 @@ |
|||||
|
# ========================================== |
||||
|
# CMock Project - Automatic Mock Generation for C |
||||
|
# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams |
||||
|
# [Released under MIT License. Please refer to license.txt for details] |
||||
|
# ========================================== |
||||
|
|
||||
|
[ "../config/production_environment", |
||||
|
"cmock_header_parser", |
||||
|
"cmock_generator", |
||||
|
"cmock_file_writer", |
||||
|
"cmock_config", |
||||
|
"cmock_plugin_manager", |
||||
|
"cmock_generator_utils", |
||||
|
"cmock_unityhelper_parser"].each {|req| require "#{File.expand_path(File.dirname(__FILE__))}/#{req}"} |
||||
|
|
||||
|
class CMock |
||||
|
|
||||
|
def initialize(options=nil) |
||||
|
cm_config = CMockConfig.new(options) |
||||
|
cm_unityhelper = CMockUnityHelperParser.new(cm_config) |
||||
|
cm_writer = CMockFileWriter.new(cm_config) |
||||
|
cm_gen_utils = CMockGeneratorUtils.new(cm_config, {:unity_helper => cm_unityhelper}) |
||||
|
cm_gen_plugins = CMockPluginManager.new(cm_config, cm_gen_utils) |
||||
|
@cm_parser = CMockHeaderParser.new(cm_config) |
||||
|
@cm_generator = CMockGenerator.new(cm_config, cm_writer, cm_gen_utils, cm_gen_plugins) |
||||
|
@silent = (cm_config.verbosity < 2) |
||||
|
end |
||||
|
|
||||
|
def setup_mocks(files) |
||||
|
[files].flatten.each do |src| |
||||
|
generate_mock src |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
private ############################### |
||||
|
|
||||
|
def generate_mock(src) |
||||
|
name = File.basename(src, '.h') |
||||
|
puts "Creating mock for #{name}..." unless @silent |
||||
|
@cm_generator.create_mock(name, @cm_parser.parse(name, File.read(src))) |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
def option_maker(options, key, val) |
||||
|
options = options || {} |
||||
|
options[key.to_sym] = |
||||
|
if val.chr == ":" |
||||
|
val[1..-1].to_sym |
||||
|
elsif val.include? ";" |
||||
|
val.split(';') |
||||
|
elsif val == 'true' |
||||
|
true |
||||
|
elsif val == 'false' |
||||
|
false |
||||
|
elsif val =~ /^\d+$/ |
||||
|
val.to_i |
||||
|
else |
||||
|
val |
||||
|
end |
||||
|
options |
||||
|
end |
||||
|
|
||||
|
# Command Line Support ############################### |
||||
|
|
||||
|
if ($0 == __FILE__) |
||||
|
usage = "usage: ruby #{__FILE__} (-oOptionsFile) File(s)ToMock" |
||||
|
|
||||
|
if (!ARGV[0]) |
||||
|
puts usage |
||||
|
exit 1 |
||||
|
end |
||||
|
|
||||
|
options = {} |
||||
|
filelist = [] |
||||
|
ARGV.each do |arg| |
||||
|
if (arg =~ /^-o\"?([a-zA-Z0-9._\\\/:\s]+)\"?/) |
||||
|
options.merge! CMockConfig.load_config_file_from_yaml( arg.gsub(/^-o/,'') ) |
||||
|
elsif (arg =~ /^--([a-zA-Z0-9._\\\/:\s]+)=\"?([a-zA-Z0-9._\-\\\/:\s\;]+)\"?/) |
||||
|
options = option_maker(options, $1, $2) |
||||
|
else |
||||
|
filelist << arg |
||||
|
end |
||||
|
end |
||||
|
|
||||
|
CMock.new(options).setup_mocks(filelist) |
||||
|
end |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue