我正在尝试Ivory
(http://ivorylang.org,https://github.com/GaloisInc/ivory)并使用ivory-hw
模块来操纵微控制器中的某些寄存器。
cmain :: Def ('[] :-> ())
cmain = voidProc "main" $ body $ do
setReg regFoo $ do
clearBit foo_bitbar
setBit foo_bitbaz
forever $ return ()
main_module :: Module
main_module = package "main" $ do
incl cmain
main :: IO ()
main = runCompiler [ main_module ] [] (initialOpts {constFold = True,
outDir = Just "out"})
构建和运行给出:
$ exe
*** Procedure main
ERROR: [ No location available ]:
Unbound value: 'ivory_hw_io_write_u32'
exe: Sanity-check failed!
将选项scErrors = False
添加到runCompiler
会关闭健全性检查,代码将运行至完成生成源。
但是,main.c
包含对ivory_hw_io_write_u32
的调用,但此函数未在任何地方定义(可能解释错误)。关于github,我可以找到包含文件ivory_hw_prim.h
的示例。
经过一些实验,我可以通过为hw内容添加一个模块然后将其作为依赖项添加到我的main_module
来包含这个:
hw_module :: Module
hw_module = package "ivory_hw_prim" hw_moduledef
main_module :: Module
main_module = package "main" $ do
depend hw_module
incl cmain
并添加runCompiler
并添加hw_artifacts
以生成标题:
main = runCompiler [ main_module ] hw_artifacts (initialOpts {scErrors = False,
constFold = True,
outDir = Just "out"})
这会将ivory_hw_prim.h
添加到生成的文件集合中,并在main.h
中包含必要的包含。
但是,这只能通过将scErrors = False
选项保留到runCompiler
来实现,这表明我仍然没有做到这一点。
因此,我的问题是:使用Ivory硬件包的正确方法是什么?
答案 0 :(得分:1)
解决方案是在包中加入hw_moduledef
:
main_module :: Module
main_module = package "main" $
incl cmain >> hw_moduledef
(depend
函数只包含标题。)在hw_moduledef
包中包含"main"
会使其定义对完整性检查器可见。
顺便说一下,Ivory模块系统将来可能会得到改进,因此Ivory会在编译时计算依赖关系,从而减轻程序员必须进行显式包含。